Calculating jump speed

You can talk about almost anything that you want to on this board.

Moderator: Moderators

User avatar
DRW
Posts: 2070
Joined: Sat Sep 07, 2013 2:59 pm

Calculating jump speed

Post by DRW »

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?
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
User avatar
tokumaru
Posts: 12106
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Re: Calculating jump speed

Post by tokumaru »

Your questions are more suitable for a school exam than for a game... :lol:

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.
User avatar
dougeff
Posts: 2876
Joined: Fri May 08, 2015 7:17 pm
Location: DIGDUG
Contact:

Re: Calculating jump speed

Post by dougeff »

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
User avatar
Sogona
Posts: 186
Joined: Thu Jul 23, 2015 7:54 pm
Location: USA
Contact:

Re: Calculating jump speed

Post by Sogona »

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 = v0t + 1/2 a t2?

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
tepples
Posts: 22345
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Re: Calculating jump speed

Post by tepples »

Triple ninja'd. But whatever:
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.)
I'll get the integral calculus* out of the way first:

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.
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?
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.

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.
User avatar
rainwarrior
Posts: 8062
Joined: Sun Jan 22, 2012 12:03 pm
Location: Canada
Contact:

Re: Calculating jump speed

Post by rainwarrior »

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.
User avatar
DRW
Posts: 2070
Joined: Sat Sep 07, 2013 2:59 pm

Re: Calculating jump speed

Post by DRW »

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?

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);
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?
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
User avatar
tokumaru
Posts: 12106
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Re: Calculating jump speed

Post by tokumaru »

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.
User avatar
dougeff
Posts: 2876
Joined: Fri May 08, 2015 7:17 pm
Location: DIGDUG
Contact:

Re: Calculating jump speed

Post by dougeff »

I don't know if this is helpful, but...

http://hamaluik.com/posts/super-mario-world-physics/
nesdoug.com -- blog/tutorial on programming for the NES
User avatar
DRW
Posts: 2070
Joined: Sat Sep 07, 2013 2:59 pm

Re: Calculating jump speed

Post by DRW »

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.
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.)

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
User avatar
GradualGames
Posts: 1106
Joined: Sun Nov 09, 2008 9:18 pm
Location: Pennsylvania, USA
Contact:

Re: Calculating jump speed

Post by GradualGames »

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.

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

*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.
User avatar
DRW
Posts: 2070
Joined: Sat Sep 07, 2013 2:59 pm

Re: Calculating jump speed

Post by DRW »

GradualGames wrote:The below is an example of what you need for jumping
If this was directed specifically towards me and not a general code snipped:
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
User avatar
GradualGames
Posts: 1106
Joined: Sun Nov 09, 2008 9:18 pm
Location: Pennsylvania, USA
Contact:

Re: Calculating jump speed

Post by GradualGames »

DRW wrote:
GradualGames wrote:The below is an example of what you need for jumping
If this was directed specifically towards me and not a general code snipped:
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.
What I posted is a 6502 implementation of what tokumaru described...unless I'm completely missing something above. :?
User avatar
DRW
Posts: 2070
Joined: Sat Sep 07, 2013 2:59 pm

Re: Calculating jump speed

Post by DRW »

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
User avatar
GradualGames
Posts: 1106
Joined: Sun Nov 09, 2008 9:18 pm
Location: Pennsylvania, USA
Contact:

Re: Calculating jump speed

Post by GradualGames »

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.

Post Reply