I want to have the player decelerate without having to use a bunch of if statements.
–
tesselodeOct 7 '12 at 15:19

Are you wanting to accelerate and decelerate exponentially every time? You seem somewhat confused about what you're asking since you say you want to double the speed every second, but your code shows doubling the position.
–
Byte56♦Oct 7 '12 at 17:03

Yeah, I want to change the speed, not the position. Fixed.
–
tesselodeOct 7 '12 at 17:16

+1 but I was struggling a little bit to answer the sub-question (how to double speed every second) - I can't find a way to exactly double the speed every second, given only delta_time elapsed and current speed!
–
Markus von BroadyOct 7 '12 at 16:03

You would use an exponential function for the acceleration to double the speed every second. I'm not sure if OP actually wants that. It will get out of hand quickly.
–
Byte56♦Oct 7 '12 at 16:05

The OP seemed to be talking about doubling the position every second anyway (player.x = player.x * 2) Which would get out of hand even quicker, exponentially quicker.
–
Byte56♦Oct 7 '12 at 16:08

He 'wanted' (because I also think he doesn't need that) to double his speed, not position every second, and he wanted to base it on delta_time! I find the problem hard without storing some "oldSpeed" value, refreshed every second.
–
Markus von BroadyOct 7 '12 at 16:12

which means in each frame you need to multiply velocity by CONSTANT^dt

EDIT

Based on the edits the edits you made in your question, you don't really need to implement this exponential method. Assuming you are going to simulate friction, you can also implement more physical method:

Physically friction reduces speed by linear manner, assuming Object mass doesn't change over time. It's applying a force to the object, exactly in opposite direction as object's current velocity. For example let's assume Friction always reduces speed by two units every second, you need to find velocity's current direction, reverse it, and reduce a vector of length two in that direction multiplied dt. here is some code to help you understand:

there is one small little thing that you might want to notice, by that code if speed is too low, the Object will jitter in it's position. That's because Fricton_Direction * dt is bigger than velocity itself, which will lead to object moving exactly in opposite direction in the next step, instead of standing still. to fix that you need to add an if statement to check if Velocity is too low and Object should be completely stopped. I'll do it like this:

As others have noted, the correct formula for deceleration due to dry friction is

velocity += constant * dt * -dir( velocity )

where dir(v) returns a vector of unit length pointing in the same direction as v.
(For one-dimensional movement, dir(v) = 1 if v > 0 and dir(v) = -1 if v < 0.)
One way to calculate it is as

dir(v) = v / abs(v)

where abs(v) gives the length or magnitude of the vector v.

To keep objects from jittering after they come to a stop (and to avoid dividing by zero if we try to calculate the direction of a prefectly stationary object), we should also ensure that the change in velocity never exceeds the original magnitude of the velocity — that is, friction should never cause an object to start moving backwards. Putting all this together, a reasonable implementation of friction in a game is:

Note that this works even if the object is moving in more than one dimension, so that velocity is a vector. (Of course, the actual code for doing this with vectors might look somewhat different, depending on what notation your language uses for vector arithmetic.)

You can add other velocity changes before or after this code; if you add them before, then small enough forces may be completely canceled by friction, which is actually realistic. In fact, for further realism, you may want to implement static friction by having the constant in the friction calculation vary depending on whether or not the velocity of the object was non-zero at the beginning of this timestep.

Also, if you want to be really accurate, you should take acceleration during the timestep into account when updating the object's position. That is, instead of just doing

velocity += delta_v;
position += velocity * dt;

you should do

velocity += delta_v;
position += ( velocity - delta_v / 2 ) * dt;

where velocity - delta_v / 2 is the average of the velocities before and after adding in delta_v.

This latter approximation to Newton's laws of motion is actually exact as long as acceleration = delta_v / dt is constant, and in any case is a better approximation than the former even for changing delta_v. However, for games with a small and constant timestep dt, the difference is generally not noticeable, at least without side-by-side comparison. The main advantage of the more accurate form is that it makes object trajectories less sensitive to changes in dt.

I should also point out that (dry) friction is not the only force that can slow down moving objects. For example, objects moving through water or air experience drag, which follows a formula that generally looks something like

delta_v = ( a * speed + b ) * -velocity * dt

where a and b are constants that depend on a lot of things such as the density and viscosity of the fluid and the mass, size and shape of the object moving through it. (See the Wikipedia link above for details; a above corresponds to Newton drag, while b corresponds to Stokes drag.)

For macroscopic objects moving through fairly inviscid fluids like water or air, b should be very small or even zero, whereas a viscous fluid like lava or molasses calls for a higher b. For game purposes, just play around with the values until you get the effect you want.

Note that, unlike with dry friction, drag forces never bring a moving object to a complete stop, so we generally don't need to worry about accidental direction reversals. The exception to this is if (a * speed + b) * dt > 1, which can happen if dt is too large or if the object somehow acquires an unusually high velocity; if that might happen, the solution is either to dynamically adjust dt to be smaller for fast-moving objects or to use a higher-order motion integrator (which really goes beyond the scope of this post).

//define a constant somewhere in your code so you could adjust the value later
DECCELLARATION_RATE = 20;
//Checks if the speed is positive or negative so we will decrease it's absolute value:
sign = (speed >= 0? 1 : -1);
//Decrease the absolute value of the speed while maintaing it's sign
speed -= sign * DECCELLARATION_RATE * dt
//If the object is moving too slowly, the above command will change the speed's sign and with it the direction of the movement.
//What we want to do is stop the object in this case.
if(sign != (speed >= 0? 1 : -1)) speed = 0;

The operator (condition ? value_if_true : value_if_false )
is called the ternary operator. You can read about it more here:

1. you answer only works for 1D world. 2. in case we assume OP wanted 1D answer both me and Byte have already given this answer.
–
Ali.SOct 7 '12 at 19:23

3

The link you gave is goes to the generic page about question marks. Why is your answer spending more space explaining ternary operators with absolutely no explanation of your movement code?
–
Justin SkilesOct 7 '12 at 19:33

@JustinSkiles Thanks, I fixed the link. He asked how to make his code short and simple, I offered a tool called a ternary operator. I'm guessing the OP is not familiar with it so I explained what it does in detail. I edited the answer to add some comments explaining the code itself. I thought it was very short and pretty clear once your know what a ternary operator does.
–
zehelvionOct 7 '12 at 19:42

@Gajoo All the things you wrote do not change the fact that 1.this answer is suitable for manipulating the x-axis speed in a 2D platformer game. 2. It matches the edited question perfectly. 3. You most likely downvoted Byte56 originally and myself now because of being competative. None of your explainations show why this answer is less useful when considering the question. In addition the last part of your answer deals with the exact same suituation. So you must think it's somewhat useful.
–
zehelvionOct 7 '12 at 20:32

2

+1 it may be not the best answer, but it shows the solution in a different way, and therefore is a positive input not deserving -3 for sure.
–
Markus von BroadyOct 7 '12 at 21:08