The key idea of smooth movement is to change velocity gradually not in jumps.
Before doing smooth movement you usually have something like this:
Code: Select all
if arrowKeyIsPressed then
movePlayerAtConstantVelocity
else
dontMovePlayer
end
That means that in the moment you press the button, the player accelerates from zero to full speed in no time. For some sorts of games, this is alright (old Zelda games, Megaman), but not for others. Smooth movements means you need some time to change from zero velocity to full velocity.
Now for the line of code, you are struggling with:
Code: Select all
player.xvel = player.xvel * (1 - math.min(dt*player.friction, 1))
First, ignore the math.min and look at that:
Code: Select all
player.xvel = player.xvel * (1 - dt*player.friction)
this can be expanded and you get:
Code: Select all
player.xvel = player.xvel - player.xvel * dt * player.friction
That means that the player's x-velocity is changed by (player.xvel*dt*player.friction). This term defines how fast the player slows down. You can see, that if the player is very fast, then he slows down fast. If he is slow (player.xvel almost zero) then the slowing down is slow.
Now for the math.min. This function returns the smaller of the two values inside. So
returns dt*player.friction if it is smaller than 1, and 1 otherwise. Putting this into the formula simply makes the code a bit shorter. The point is, if the player is moving left and is then slowed down due to acceleration, you don't want the player to "overshoot" and start moving to the right. This would happen if the term in the brackets
Code: Select all
(1 - math.min(dt*player.friction, 1))
becomes negative. In that case, the velocity would change sign (direction). To avoid that, this math.min-function ensures that if the term becomes negativ, then it is put to zero.