Tell me more ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

I have been working on a 2D top-down space strategy/shooting game. Right now it is only in the prototyping stage (I have gotten basic movement) but now I am trying to write a function that will stop the ship based on it's velocity. This is being written in Lua, using the Love2D engine.

My code is as follows (note- object.dx is the x-velocity, object.dy is the y-velocity, object.acc is the acceleration, and object.r is the rotation in radians):

function stopMoving(object, dt)
    local targetr = math.atan2(object.dy, object.dx)
    if targetr == object.r + math.pi then
        local currentspeed = math.sqrt(object.dx*object.dx+object.dy*object.dy)
        if currentspeed ~= 0 then
            object.dx = object.dx + object.acc*dt*math.cos(object.r)
            object.dy = object.dy + object.acc*dt*math.sin(object.r)
        end
    else
        if (targetr - object.r) >= math.pi then
            object.r = object.r - object.turnspeed*dt
        else
            object.r = object.r + object.turnspeed*dt
        end
    end
end

It is implemented in the update function as:

if love.keyboard.isDown("backspace") then
    stopMoving(player, dt)
end

The problem is that when I am holding down backspace, it spins the player clockwise (though I am trying to have it go the direction that would be the most efficient at getting to the angle it would have to be) and then it never starts to accelerate the player in the direction opposite to it's velocity.

What should I change in this code to get that to work?

EDIT :

I'm not trying to just stop the player in place, I'm trying to get it to use it's normal commands to neutralize it's existing velocity.

I also changed math.atan to math.atan2, apparently it's better. I noticed no difference when running it, though.

share|improve this question
1  
Why not just player.dx=0 player.dy=0? – Anko Dec 31 '12 at 9:03
3  
Because I'm not trying to tell it to just stop in place, I want it to use the ship's normal abilities in movement to cancel out it's motion. I'm going to edit the question to reflect this. – Garan Dec 31 '12 at 15:46
1  
What are the "normal abilities" of the ship? – Anko Jan 3 at 1:16
1  
Turning left and right, accelerating and decelerating (accelerates in the opposite direction). Decelerating is half as powerful as accelerating. – Garan Jan 3 at 2:35
Ok. Next, I don't understand your rotation comparisons: In the first (targetr == object.r + math.pi), why are you adding pi? In the second ((targetr - object.r) >= 2*math.pi), why are you comparing the value to a full circle (2*pi) instead of 0? Consider commenting your code. It's a good habit to get into, because it makes your intention clearer! – Anko Jan 3 at 5:06
show 6 more comments

1 Answer

The problem you're running into is the fact that when your player has stopped, there's no angle to work with so the game can't know which way to move backwards.

You either need to add one more variable that keeps track of the angle your dx/dy variables are on or two more variables to store dx/dy, leaving them alone when your real dx/dy variables don't change (and they can be safely left when their magnitude alone changes), but updating them when their direction changes.
(I think it would suffice to keep your "backup" dx/dy variables updated everywhere else save for your stopMoving() function)

share|improve this answer
This isn't the issue. If the player had stopped, it would have been caught by the "if currentspeed ~= 0". That means it wouldn't continue after the player has stopped. My issue is that it never even stops turning, and that no matter what the angle is, it always goes in the same direction. – Garan Jan 1 at 3:40
Hmm. Once I have a better handle on your problem, I'll replace my answer with something better suited. Are you sure you're calculating the angle object.r correctly? – Raceimaztion Jan 1 at 4:55
Object.r is fine, sonce I've been able to move the player around using normal controls just fine. It's not being calculated, it's being called. – Garan Jan 1 at 14:18
Why are you performing this exacting comparison? `targetr == object.r + 2*math.pi' If floating-point values are compared, more often than not they won't be equal. – Raceimaztion Jan 1 at 21:50
So you'd suggest something to test if they are within something like 1% of each other? – Garan Jan 2 at 3:57
show 1 more comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.