How do I implement deceleration?

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.

• 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. :) – Ipsquiggle Oct 20 '10 at 19:23
• Flixel calls this "drag," in case you're looking for a term that's independent of acceleration. – Gregory Avery-Weir Oct 20 '10 at 20:19
• "Deceleration" is negative acceleration. Have you taken calculus? – 3Dave Oct 20 '10 at 20:57
• Actually "Deceleration" isn't a real thing, nor is "negative acceleration". It's all regular acceleration, just in different directions. – MichaelHouse Jul 21 '12 at 0:16

Something as simple as

this.velocity.i *= 0.9;


works nicely.

• 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. – Xavura Oct 20 '10 at 18:26
• 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. – CodexArcanum Oct 20 '10 at 18:56

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.

• That's a very interesting formula. I'll have to keep that in mind for the future! – Ipsquiggle Oct 20 '10 at 19:53
• +1 Looks interesting, I think I might throw it into some code to see it work. – David Young Oct 20 '10 at 20:35
• Very good formula. I'm going to use this. Where did you get it from? Or did you derive it yourself? – Riki Sep 25 '11 at 0:32
• 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. – earok Oct 11 '11 at 0:55

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.)

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.

• I figured I would have to put a check in place, as well, but it seems to work without one. – Xavura Oct 20 '10 at 18:33