In which I summon up the quadratic formula to battle a problem whose solution doesn’t seem to be on the internet yet
There’s a very common mechanic in action games where you can control how high you jump through how long you hold down the jump button. Back in the day Sonic the Hedgehog implemented this by directly twiddling the player’s velocity, but modern games built on a physics engine usually do something like this:
when jump is first pressed: |
Typically you’d just tweak J
and F
until you’re happy with how the player is jumping.
The problem I ran into today is, I want to define the total height of the jump as a tunable parameter, and derive J
and F
such that the jump winds up being the desired height. That way I can have something like an “item that lets you jump 3 blocks higher than usual” without stopping to figure out what physics settings would make the jump work out that way.
To achieve this, we have to dust off some high school physics.
The initial impulse
When jump is first pressed we apply an impulse J
, which should be strong enough to cause a jump of height h
. If the button is immediately released no further forces will be applied, so h
is the minumum height it’s possible to jump.
Deriving J
is straightforward - we just note how much potential energy the player will have at the peak of the jump, and apply an impulse giving the same amount of kinetic energy. Assuming a player of mass m
, under gravity g
:
PE = mgh // Potential energy at peak of jump |
The gradual force
Now the hard part. After the player jumps, we apply a force F
over some time t
(or until the button is released). We want to tune F
such that, if applied for time t
, the jump will reach a total height of H
.
As before, we can note that at the peak of the total jump the body will have potential energy mgH
, so the work W
done by the gradual force must be that value minus the energy contributed by the initial impulse. However, work is force times distance, so we’ll need to define d
as the distance the body moves while the force is applied, and then state d
in known terms so it can cancel out of the equation.
Here goes:
PE = mgh // Potential energy at peak of jump |
At this point F is defined purely in terms of known values - all that’s left is to solve for it. For clarity, define f = F/m
f = F/m |
Implementation
And there you have it! Below are my javascript implementations. In both cases, dist
is the distance contributed by that part of the jump physics, so the total jump height will be the sum of the distances you pass to each function.
function getJumpImpulse(dist, g, mass) { |
Caveat
When plugged into an actual game, your character will jump a little bit lower than the equations predict, due to the physics being simulated in discrete timesteps. The size of the error will depend on how big your timesteps are.