Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

Ok, so I am making a first person shooter game and I am currently working on movement that looks and feels good. I want to incorporate acceleration based movement for the player so that he has to accelerate to max speed and decelerate to minimum speed. Acceleration will happen when you have the key pressed and deceleration will happen when you let go of that key. The problem is that there are some instances where you switch from moving forward to moving backward where no deceleration is needed because you could potentially be moving at double speed in the reverse if you did. Does anyone have a good implementation of how to accomplish acceleration based movement that works well?

share|improve this question
    
When the key is down you could just add an x amount of velocity(building up from zero to max velocity) to your position. When you hit the backward key the velocity decreases going into the minus zero. You're still adding the velocity to your position. Once it goes into a negative number, the addition of this velocity turns into a subtraction. Giving the effect that your character is decelerating first and then walks backward. When no keys are pressed you can interpolate towards zero. This could also be done by multiplying by a number smaller than 1 i.e. 0.98f Giving the effect of friction. –  Sidar Sep 4 '12 at 20:22
    
Just as a note because it's somewhat unclear from the question but deceleration should go toward 0. You'll still want deceleration toward 0 when you stop moving backward, None at all would cause you to drift backward forever. –  Lunin Sep 4 '12 at 21:14
    
@lunin; That's why I suggest multiplying the velocity by a number smaller than 1 when no key is pressed. Because the velocity becomes smaller and smaller on every step eventually hitting zero. A fake friction if you will. –  Sidar Sep 5 '12 at 4:05
    
@Sidar So you did! That's what I get for commenting before fully reading all the other comments –  Lunin Sep 6 '12 at 17:20
    
@Lunin yeah, I too draw conclusions too fast...we need to stop doing that =P –  Sidar Sep 6 '12 at 19:16
show 1 more comment

1 Answer 1

There's something weird about your concept of the issue since you say, "could potentially be moving at double speed in the reverse." This should not be the case with an acceleration-based solution.

You will have a double playerVelocity value in your Player class. To keep it simple for now, imagine just forward/backward velocity. Every frame, you add your acceleration value (PLAYER_ACCELERATION) to the player's velocity until it reaches a maximum - the speed at which you generally want the player to run (PLAYER_MAX_SPEED). This should only take a handful of frames unless you want the controls to feel very "floaty". (You don't for a modern FPS.)

If the player reverses direction, you add negative acceleration. If they are moving forward at full speed and reverse direction, it will take them twice as long to get to "full speed reverse" than it does from standing still.

If the player releases all buttons, you add acceleration towards zero. He will slow down until he stops.

An implementation:

final PLAYER_MAX_SPEED = 1.0f;
final PLAYER_ACCELERATION = 0.2f
double playerVelocity = 0.0f;

public void update() {        // Called every frame, and assuming constant fps

    if (forward_button_down) {

        // The player is holding the "move forward" button
        playerVelocity += PLAYER_ACCELERATION;
        if (playerVelocity > PLAYER_MAX_SPEED) {
            playerVelocity = PLAYER_MAX_SPEED;
        }

    } else if (backward_button_down) {

        // The player is holding the "move backward" button
        playerVelocity -= PLAYER_ACCELERATION;
        if (playerVelocity < -PLAYER_MAX_SPEED) {
            playerVelocity = -PLAYER_MAX_SPEED;
        }

    } else {

        // Neither forward nor backward pressed
        if (playerVelocity < 0) {
            playerVelocity += PLAYER_ACCELERATION;
            if (playerVelocity >= 0) {
                playerVelocity = 0.0f;
            }
        } else {
            playerVelocity -= PLAYER_ACCELERATION;
            if (playerVelocity <= 0) {
                playerVelocity = 0.0f;
        }
    }
}

Another thing you'll probably want to do is make the player accelerate much more quickly toward zero than he accelerates beyond zero, otherwise your character will feel unresponsive.

If you use something like this for forward/backward, and another variable for left/right, you'll have to limit the combined speed (bust out your geometry), otherwise your character will move diagonally-forward faster than he moves only-forward.

share|improve this answer
add 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.