Calculating jump speed
Moderator: Moderators
Calculating jump speed
In my game, I'm at the point where I have to implement a good jumping algorithm So, I thought that I base my algorithm on real physics. And that's why I need to know:
If a person jumps a specific height, what is the mathematical formula to calculate how long the jump will take until the person lands on the ground again? (Assuming Earth's gravity.)
Then, when we know how long the jump of a specific height takes, how do I calculate in what height the person will be at any given time of the jump?
I'm pretty sure there is a formula for this. From this formula, I will calculate at which frame of the jump the player will have which y position and save these values into a lookup table. But first of all I need to know the general mathematical formula itself.
Does anybody know where I can find this?
If a person jumps a specific height, what is the mathematical formula to calculate how long the jump will take until the person lands on the ground again? (Assuming Earth's gravity.)
Then, when we know how long the jump of a specific height takes, how do I calculate in what height the person will be at any given time of the jump?
I'm pretty sure there is a formula for this. From this formula, I will calculate at which frame of the jump the player will have which y position and save these values into a lookup table. But first of all I need to know the general mathematical formula itself.
Does anybody know where I can find this?
Available now: My game "City Trouble".
Website: https://megacatstudios.com/products/city-trouble
Trailer: https://youtu.be/IYXpP59qSxA
Gameplay: https://youtu.be/Eee0yurkIW4
German Retro Gamer article: http://i67.tinypic.com/345o108.jpg
Website: https://megacatstudios.com/products/city-trouble
Trailer: https://youtu.be/IYXpP59qSxA
Gameplay: https://youtu.be/Eee0yurkIW4
German Retro Gamer article: http://i67.tinypic.com/345o108.jpg
Re: Calculating jump speed
Your questions are more suitable for a school exam than for a game... 
Since a game's state is modified progressively, one step/frame at a time, you don't need to know "in what height the person will be at any given time", you just update their position for the next frame. Similarly, you don't need to know how long the jump will take, because you don't need to manually hardcode that amount of time into NES frames.
What games typically do, is give the object a large negative Y velocity. Say, -6 pixels per frame. Then you need gravity to prevent the object from moving up indefinitely. Gravity should have a much smaller value, maybe around 0.3 pixels per frame. Then every frame you add the object's Y velocity to its Y coordinate, and also add the gravity to the Y velocity, so it will slowly move towards 0, at which point the object will at the peak of its jump. Continue to add gravity to the speed and it will become positive, effectively pushing the object down.
You can tweak the initial velocity of the jump and the amount of gravity until the jump matches your desired height and duration. I remember someone saying they didn't even add gravity during the first steps of the jump, which was necessary to match the effect they wanted.
This might not be the most physically accurate way to describe jumps, but nearly every game with decent physics you ever played does it like this, and you certainly won't get anything much more accurate than this out of an 8-bit CPU running at 1.79MHz.
Since a game's state is modified progressively, one step/frame at a time, you don't need to know "in what height the person will be at any given time", you just update their position for the next frame. Similarly, you don't need to know how long the jump will take, because you don't need to manually hardcode that amount of time into NES frames.
What games typically do, is give the object a large negative Y velocity. Say, -6 pixels per frame. Then you need gravity to prevent the object from moving up indefinitely. Gravity should have a much smaller value, maybe around 0.3 pixels per frame. Then every frame you add the object's Y velocity to its Y coordinate, and also add the gravity to the Y velocity, so it will slowly move towards 0, at which point the object will at the peak of its jump. Continue to add gravity to the speed and it will become positive, effectively pushing the object down.
You can tweak the initial velocity of the jump and the amount of gravity until the jump matches your desired height and duration. I remember someone saying they didn't even add gravity during the first steps of the jump, which was necessary to match the effect they wanted.
This might not be the most physically accurate way to describe jumps, but nearly every game with decent physics you ever played does it like this, and you certainly won't get anything much more accurate than this out of an 8-bit CPU running at 1.79MHz.
Last edited by tokumaru on Thu Jan 21, 2016 5:06 pm, edited 2 times in total.
Re: Calculating jump speed
Real physics will look wrong in a game. In real life, you can only jump about half your height, and be in the air about a second. That's a vertical movement of about 1/2 of a pixel per frame to a max of 16 pixels of vertical movement. That would be very dull gameplay.
Last edited by dougeff on Thu Jan 21, 2016 5:06 pm, edited 2 times in total.
nesdoug.com -- blog/tutorial on programming for the NES
Re: Calculating jump speed
d = v0t + 1/2 a t2?DRW wrote:If a person jumps a specific height, what is the mathematical formula to calculate how long the jump will take until the person lands on the ground again? (Assuming Earth's gravity.)
d being height, v0 being at what speed you initially jump, and a being gravity, or -9.8m/s2
I could be wrong, but I believe solving for t would give you the time.
Of course, I have no idea how you'd translate this to the NES
Re: Calculating jump speed
Triple ninja'd. But whatever:
Acceleration: d^2y/dt^2 = g
Velocity: dy/dt = g*t
Displacement: y = g*t^2/2
where y is height, g is the acceleration due to gravity, and t is time since the peak of the jump. Assuming SI units and Earth conditions, y is in meters, t is in seconds, and g = 9.80665 m/s^2.
Given y, you want to find 2*t, as half the time is spent rising and the other half falling. From here on, everything is algebra.
y = g*t^2/2
2*y = g*t^2
2*y/g = t^2
sqrt(2*y/g) = t
2*sqrt(2*y/g) = 2*t
Now that you have t, the time from jumping from peak or the time from peak to landing, the magnitude of the vertical component of velocity at the start and end of the jump is g*t.
If you can provide a particular height or hang time, a particular scale (in units such as pixels per meter), and a particular frame rate (in frames per second), I can demonstrate how to translate this into 6502 code.
* Integral calculus is the area between the gum line and the tartar line. Differential calculus is the rate of growth of tartar over time.
I'll get the integral calculus* out of the way first:DRW wrote:In my game, I'm at the point where I have to implement a good jumping algorithm So, I thought that I base my algorithm on real physics. And that's why I need to know:
If a person jumps a specific height, what is the mathematical formula to calculate how long the jump will take until the person lands on the ground again? (Assuming Earth's gravity.)
Acceleration: d^2y/dt^2 = g
Velocity: dy/dt = g*t
Displacement: y = g*t^2/2
where y is height, g is the acceleration due to gravity, and t is time since the peak of the jump. Assuming SI units and Earth conditions, y is in meters, t is in seconds, and g = 9.80665 m/s^2.
Given y, you want to find 2*t, as half the time is spent rising and the other half falling. From here on, everything is algebra.
y = g*t^2/2
2*y = g*t^2
2*y/g = t^2
sqrt(2*y/g) = t
2*sqrt(2*y/g) = 2*t
Now that you have t, the time from jumping from peak or the time from peak to landing, the magnitude of the vertical component of velocity at the start and end of the jump is g*t.
Usually it's done with Euler integration, which is how mathematicians describe the process that tokumaru described above. Set the initial velocity at the start of the jump, then add gravity (converted to subpixels per frame squared) to the object's velocity every frame, and add the object's velocity to its displacement every frame.Then, when we know how long the jump of a specific height takes, how do I calculate in what height the person will be at any given time of the jump?
If you can provide a particular height or hang time, a particular scale (in units such as pixels per meter), and a particular frame rate (in frames per second), I can demonstrate how to translate this into 6502 code.
* Integral calculus is the area between the gum line and the tartar line. Differential calculus is the rate of growth of tartar over time.
- rainwarrior
- Posts: 8062
- Joined: Sun Jan 22, 2012 12:03 pm
- Location: Canada
- Contact:
Re: Calculating jump speed
Also note that Euler integration is an approximation, meaning it accumulates errors over the course of the jump, so the continuous calculus formula is really only a (good) estimate of what your game is going to do.
What I suggest is to write a small program, in python or otherwise, that just runs the jump/gravity simulation for as many frames as it takes to land, and collects statistics: frames in the air, highest point reached, maximum horizontal span, etc.
Pick some starting constants using calculus, and then put them into your little simulator, and tweak them until you get the jump you want coming out of it.
What I suggest is to write a small program, in python or otherwise, that just runs the jump/gravity simulation for as many frames as it takes to land, and collects statistics: frames in the air, highest point reached, maximum horizontal span, etc.
Pick some starting constants using calculus, and then put them into your little simulator, and tweak them until you get the jump you want coming out of it.
Re: Calculating jump speed
Looks like the mathematical stuff is more complicated than I thought. So, I guess I'll go with tokumaru's suggestion.
However, since this method uses floating point calculations, I guess I will pre-calculate the heights of each frame of the jump and put these values into a lookup array, so that the jumping routine just needs to read from that array to see how many pixels the character needs to move up or down in each frame.
How do real games do this calculation? Do they use a lookup array as well, with the array being long enough so that a jump starting from the highest possible position and going down to the lowest bottom can still be looked up?
Or do they actually calculate the current value immediately? If yes, wouldn't this be slow since it uses floating point calculations?
To check if I got the idea right, is this general code to calculate these values correct?
And another question: In how far does the gravity value relate to the actual real gravity? Let's say I want to try out the real Earth's gravity of 9.80665 m/s². How do I convert this value into the gravity constant of the program?
However, since this method uses floating point calculations, I guess I will pre-calculate the heights of each frame of the jump and put these values into a lookup array, so that the jumping routine just needs to read from that array to see how many pixels the character needs to move up or down in each frame.
How do real games do this calculation? Do they use a lookup array as well, with the array being long enough so that a jump starting from the highest possible position and going down to the lowest bottom can still be looked up?
Or do they actually calculate the current value immediately? If yes, wouldn't this be slow since it uses floating point calculations?
To check if I got the idea right, is this general code to calculate these values correct?
Code: Select all
const double gravity = 0.3;
const int startY = 0;
double velocity = -6;
double y = startY;
int yInPixels = y;
int previousYInPixels;
cout << "Starting Y: " << yInPixels << "\n\n";
do
{
previousYInPixels = yInPixels;
y += velocity;
yInPixels = y;
cout << "Absolute Y: " << yInPixels << "\n"
<< "Offset Y: " << yInPixels - previousYInPixels << "\n\n";
velocity += gravity;
}
while (yInPixels < startY);Available now: My game "City Trouble".
Website: https://megacatstudios.com/products/city-trouble
Trailer: https://youtu.be/IYXpP59qSxA
Gameplay: https://youtu.be/Eee0yurkIW4
German Retro Gamer article: http://i67.tinypic.com/345o108.jpg
Website: https://megacatstudios.com/products/city-trouble
Trailer: https://youtu.be/IYXpP59qSxA
Gameplay: https://youtu.be/Eee0yurkIW4
German Retro Gamer article: http://i67.tinypic.com/345o108.jpg
Re: Calculating jump speed
In games, floating-point math is normally replaced by fixed-point math, which is fast enough for fractional movement even in slow 8-bit CPUs. The basic idea is that you use an additional byte to represent the fractional part of positions, velocities, etc. and when the fractional part overflows or underflows, this is propagated to the integer part of the numbers.
Re: Calculating jump speed
nesdoug.com -- blog/tutorial on programming for the NES
Re: Calculating jump speed
Alright, I wrote another little test program to check these values. (I didn't optimize for the NES, like using global variables instead of function parameters etc.)tokumaru wrote:In games, floating-point math is normally replaced by fixed-point math, which is fast enough for fractional movement even in slow 8-bit CPUs. The basic idea is that you use an additional byte to represent the fractional part of positions, velocities, etc. and when the fractional part overflows or underflows, this is propagated to the integer part of the numbers.
Can you please tell me whether everything is correct according to what you described me?
Code: Select all
#include <iostream>
using namespace std;
const int Gravity = 30;
const int InitialVelocity = -6;
void InitializeJump(int &velocityBase, int &velocityPoint);
void NextJumpFrame(int &y, int &velocityBase, int &velocityPoint);
int main()
{
int velocityBase;
int velocityPoint;
int lastVelocity;
int y = 0;
int maxHeight = y;
InitializeJump(velocityBase, velocityPoint);
cout << "Y: " << y << "\n";
do
{
lastVelocity = velocityBase;
NextJumpFrame(y, velocityBase, velocityPoint);
cout << "Y: " << y << " (Velocity: " << lastVelocity << ")\n";
if (y < maxHeight)
maxHeight = y;
}
while (y < 10000);
cout << "\n";
cout << "Gravity: " << Gravity << "\n";
cout << "Initial velocity: " << InitialVelocity << "\n";
cout << "Max height: " << maxHeight;
cin.get();
}
void InitializeJump(int &velocityBase, int &velocityPoint)
{
velocityBase = InitialVelocity;
velocityPoint = 0;
}
void NextJumpFrame(int &y, int &velocityBase, int &velocityPoint)
{
y += velocityBase;
velocityPoint += Gravity;
if (velocityPoint >= 100)
{
++velocityBase;
velocityPoint -= 100;
}
}Available now: My game "City Trouble".
Website: https://megacatstudios.com/products/city-trouble
Trailer: https://youtu.be/IYXpP59qSxA
Gameplay: https://youtu.be/Eee0yurkIW4
German Retro Gamer article: http://i67.tinypic.com/345o108.jpg
Website: https://megacatstudios.com/products/city-trouble
Trailer: https://youtu.be/IYXpP59qSxA
Gameplay: https://youtu.be/Eee0yurkIW4
German Retro Gamer article: http://i67.tinypic.com/345o108.jpg
- GradualGames
- Posts: 1106
- Joined: Sun Nov 09, 2008 9:18 pm
- Location: Pennsylvania, USA
- Contact:
Re: Calculating jump speed
The below is an example of what you need for jumping, with details such as collision and ejection left out. If anyone notices anything that can be improved in the below, I'd be eager to learn it. *edit* I'll try to read your C code and comment, but I posted this asm example partially for my own practice in explaining things to others, so I apologize in advance if this is not immediately helpful to you for your C implementation. Conceptually though you could translate this to C pretty easily.
*edit* I forgot to mention, the two highest bytes of the 3 byte y coordinate would be your 16 bit world coordinate. The lowest byte is sub-pixel precision.
Code: Select all
;Note I picked all these constants arbitrarily, I wouldn't know without running the code what the jump would look like. I would then tweak these values til I get the arc that I want.
ACCELERATION = 100
START_JUMP = -50 ;on ca65 you would need to use feature .force_range for it to be happy with negative values used as bytes
;zp variables
y_coordinate: .res 3
y_velocity: .res 2
sign_extend_byte: .res 1
;when you detect A button and the character is standing on something
lda #<START_JUMP
sta y_velocity
lda #>START_JUMP
sta y_velocity+1
....
;on each frame. You would always do this--jumping just sets y velocity to an initial value, landing on a tile (not included in example) would set y velocity to 0. Ejection would keep it at 0 if you're standing on a tile.
;Add 16 bit y velocity to 24 bit y coordinate with sign extension. 16 bit world coordinates, 8 bit sub pixel precision
lda #0
sta sign_extend_byte
lda y_coordinate+3
bpl :+
lda #$ff
sta sign_extend_byte
:
clc
lda y_coordinate
adc y_velocity
sta y_coordinate
lda y_coordinate+1
adc y_velocity+1
sta y_coordinate+1
lda y_coordinate+2
adc sign_extend_byte
sta y_coordinate+2
;Now add acceleration to y velocity
clc
lda y_velocity
adc #<ACCELERATION
sta y_velocity
lda y_velocity+1
adc #>ACCELERATION
sta y_velocity+1
Re: Calculating jump speed
If this was directed specifically towards me and not a general code snipped:GradualGames wrote:The below is an example of what you need for jumping
Thanks, but I already know how to implement movement functions, i.e. how to react to user input and level environment. In fact, I already have a fully working jumping function in my game. It's just that the Y value is calculated in a pretty basic way.
I just wanted to know whether the calculation in my above sample code is correct in the way that tokumaru described.
The actual NES implementation won't be a problem. I just need to know if the general algorithm for calculating the Y value is correct so far.
Last edited by DRW on Fri Jan 22, 2016 7:57 am, edited 1 time in total.
Available now: My game "City Trouble".
Website: https://megacatstudios.com/products/city-trouble
Trailer: https://youtu.be/IYXpP59qSxA
Gameplay: https://youtu.be/Eee0yurkIW4
German Retro Gamer article: http://i67.tinypic.com/345o108.jpg
Website: https://megacatstudios.com/products/city-trouble
Trailer: https://youtu.be/IYXpP59qSxA
Gameplay: https://youtu.be/Eee0yurkIW4
German Retro Gamer article: http://i67.tinypic.com/345o108.jpg
- GradualGames
- Posts: 1106
- Joined: Sun Nov 09, 2008 9:18 pm
- Location: Pennsylvania, USA
- Contact:
Re: Calculating jump speed
What I posted is a 6502 implementation of what tokumaru described...unless I'm completely missing something above.DRW wrote:If this was directed specifically towards me and not a general code snipped:GradualGames wrote:The below is an example of what you need for jumping
Thanks, but I already know how to implement movement functions. I just wanted to know whether the calculation in my sample code is correct in the way that tokumaru described.
The actual NES implementation won't be a problem. I just need to know if the general algorithm for calculating the Y value is correct so far.
Re: Calculating jump speed
O.k., but all I wanted to know is: The general C++ code that I wrote above, is this one correct? This is not about 6502 yet. I just need to know whether the code that I already wrote to demonstrate the jumping algorithm is correct the way it is implemented or if you find an error.
Available now: My game "City Trouble".
Website: https://megacatstudios.com/products/city-trouble
Trailer: https://youtu.be/IYXpP59qSxA
Gameplay: https://youtu.be/Eee0yurkIW4
German Retro Gamer article: http://i67.tinypic.com/345o108.jpg
Website: https://megacatstudios.com/products/city-trouble
Trailer: https://youtu.be/IYXpP59qSxA
Gameplay: https://youtu.be/Eee0yurkIW4
German Retro Gamer article: http://i67.tinypic.com/345o108.jpg
- GradualGames
- Posts: 1106
- Joined: Sun Nov 09, 2008 9:18 pm
- Location: Pennsylvania, USA
- Contact:
Re: Calculating jump speed
Here's how I'd do it in pseudo C. Note as above I picked arbitrary constants. If I were building a real game, I'd tweak these until I got the arc I wanted.
Code: Select all
#define START_JUMP -50
#define ACCELERATION 100
long y_coordinate; //assuming this means 4 bytes on the NES. We'll just care about the lowest 3 bytes, unless you have an obscenely huge world!
int y_velocity;
....
//when you hit A button and you know you're standing on something.
y_velocity = START_JUMP;
//on each frame
y_coordinate += y_velocity;
y_velocity += ACCELERATION;
//y_coordinate would be your 16 bit world coordinate and 8 bit sub pixel precision. So you would have to process it differently in C to get the world Y coordinate...
int actual_y_coordinate = y_coordnate >> 8; // there would be a better way of just converting bytes 1 and 2 (counting from 0) into an int with pointer math, but I'm unsure of how this would work in C on the NES.
//assume later on you'd do ejection and reset velocity to 0 if you're standing on something, etc.