Jumping to a Specific Height

J

Jordan Robinson

Guest
Jumping to a Specific Height
Jordan Robinson

GM Version: 1.4.1757
Target Platform: ALL
Download: N/A
Links: N/A

Summary:
This tutorial will explain how you can easily make your player jump to a specific height, thus giving you more control over movement.

Tutorial:
The end result of this tutorial will be a small formula, easily implemented with a bit of GML, which will have our player jumping exactly how we want. But before we get to the coding, we need to look at a little bit of theory.

A couple of terms I will be using here are kinetic energy and potential energy. Before the player jumps, his potential energy (Pe) is 0 (with regard to his vertical motion). At the top of the jump, the player's kinetic energy (Ke) is 0. Therefore, we can say that: Ke(top) = Pe(bottom)

Ke = 0.5mv^2
where m = mass and v = velocity.
Pe = mgh
where m = mass, g = gravity acceleration, and h = height.

We now have everything we need to start working out our formula.

Ke(top) = Pe(bottom)
0.5mv^2 = mgh

Simplifying the equation:
0.5v^2 = gh
v^2 = 2gh
v = √2gh

Result:
v = √2gh
where v is the jump speed required to reach the specified height h, given the acceleration due to gravity g.

So the final part is to implement this formula in GML. There are a couple of important points to remember when doing this:
  • The value of y increases as you move down the screen. Therefore, our jump speed has to be negative.
  • Acceleration due to gravity should be the value you are adding to your player's vspeed each step.
  • Height will be the height in pixels you want the player to jump from his current position.
  • This equation is dependent on the value for gravity, so the room speed will not affect it. The player will always reach your desired height provided you use the correct values.
Example Code:
Code:
if(keyboard_check_pressed(vk_space))
{
    vspeed = -sqrt(2 * gravity * height); //Replace height with your desired height.
}
 
Last edited by a moderator:
J

Jordan Robinson

Guest
It seems like the game being a discrete simulation might be a confounding factor here. I guess that would depend on the level of accuracy needed. Have you looked into that?
Hi there,

If you use the built-in gravity and vspeed variables, then gravity will be applied in the same step as when you set the required jump speed, which will cause a small error resulting in a jump height slightly smaller than intended. This is because the speed calculated is the initial speed - the player has to move at that speed initially before we start deducting gravity.

The way to get around that is by using your own vertical speed variables. For example:
Code:
grav = 0.2;
jumpSpeed = -sqrt(2 * grav * 32);

ySpeed = 0;
Code:
ySpeed += grav; //Note we apply gravity before the vertical speed is set for jumping.

if(keyboard_check_pressed(vk_space))
{
    ySpeed = jumpSpeed;
}

//Collision code here.

The method I explained above will give the most accurate jump height., however, there is another error which, as far as I know, can't be avoided (although if anybody knows how to get around it please let me know!). The formula we are using to calculate the required initial speed works in real life because time is continuous, but in the game time moves in fixed chunks (steps). In most cases, it would generally work out that to reach a given height it won't be an exact number of steps. Since the game can't run in fractions of a step, it means the characters jump height won't be exactly right.

Hopefully, this clarifies?
 
R

Rukola

Guest
Not bad, Jordan! How would you suggest the formula if you want to find out how high a character will be at his peak?

edit: After fiddling I got this for finding out the peak your character jump:

Code:
v = √2gh
1.7 = √(2 * .1 * 15)
sqr(1.7) = 2 * .1 * 15
sqr(1.7) / 2 / .1 = 15
h = sqr(v) / 2 / g
 
Last edited by a moderator:
J

Jordan Robinson

Guest
Not bad, Jordan! How would you suggest the formula if you want to find out how high a character will be at his peak?

edit: After fiddling I got this for finding out the peak your character jump:

Code:
v = √2gh
1.7 = √(2 * .1 * 15)
sqr(1.7) = 2 * .1 * 15
sqr(1.7) / 2 / .1 = 15
h = sqr(v) / 2 / g
Yup that is right.
Just remember to use brackets to make sure the order of operations is correct. h = (v^2/2) / g
You could also write it as h = (0.5v^2) / g
 
W

Wake

Guest
The method I explained above will give the most accurate jump height., however, there is another error which, as far as I know, can't be avoided (although if anybody knows how to get around it please let me know!). The formula we are using to calculate the required initial speed works in real life because time is continuous, but in the game time moves in fixed chunks (steps). In most cases, it would generally work out that to reach a given height it won't be an exact number of steps. Since the game can't run in fractions of a step, it means the characters jump height won't be exactly right.
Only way I can think of is by having a height variable that records how high you are in each step (it should begin at 0 and only raise when you're jumping). Then, you could check at every step if the ySpeed puts you above the desired jump height and limit it using the min function.
 
J

Jordan Robinson

Guest
Only way I can think of is by having a height variable that records how high you are in each step (it should begin at 0 and only raise when you're jumping). Then, you could check at every step if the ySpeed puts you above the desired jump height and limit it using the min function.
That's an interesting idea, and I think it could probably work quite well.
 
C

Cheesebird

Guest
I do not agree that the formula you have given gives the most accurate jumping speed. As pointed out by flyingsaucerinvasion, your solution would indeed solve the problem in real life where physics are continuous, but GameMaker's built-in physics are discrete. "Very discrete", in fact, in the sense that a continuous solution will give relatively large errors. Unless you have adapted the use of continuous physics in your game, or you have very high room speed, your formula will give these errors.

I don't know how to do energy arguments in discrete systems, but I do know the equations of motion in those systems. If an object has a starting velocity of +v and is accelerated g by the gravity, its relative position after time t is given by
y(t) = 0.5gt^2 + (v+0.5g)t.
For comparison, in a continuous system the equation would have been y(t) = 0.5gt^2 + vt, and that equation can be used to derive your method. The corresponding formula derived with the above equation is slightly more elaborate. The speed v needed to jump a height of h would have to fit into the following equation:
(1/(2g^2) - 1/g)v^2 + 1/2(1/g - 1 - 1/g^2)v + (1/8 - g/4 - h) = 0.
It's just a quadratic equation, so it's easily solved. (To derive the equation, find the value T for which y reaches its maximum by solving y'(t) = 0. Then the equation y(T) = h gives the above equation.) I just posted a guide on the topic of discrete physics, with the theme of hitting a target with an arrow; among other things I include a derivation of the discrete equation of motion.

Here is an implementation of my method, when we take into account that GameMaker rooms has an "inverted" y-axis compared to regular coordinate systems:
Code:
/** get_speed_height(height, g)
  *
  * height: number of pixels to jump
  * g:      the acceleration the object is subjected to
  *
  * Returns the required speed to jump height pixels high
  * when subject to gravity.
  */

height = argument0;
g = argument1;

a = 1/(2*sqr(g)) - 1/g;
b = 0.5*(1/g - 1 - 1/sqr(g));
c = 1/8 - 0.25*g + height;

v = -(-b - sqrt(sqr(b) - 4*a*c))/(2*a);
return v;
 
J

Jordan Robinson

Guest
I do not agree that the formula you have given gives the most accurate jumping speed. As pointed out by flyingsaucerinvasion, your solution would indeed solve the problem in real life where physics are continuous, but GameMaker's built-in physics are discrete. "Very discrete", in fact, in the sense that a continuous solution will give relatively large errors. Unless you have adapted the use of continuous physics in your game, or you have very high room speed, your formula will give these errors.

I don't know how to do energy arguments in discrete systems, but I do know the equations of motion in those systems. If an object has a starting velocity of +v and is accelerated g by the gravity, its relative position after time t is given by
y(t) = 0.5gt^2 + (v+0.5g)t.
For comparison, in a continuous system the equation would have been y(t) = 0.5gt^2 + vt, and that equation can be used to derive your method. The corresponding formula derived with the above equation is slightly more elaborate. The speed v needed to jump a height of h would have to fit into the following equation:
(1/(2g^2) - 1/g)v^2 + 1/2(1/g - 1 - 1/g^2)v + (1/8 - g/4 - h) = 0.
It's just a quadratic equation, so it's easily solved. (To derive the equation, find the value T for which y reaches its maximum by solving y'(t) = 0. Then the equation y(T) = h gives the above equation.) I just posted a guide on the topic of discrete physics, with the theme of hitting a target with an arrow; among other things I include a derivation of the discrete equation of motion.

Here is an implementation of my method, when we take into account that GameMaker rooms has an "inverted" y-axis compared to regular coordinate systems:
Code:
/** get_speed_height(height, g)
  *
  * height: number of pixels to jump
  * g:      the acceleration the object is subjected to
  *
  * Returns the required speed to jump height pixels high
  * when subject to gravity.
  */

height = argument0;
g = argument1;

a = 1/(2*sqr(g)) - 1/g;
b = 0.5*(1/g - 1 - 1/sqr(g));
c = 1/8 - 0.25*g + height;

v = -(-b - sqrt(sqr(b) - 4*a*c))/(2*a);
return v;
Ah now this is an interesting idea. I had been looking at more simple methods and hadn't considered using a quadratic equation. However, I think if you put this into practice you will still get similar errors to what you'd have with the original method of the tutorial.
 
C

Cheesebird

Guest
Ah now this is an interesting idea. I had been looking at more simple methods and hadn't considered using a quadratic equation. However, I think if you put this into practice you will still get similar errors to what you'd have with the original method of the tutorial.
Well, if you're referring to the fact that the object will not at any actual step hit the target position, but rather at a hypothetical "in the middle"-step, then you're correct. But that can't really be helped if you both want to use GameMaker physics and jump to a specific height. However, the result will be more accurate than when using the continuous model. In fact, the only error would be due to cumulative round-offs. I made a short program to illustrate the difference: host-a.net/u/Cheesebird/example34.zip. A screenshot is shown below.

 
Last edited by a moderator:
Top