Apply Force Relative To Rotation?

Questions about the LÖVE API, installing LÖVE and other support related questions go here.
Forum rules
Before you make a thread asking for help, read this.
User avatar
bartbes
Sex machine
Posts: 4946
Joined: Fri Aug 29, 2008 10:35 am
Location: The Netherlands
Contact:

Re: Apply Force Relative To Rotation?

Post by bartbes »

Not 2, most (if not all) keyboards I encountered were able to do at least 3 keys at the same time. (how else would you do ctrl+alt+del, all the windows users need this)
stevec64
Prole
Posts: 1
Joined: Thu Jun 25, 2009 9:36 am

Re: Apply Force Relative To Rotation?

Post by stevec64 »

Alex wrote:Do not use applyForce() or applyImpulse(). They are broken hard. I've reported the bug and sent a patch, but until it goes through, use setVelocity(). It is not broken, and it's possible to model acceleration and jerk using only setVelocity and the time increment.
I just hit this bug recently also... spent a while trying to figure out where unwanted torque was coming from. For the purposes of those who want to make a local fix to their source (I couldn't find Alex's patch on the Tracker):

The offending code is in box2d\Body.cpp. Make the following changes:

Code: Select all

	void Body::applyImpulse(float jx, float jy)
	{
		body->ApplyImpulse(b2Vec2(jx, jy), body->GetWorldCenter());
	}

	void Body::applyImpulse(float jx, float jy, float rx, float ry)
	{
		body->ApplyImpulse(b2Vec2(jx, jy), b2Vec2(rx, ry));
	}

	void Body::applyTorque(float t)
	{
		body->ApplyTorque(t);
	}

	void Body::applyForce(float fx, float fy, float rx, float ry)
	{
		body->ApplyForce(b2Vec2(fx, fy), b2Vec2(rx, ry));
	}

	void Body::applyForce(float fx, float fy)
	{
		body->ApplyForce(b2Vec2(fx, fy), body->GetWorldCenter());
	}

This seemed to fix the issues I had at least, so happily applying forces and impulses now getting the behavior I expect.

Steve
LagMasterSam
Prole
Posts: 8
Joined: Sun Aug 30, 2009 2:24 pm

Re: Apply Force Relative To Rotation?

Post by LagMasterSam »

Alex wrote:Do not use applyForce() or applyImpulse(). They are broken hard. I've reported the bug and sent a patch, but until it goes through, use setVelocity(). It is not broken, and it's possible to model acceleration and jerk using only setVelocity and the time increment.

Aside from that, lejeaunerenard is right. Derive your new x and y using the amount of force you want to apply (R) and the the angle that the object is rotated (theta):

Code: Select all

vx, vy = object:getVelocity()
newX, newY = R*math.cos(theta), R*math.sin(theta)
object:setVelocity(newX + vx, newY + vy)
I've tried using your code. However, my object almost immediately reaches a slow maximum speed, no matter how large I make R.
Manny73211
Prole
Posts: 1
Joined: Mon Aug 05, 2024 7:11 am

Re: Apply Force Relative To Rotation?

Post by Manny73211 »

I tried this in 11.5 and it doesn't really work how i want it to. basically, it moves right instead of forwards. i do not understand the code so idk how to fix it. Here's the code:

Code: Select all

function love.load()
    wf = require "libraries/windfield"
    world = wf.newWorld(0, 0)

    love.graphics.setDefaultFilter("nearest", "nearest")

    p = {
        x = love.graphics.getWidth()/2,
        y = love.graphics.getHeight()/2,
        sprite = love.graphics.newImage("gfx/ArrowGuy.png"),
        rot = 0
    }
    p.collider = world:newRectangleCollider(p.x-40, p.y-40, p.sprite:getWidth()*5, (p.sprite:getHeight()-2)*5)
    p.collider:setAngularDamping(2)
    p.collider:setLinearDamping(1)
end

function love.update(dt)
    if love.keyboard.isDown("up") then
        p.collider:applyLinearImpulse(100*math.cos(p.collider:getAngle()),100*math.sin(p.collider:getAngle()))
    end

    if love.keyboard.isDown("left") then
        p.collider:applyAngularImpulse(-1000)
    end
    if love.keyboard.isDown("right") then
        p.collider:applyAngularImpulse(1000)
    end

    p.x = p.collider:getX()
    p.y = p.collider:getY()
    
    world:update(dt)
    p.rot = p.collider:getAngle()
end

function love.draw()
    --player
    love.graphics.draw(p.sprite, p.x, p.y, p.rot, 5, 5, 8, 8)
    --hitboxes
    world:draw()
end
User avatar
dusoft
Party member
Posts: 635
Joined: Fri Nov 08, 2013 12:07 am
Location: Europe usually
Contact:

Re: Apply Force Relative To Rotation?

Post by dusoft »

Manny73211 wrote: Mon Aug 05, 2024 7:41 am I tried this in 11.5 and it doesn't really work how i want it to. basically, it moves right instead of forwards. i do not understand the code so idk how to fix it. Here's the code:

Code: Select all

function love.load()
    wf = require "libraries/windfield"
    world = wf.newWorld(0, 0)

    love.graphics.setDefaultFilter("nearest", "nearest")

    p = {
        x = love.graphics.getWidth()/2,
        y = love.graphics.getHeight()/2,
        sprite = love.graphics.newImage("gfx/ArrowGuy.png"),
        rot = 0
    }
    p.collider = world:newRectangleCollider(p.x-40, p.y-40, p.sprite:getWidth()*5, (p.sprite:getHeight()-2)*5)
    p.collider:setAngularDamping(2)
    p.collider:setLinearDamping(1)
end

function love.update(dt)
    if love.keyboard.isDown("up") then
        p.collider:applyLinearImpulse(100*math.cos(p.collider:getAngle()),100*math.sin(p.collider:getAngle()))
    end

    if love.keyboard.isDown("left") then
        p.collider:applyAngularImpulse(-1000)
    end
    if love.keyboard.isDown("right") then
        p.collider:applyAngularImpulse(1000)
    end

    p.x = p.collider:getX()
    p.y = p.collider:getY()
    
    world:update(dt)
    p.rot = p.collider:getAngle()
end

function love.draw()
    --player
    love.graphics.draw(p.sprite, p.x, p.y, p.rot, 5, 5, 8, 8)
    --hitboxes
    world:draw()
end
Please, don't bump old threads, but rather create a new one.

You need to apply -math.rad(90), i.e. negative 90 degree angle to your calculations, if you assume your body is facing north / top.
Post Reply

Who is online

Users browsing this forum: Ahrefs [Bot], Bing [Bot], Google [Bot], Semrush [Bot] and 4 guests