12
\$\begingroup\$

I say "deceleration" because I'm not using acceleration at the moment; what I mean is moving the velocity back towards zero, eventually stopping.

I'm new to vectors and not so great with physics and such. How is "deceleration" normally handled?


What I have now works, but it seems kind of hackish.

update:function(Game, t, dt) {
    var speed = Game.Input.isKeyDown('shift') ? 8 : 4;

    if (Game.Input.isKeyDown('a')) {
        this.velocity.i -= speed;
    }
    else if (Game.Input.isKeyDown('d')) {
        this.velocity.i += speed;
    }
    else {
        if (Math.abs(this.velocity.i) > 3) {
            this.velocity.i += (this.velocity.i > 0) ? -speed : speed;
        }
        else {
            this.velocity.i = 0;
        }
    }

    if (Game.Input.isKeyDown('w')) {
        this.velocity.j -= speed;
    }
    else if (Game.Input.isKeyDown('s')) {
        this.velocity.j += speed;
    }
    else {
        if (Math.abs(this.velocity.j) > 3) {
            this.velocity.j += (this.velocity.j > 0) ? -speed : speed;
        }
        else {
            this.velocity.j = 0;
        }
    }

    this.updateVectors(dt);
}

I used 3 because anything lower exhibits weird behaviour, I'm guessing if I raised the speed then it would need to be changed.

\$\endgroup\$
4
  • 2
    \$\begingroup\$ Also little semantic detail.. in the statement velocity.i += speed; the speed is in fact your acceleration, i.e. the rate that velocity changes by. :) \$\endgroup\$
    – Ipsquiggle
    Commented Oct 20, 2010 at 19:23
  • \$\begingroup\$ Flixel calls this "drag," in case you're looking for a term that's independent of acceleration. \$\endgroup\$ Commented Oct 20, 2010 at 20:19
  • \$\begingroup\$ "Deceleration" is negative acceleration. Have you taken calculus? \$\endgroup\$
    – 3Dave
    Commented Oct 20, 2010 at 20:57
  • 1
    \$\begingroup\$ Actually "Deceleration" isn't a real thing, nor is "negative acceleration". It's all regular acceleration, just in different directions. \$\endgroup\$
    – House
    Commented Jul 21, 2012 at 0:16

4 Answers 4

16
\$\begingroup\$

Something as simple as

this.velocity.i *= 0.9;

works nicely.

\$\endgroup\$
3
  • \$\begingroup\$ Heh, trust me to over-complicate it that bad. I just read recently that you can simulate basic air resistance by multiplying by 0.9 and still that didn't come to mind. Thank you. \$\endgroup\$
    – Xavura
    Commented Oct 20, 2010 at 18:26
  • \$\begingroup\$ Haha, oh wow, yeah. I was calculating an inverse vector normal and multiplying it by a slow-down factor. Why didn't I just do this? Sometimes the really obvious answers are the easiest to miss. \$\endgroup\$ Commented Oct 20, 2010 at 18:56
  • \$\begingroup\$ I believe this will perform badly in scenarios where the FPS is floating (e.g. the delta between frames is small in one frame and big on the next one). \$\endgroup\$ Commented Apr 16, 2022 at 11:23
7
\$\begingroup\$

In Pseudocode, I do variations of this:

Speed += ((MoveDirection * MaximumSpeed) - Speed) * AccelerationFactor

Where:

  • Speed is the current speed the entity is travelling at on the current axis.
  • MoveDirection is the direction the entity is trying to travel in on the current axis, 1 is forward, 0 is still and -1 is backwards. All values in between are allowed.
  • MaximumSpeed is a constant determining the fastest that the entity can travel on the current axis.
  • AccelerationFactor is a constant between 0 and 1 that represents the rate of acceleration and deceleration. 1 is instant, and 0 will never move.

Which handles both Acceleration and Deceleration nicely in a curved, rather than line. If you want different acceleration and deceleration rates you could do IF statements that determine whether the player is attempting to not move or move in the opposite direction.

\$\endgroup\$
4
  • 1
    \$\begingroup\$ That's a very interesting formula. I'll have to keep that in mind for the future! \$\endgroup\$
    – Ipsquiggle
    Commented Oct 20, 2010 at 19:53
  • \$\begingroup\$ +1 Looks interesting, I think I might throw it into some code to see it work. \$\endgroup\$ Commented Oct 20, 2010 at 20:35
  • \$\begingroup\$ Very good formula. I'm going to use this. Where did you get it from? Or did you derive it yourself? \$\endgroup\$
    – Riki
    Commented Sep 25, 2011 at 0:32
  • \$\begingroup\$ Sorry for the delay on responding, I vaguely remember being inspired by the code of one of the Blitz3D demos, I can't remember which one though. \$\endgroup\$
    – earok
    Commented Oct 11, 2011 at 0:55
3
\$\begingroup\$

The answers here (vel = vel * 0.9) are actually damping, not what I would consider 'deceleration'.

I often do deceleration like this:

if ( Game.Input.isKeyDown( "w" ) )
{
    this.velocity.i = Math.max( -WALKSPEED, this.velocity.i - WALKFORCE);
}
else if ( Game.Input.isKeyDown( "d" ) )
{
    this.velocity.i = Math.min( WALKSPEED, this.velocity.i + WALKFORCE);
}
else
{
    if (this.velocity.i < 0)
    {
        this.velocity.i = Math.min( 0, this.velocity.i + WALKFORCE);
    }
    else if (this.velocity.i > 0)
    {
        this.velocity.i = Math.max( 0, this.velocity.i - WALKFORCE);
    }
}

Some pros and cons vs. damping:

Pros:

  • The speeding up acceleration and the slowing down acceleration are both linear, which gives a pleasant subtle 'game feel' that I think damping doesn't provide. This is the important part.
  • The character comes to a predictable complete stop after a predictable number of iterations.

Cons:

  • This is trickier to implement if you are using non-orthogonal motion (which it sounds like you are?) Basically, you have to get a force vector that is aligned with the velocity, compare lengths, and subtract or zero-out as approrpriate. (If you want that explained with code, just ask.)
\$\endgroup\$
1
\$\begingroup\$

Very simply put, in pseudo code:

if(no movement keys pressed) [Meaning we want to start to decelerate]
current speed *= 0.85 [Or some number between 0 and 1, the smaller the faster the deceleration]

However, you would need to check if(current speed < 0.001f) or something and set to 0.

\$\endgroup\$
1
  • \$\begingroup\$ I figured I would have to put a check in place, as well, but it seems to work without one. \$\endgroup\$
    – Xavura
    Commented Oct 20, 2010 at 18:33

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .