One simple solution is to keep a timer and a boolean. When the button is first pressed, if the boolean is false and the player is on the ground, apply the force and start set thee timer to some specific and set the boolean to true. When the button is released, set the boolean to false. If the boolean is true, decrement the timer by the time delta. Keep applying the force each frame so long as the boolean is true and the timer hasn't expired.
bool is_jumping = false
float jump_timer = 0.0
jump_pressed () {
if (!is_jumping && is_on_ground())) {
is_jumping = true
jump_timer = 0.5
}
}
jump_released () {
is_jumping = false
}
update (float time_delta) {
if (is_jumping) {
jump_timer = max(0.0, jump_timer - time_delta)
if (jump_timer > 0.0)
apply_jump_force()
}
}
Finding the ideal timer length and force will take some tweaking. You could with some work derive the right values to get a particular jump height, but I would play with the values until you get something that feels right.
The advantages of this approach are that pressing the button for longer results in a higher jump, which is what you want if you want your platformer to feel "right" (like Mario).
If you want stiffer controls, you could allow a fixed jump velocity. Just set that boolean when the player jumps, and reset it when the player lands.
bool is_jumping = false
jump_pressed () {
if (!is_jumping && is_on_ground())
is_jumping = true
apply_jump_force()
}
}
update () {
if (is_on_ground())
is_jumping = false
}
Be mindful that will require a little more work if update is called after jump_pressed
is called but before physics updates and the jump force is applied. You might need an extra bool or check to avoid resetting is_jumping
on that first frame.
More advanced versions can start the jump after the button is released (measuring how long the button was held) or after a timer expired (it should be a pretty short timer).
You can with this method also use fixed gradiations of jump height, e.g. a short jump if the button time is 0 - 0.05 seconds and a high jump if button time is 0.05 - 0.1 seconds. All that needs to change there is the amount of force applied for a decent effect.
Even with variable jump height, you might want a stable upward velocity, up to a point, rather than the high initial jump velocity and steady gravity acceleration. in this case, you need to each frame during jump ascent (measured again with a timer) calculate the necessary force to apply to achieve the desired velocity. This requires some knowledge of physics formulas and how your physics library updates, but is otherwise pretty simple.