Search code examples
mathgravity

Solving the time an object takes to accelerate upwards taking gravity into account


I have an character in a game that can jump; the jump height can be affected by holding down the jump button for a longer time. There is a maximum velocity the character can reach in the upwards direction, and I am trying to figure out how long the longest jump can be taking gravity into account.

I'm pretty sure this has something to do with SUVAT equations as the object is accelerating, but I can't seem to work gravity into the equation. Here are the variables I'm working with...

JumpVelocity = 2.0,
JumpAccel = 0.5,
JumpMax = 7.5,
Gravity = -14.0,

as soon as jump is pressed an initial velocity is set...

yVelocity = JumpVelocity;

and then every frame the jump button is held the velocity is increased until it reaches the cap

if (!jumpFinished)
{
    yVelocity += JumpAccel; 
    yVelocity += Gravity * deltaTime;
    if (yVelocity >= JumpMax) 
    {
        yVelocity = JumpMax;
        jumpFinished = true;
    }
}
yVelocity *= deltaTime;

I check to see if the jump is finished with:

if (yVelocity <= 0.0)

What I want to solve is how long the whole upwards phase of the jump process will take if the user were to max-out the jump velocity?


Solution

  • You let the initial velocity be increased while pressing, with the character already moving, so you have 2 differente stages:

    STAGE 1

    An initial positive acceleration, your character accelerate, sort of rocket or jetpack.

    Initial conditions (t=0 of this branch):

    v0   = JumpVelocity
    vmax = JumpMax
    a    = Gravity + jaccel 
    r0   = 0 (initial height)
    

    note that jaccel is not JumpAccel. Given your code JumpAccel is the variation of velocity in deltaTime time. So the actual burst acceleration is jaccel = JumpAccel/deltaTime. (USEFUL: for completeness - provide deltaTime).

    This line in your code makes no sense to me: please explain.

    yVelocity *= deltaTime;
    

    Now you want to know when v, the velocity, reaches vmax. Given:

    v = v0 + a*t
    

    you want to find the value of t at which v=vmax. So you substitute and solve for t:

    vmax = v0 + a*t
    t = (vmax - v0)/a
    

    or, using your symbols:

    t = (JumpMax - JumpVelocity)/(Gravity + jaccel)
    

    From t you can now evaluate the height that you have reached when you are at the maximum velocity. Get this kinematic equation:

    r = r0 + v0*t + 0.5*a*t*t
    

    and substitute all the variables to get r1, the position at the end of the thurst.

    r1 = 0 + JumpVelocity*t + 0.5*(Gravity + jaccel)*t*t
    

    STAGE 2

    The character continue decelerating until reaches the maximum height, that's what you want to know.

    In this second problem we "move" the time origin here, where the first stage has just completed, so we are at t=0 again (this cannot be applied in the graph - the coordinate system is only one there... few more subtractions because of this in the gnuplot commands below). Forget about the previously evaluated t - its out of scope now. Our current initial conditions are:

    v0   = JumpMax
    a    = Gravity
    r0   = r1, r evaluated at the previous stage
    

    Now you want to find the value of t when v=0. So, using again:

    v = v0 + a*t
    

    substituting v = 0 and solving for t:

    0 = v0 + a*t
    t = -v0/a
    

    That using your variables (no symbols substitutions as shown before - easier to follow and you can evaluate it actually):

    t = -JumpMax/Gravity
    

    replacing t in the kinematic equation with constant acceleration, in order to find the position at that time (the time of the maximum height!):

    r = r0 + v0*t + 0.5*a*t*t
    

    that, using your variables is:

    rmax = r1 + JumpMax*t + 0.5*Gravity*t*t.
    

    That's it: rmax is the maximum height reached by your character.

    To conclude, I have enjoyed to plot the two functions using gnuplot - it's available for free for both linux and windows, so you can play with it.

    In the graph you can get the position at the various timesteps (each point is at a subsequent timestep, being plotted the height, r, versus the time, t). The two arrows point to r1 and rmax, evaluated using the formulas obtained above (see the gnuplot commands)

    plotted with gnuplot

    Here the gnuplot commands to generate the graph - good luck!

    unset key
    
    JumpVelocity = 2.0
    JumpMax = 7.5
    Gravity = -14
    jaccel = 30
    
    const_acc(t,r0,v0,a) = r0 + v0*t + 0.5*a*t**2
    
    t1 = (JumpMax - JumpVelocity)/(Gravity + jaccel)
    r1 = const_acc(t1, 0, JumpVelocity,Gravity+jaccel)
    t2 = -JumpMax/Gravity + t1
    rmax = const_acc(t2-t1, r1, JumpMax, Gravity)
    
    set arrow from t1,0 to t1,r1
    set arrow from t2,0 to t2,rmax
    
    set xlabel "t" 
    set ylabel "r" 
    set xrange [ 0 : 2 ]
    set yrange [ 0 : ]
    
    plot x <= t1 ? const_acc(x,0,JumpVelocity,Gravity + jaccel) : 1/0 w p, x >= t1 ? const_acc(x-t1, r1, JumpMax, Gravity) : 1/0 w p
    pause -1