There is a counter that only allows Mario to accelerate vertically for 8 consecutive frames. Release KEY_JUMP at any time before frame 8 and gravity takes over.
When you are on the ground and press KEY_JUMP, the code calculates an initial velocity for Mario, changes his position accordingly and then calculates a decreased velocity owing to friction and gravity before that frame’s tick() ends. If you are pressing KEY_JUMP the next frame, this slower velocity is thrown away and another new initial velocity, smaller than the one before it, but still upwards, is added to Mario’s position and again a final, slower velocity is calculated before the frame’s end. This repeats until frame 8 when your jump runs out and gravity is the only y acceleration acting on Mario.
Here’s a quick table that displays velocities and heights, as it’s not really worth the rigmarole involved in deriving complex equations for so discrete a frame set.
|Frame||Initial Velocity||Height||Final Velocity|
|1||7 * 1.9||13.3||8.305|
|2||7 * 1.9||26.6||8.305|
|4||5 * 1.9||47.5||5.075|
|5||4 * 1.9||55.1||3.46|
|6||3 * 1.9||60.8||1.845|
|7||2 * 1.9||64.6||0.23|
|8||1 * 1.9||66.5||-1.385|
Here I’ve written the velocities with a positive sign, since upwards is considered positive on most x/y axes. The code that handles this actually uses negative numbers as it’s axis is upside down, but this shouldn’t affect relative distances and positive numbers look better on blogs so I’m going to use them.
Also, the velocity for the first two frames is not a typo, it really is set to the same value both frames, and as we’ll see after studying gravity, hitting jump for a single frame gives Mario just enough juice to clear hills that are a single block high.