I've seen a few tutorials that have commented that systems to make a character smoothly accelerate or decelerate were "too complicated to go into here", or have included large blocks of code to handle it. Well, I'm here to tell you that this is not the case! A nice smooth acceleration and deceleration can both be handled in a single line of code! Code: speed = (speed + acceleration) * deceleration A couple caveats: speed and acceleration are both in pixels per frame. deceleration is a percentage, ranging from 0 to 1. Because deceleration is being applied to acceleration immediately, your actual speed gain is acceleration * deceleration. For example, if acceleration is 10 and deceleration is 0.8, you only gain 8 speed in the first frame (and less in each subsequent frame, because you're losing 20% of speed's current value). Setting deceleration to 0 will prevent your character from moving. Setting deceleration to 1 will make your character accelerate linearly, with no cap. Setting deceleration over 1 will make the character accelerate faster than the acceleration value, and will make them continue to accelerate, even after they stop moving. This applies acceleration and deceleration every frame! As such, if you're working with very small values (such as pixel movement in a low-res game), you will hit the cap super fast, and there won't be any visible smooth acceleration/deceleration. We'll discuss how to deal with that a bit further down. So, what does this formula do for us? First, look at the following graphs: On the Accelerating chart, the object is starting at 0 and adding 5, then decelerating by 0.70 each frame. On the Decelerating chart, it's starting just below 12 (where the previous chart maxed out), adding 0 per frame, and still decelerating by 0.70. If you were to accelerate in the opposite direction, it would do the exact same thing, just in negative numbers. Technically, it will never reach 12, instead becoming infinitely close. Likewise, the speed will never drop to 0 (unless you apply negative acceleration), but will again get infinitely close; so close that it would take years to move a single pixel. Due to the limits of computer storage and the resulting rounding errors, you will eventually get a result of those maximum or minimum numbers. If you don't want sub-pixel movements, you could apply a round() to the formula. It would alter the curve, but still give a similar final effect. Do not use floor() or ceil() though, as those round down or up, not towards or away from 0 as many people expect (ie, floor(3.5) is 3, but floor(-3.5) is -4, not -3). Be aware that this has it's own risk: In the charts above, since deceleration is 0.7, you get the following results: 12 * 0.70 = 8.40 = 8 8 * 0.70 = 5.60 = 6 6 * 0.70 = 4.20 = 4 4 * 0.70 = 2.80 = 3 3 * 0.70 = 2.10 = 2 2 * 0.70 = 1.40 = 1 1 * 0.70 = 0.70 = 1 1 * 0.70 = 0.70 = 1 Without some sort of error checking, the character never stops once they start moving. Personally, I'd recommend sticking with the unrounded, sub-pixel movement. If you are using delta time, the calculations become a bit more complicated, but not untenable. The first thing you have to do is reduce acceleration from its per-second value to its per-frame value. This is easy: Code: acceleration * delta So, if your acceleration is 60 pixels per second and delta is exactly 1/60 of a second this frame, you get an acceleration of 60/60 or 1 pixel. However, if you do the same thing to deceleration, everything falls apart. If you take a deceleration of 0.60 and multiply it by the same 1/60 above, you get 0.60/60 = 0.01, which, over the course of 1 second results in the retention of 0.000000000000000000000000000000000000000000000000000000000001% of a pixel per second, which is so small that internal rounding would make it so that there was no movement at all. What went wrong? It's because the value of deceleration is what's left over after we slow down, and we don't want to break that up into it's per-frame value, we want the loss (in the above example 100% - 60% = 40% or 0.40) to be broken up. So the per-frame for deceleration is: Code: (1 - ((1 - deceleration) * delta)) What's happening there? First, we're subtracting deceleration from 1 to give us the speed loss as a percentage. Then, we're multiplying that by delta to figure out how much speed is lost per frame. Then, we're subtracting the per-frame speed loss from 1, so that we again have the percentage of speed retained. Taken together, it's: Code: speed = (speed + (acceleration * delta)) * (1 - ((1 - deceleration) * delta)) Of course, you could get the same result by just using the first formula and the per-second values adjusted to their per-frame values, but this method lets you set acceleration and deceleration as per-second values, and have them stay accurate, even in the case of lag or frame skips. The one drawback to this system is that the maximum speed is not easily calculated based on your acceleration and deceleration values. Looking at the original chart, how do we get a max speed of 12 from acceleration 5 and deceleration 0.70? Each frame, we take the starting value, add acceleration, and multiply the total by deceleration. This is the same as taking the starting speed and multiplying it by deceleration, and then adding acceleration * deceleration. Each frame, the starting value of speed is the ending value of the previous frame. Frame 1: (5 * 0.70) Frame 2: (5 * 0.70) + (5 * 0.70 * 0.70) Frame 3: (5 * 0.70) + (5 * 0.70 * 0.70) + (5 * 0.70 * 0.70 * 0.70) And so on. Eventually, the difference between two frames becomes immeasurably small. If you know calculus, there should be some way to calculate that limit based on the known information. However, that's beyond my mathematical skills. For me, the easiest way is to plug the numbers into a spreadsheet like the one I used to generate those graphs, and tweak acceleration and deceleration until I get the numbers I want. Hopefully this helps someone out there. Questions, comments or corrections? Post 'em below. And if you're a math whiz and want to fill in that final formula for me, please do so! Thanks all for reading!