How to implement frictional in a game
Some time ago I watched a YouTube video in which indie game developer @randy showed how he implemented physics in his game. My attention was drawn to the incorrectly (not in accordance with the rules of physics) implemented frictional force. In this post I will answer why.
First, let’s see how randy’s basic motion kinematics is implemented. Below I present the pseudo code:
new_velocity = old_velocity + acceleration * delta_time // velocity v(t)
new_position = old_position + new_velocity * delta_time // displacement d(t)
Everything looks good here. Change in displacement over time, that’s the physical interpretation of velocity, while change in velocity over time, that’s acceleration.
Now let’s look at how @randy implemented friction:
new_acceleration = old_acceleration - velocity * friction * delta_time
Although the above code generates the effect of slowing down a body that is in motion, it is an implementation that is inconsistent with how friction works in reality. I would only add that we are here talking about dynamic friction, which acts on a body moving with velocity v. Such a force does not depend on the speed, but only on the pressure of the body on the ground (mass + gravitational force). The above formula assumes that the faster a body gliding on the ground moves, the more friction slows it down.
Friction as a “force” should affect (change) the speed of the body. And since both mass and gravitational force are constant, friction should be constant throughout the entire duration of motion.
In each time interval of length delta_time
we take the value of the velocity (which is the average velocity in that time interval, because in games time is not continuous as in reality) and subtract from it the value of the frictional force. Friction is a force and therefore a change in velocity over time, so we also multiply it by delta_time
.
new_velocity = old_velocity + acceleration * delta_time - friction * delta_time
= old_velocity + (acceleration - friction) * delta_time
new_position = old_position + new_velocity * delta_time
It appears that friction is a simple constant that reduces acceleration.
Furthermore, note how, in effect, to calculate new_position
we multiply friction
by delta_time
squared. Since friction represents the change in velocity over time, and velocity represents the change in displacement over time, this means that friction is in this situation the second derivative of velocity after time.
d"(t) = v'(t) = a(t) <- friction at time t
Of course, in games we do not have a real “moment” t
of length going to zero, so such ideal formulas are only a model for approximating the laws of physics in the intervals between one displayed game frame and another.
Integrating the above formula after time (dt) and assuming that the friction a(t)
is constant and equal to a
(which we established earlier to be true), we get:
v(t) = v0 + a * t
d(t) = d0 + v0 * t + (a * t * t) / 2
So we came up with the classic formulas for velocity and displacement in uniformly accelerated motion. Zero surprise, because friction is simply a force, so acceleration (deceleration) in the direction opposite to the direction of motion.
Finally, there is a known deceleration force proportional to velocity, and it is air resistance. So, in fact, for the calculation of deceleration this velocity must be taken into account anyway. So it may turn out that the friction implemented by @randy is not at all such a bad approximation as it seems at first glance :)