Archived

This topic is now archived and is closed to further replies.

Neen10do

erratic jumping

Recommended Posts

i finally got my jumping for my dude to work... kinda sorta. when the player jumps, it sets the velocity at a constant rate, ie 80. but each time the player jumps, it goes to different heights. considering the velocity always starts the same, and there are no external factors, why wouldn''t it jump the same every time? here is some code input function
  
void cMainGame::CheckInput()
{
	//BUTTON PRESSES///////////

	static bool Z;
	///////////////////////////

 
        //this just keeps the player from going through the floor, for now. primiative collision.

	if(Player.mySprite.myY >= 396)
	{
		Player.myPhysics.vVelocity = 0;
		Player.mySprite.myY = 396;
		Player.myPhysics.jumping = false;
	}

	switch(GameMode)
	{
		//The Game is Running

		case MainGame:
			//Jump

			if(dk.KeyPressed(DIK_Z))
			{
				if(Z == false)
					if(Player.myPhysics.jumping == false)
					{
						Player.Jump(80);
					}
				Z = true;
			}
			else
			{
				Z = false;
			}

		break;
		default: break;
	};
  
here is the jump function
  
//Makes the object jump based on physics

void cObject::Jump(int velocity)
{
	myPhysics.jumping = true;
	myPhysics.vVelocity = velocity;
}
//////////////////////////////////////////

  
and here is the physics function that is applied to the object every frame. TimeDelta is the difference between frames, in milliseconds.
  
//APPLIES PHYSICS//////////////

void cPhysics::ApplyPhysics(float &Xpos, float &Ypos, DWORD TimeDelta)
{
	
	//if jumping

	if(jumping)
	{
		//Terminal velocity

		if(vVelocity > -100)
		{
			//Applies Gravity

			vVelocity = vVelocity + (int)GRAVITY * TimeDelta;
		}

		//Moves object

		Ypos = Ypos - (vVelocity / 10);
	}
}	
///////////////////////////////

  
can you guys find any reason my jumping would be erratic? ---------------------- i code therefore i am. Aero DX - Coming to a bored Monitor near you!

Share this post


Link to post
Share on other sites
Not sure, but I think it''s because each time segment, you adjust the position by the final velocity, not the average velocity. Try storing the initial velocity in a temp variable before changing it, then use (velocity + initialVelocity) / 2 as the average.


How appropriate. You fight like a cow.

Share this post


Link to post
Share on other sites
As well, if you're using time based scaling, you should be using floating point co-ordinates and values for everything or else you'll run into horrendous round-off errors. This might already be the case for this example.

Your assumption about "external factors" is inccorect in this case. The frame time is external, and without adequate precision, the error introduced by rounding the velocities and co-ordinates at EVERY FRAME will really throw off calculations.

Start by using floating points for anything time-scaled, then see if that fixes it. If not, come back here and post the new (modified) problem and code.

[edited by - AndyTX on May 5, 2003 5:29:04 PM]

Share this post


Link to post
Share on other sites
ok i took both of your suggestions, but i still get erratic heights. here is the code:

INPUT

  
void cMainGame::CheckInput()
{
//BUTTON PRESSES///////////

static bool Z;
///////////////////////////


if(Player.mySprite.myY >= 396)
{
Player.myPhysics.vVelocity = 0;
Player.mySprite.myY = 396;
Player.myPhysics.jumping = false;
}

switch(GameMode)
{
//The Game is Running

case MainGame:
//Jump

if(dk.KeyPressed(DIK_Z))
{
if(Z == false)
if(Player.myPhysics.jumping == false)
{
Player.Jump(30);
}
Z = true;
}
else
{
Z = false;
}

break;
default: break;
};

JUMP

  
//Makes the object jump based on physics

void cObject::Jump(float velocity)
{
myPhysics.jumping = true;
myPhysics.vVelocity = velocity;
myPhysics.ivVelocity = velocity;
}
//////////////////////////////////////////



the physics function

  
//APPLIES PHYSICS//////////////

void cPhysics::ApplyPhysics(float &Xpos, float &Ypos, DWORD TimeDelta)
{

//if jumping

if(jumping)
{
//Terminal velocity

if(vVelocity > -100)
{
//Applies Gravity

vVelocity = vVelocity + GRAVITY * TimeDelta;
}

//Moves object

Ypos = Ypos - (ivVelocity + vVelocity / 2) / 10;
}
}


PS: is it wrong to divide by 10? it seems this is the only way i can slow things down.


}
///////////////////////////////////
[/source]


----------------------
i code therefore i am.

Aero DX - Coming to a bored Monitor near you!

Share this post


Link to post
Share on other sites
"ivVelocity + vVelocity / 2"


Remember that division is higher precedence than addition. Stick some parentheses around that addition, mister.


How appropriate. You fight like a cow.

Share this post


Link to post
Share on other sites

//if jumping
if(jumping)
{
//Terminal velocity
if(vVelocity > -40)
{
//Applies Gravity
vVelocity = vVelocity + GRAVITY * TimeDelta;
}

//Moves object
Ypos = Ypos - TimeDelta * ((ivVelocity + vVelocity) / 2);
}

i did both of your suggesstions, still no dice. sometimes he jumps and its really choppy, and some times he never jumps at all. he is all i am blitting to the screen, so time delta is small (0-2). anyone? this is really frustration.

----------------------
i code therefore i am.

Aero DX - Coming to a bored Monitor near you!

Share this post


Link to post
Share on other sites
Hmm why not change position directly? s = ut + 1/2*a*t^2

or

vectorPos = vectorPos * timeDelta + 0.5 * g * SQR(timeDelta);

Share this post


Link to post
Share on other sites
here is my code under Kyo''s suggestion:

//APPLIES PHYSICS//////////////
void cPhysics::ApplyPhysics(float &Xpos, float &Ypos, DWORD TimeDelta)
{

//if jumping
if(jumping)
{
//Moves object
Ypos = Ypos * TimeDelta + (float).5 * GRAVITY * (TimeDelta * TimeDelta);

//Terminal velocity
if(vVelocity > -120)
{
vVelocity = -120;
}
}
}
///////////////////////////////

the only problem with this is it has no velocity in it!! i dont know what s = ut + 1/2*a*t^2 is but i implemented the other one you gave me and it just sticks the dude on the cealing forever.

is there anyone in the world who has gotten this to work!?!?! some sample code, your game, whatever it takes!! this should not be that hard!!!!


----------------------
i code therefore i am.

Aero DX - Coming to a bored Monitor near you!

Share this post


Link to post
Share on other sites
What fps are you getting, if the time difference is very low, it could mean DeltaTime is 0 almost and cause problems. If that is the case, then slow down your loop, using Sleep(1) or something. Just don''t forget to remove it later

Also don''t use s = ut + 0.5at^2, that doesn''t work for deltaTime. Your original code without a doubt is wrong, but with the time correction for the position being moved by the velocity, it should be ok.

Finally I can''t see what is happening with that ivvelocity. Is that supposed the be the velocity a frame ago, or the initial velocity. Either way I don''t think it''s needed.

Share this post


Link to post
Share on other sites
"You fight like a cow..."....... I love MI.

-

If it was up to me, I would have gravity constantly being applied to the object. When the object jumps, I would apply the vector of the jump to the object (if the object is on the ground of course) and that is all. That way, the object would go up and then slowing come back down due to gravity. Since the vector's magnitude of the jump would be a constant (usually unless you wanted the player to jump at different heights (maybe based on their "jumping skill ability")) they would always jump the same height.

[EDIT] Please note that I haven't done a platformer yet.


- Rob Loach
Current Project: Go Through Object-Oriented Programming in C++ by Robert Lafore

"Do or do not. There is no try."
- Yoda


[edited by - Rob Loach on May 6, 2003 12:15:37 PM]

Share this post


Link to post
Share on other sites
quote:
Original post by Neen10do
here is my code under Kyo''s suggestion:

//APPLIES PHYSICS//////////////
void cPhysics::ApplyPhysics(float &Xpos, float &Ypos, DWORD TimeDelta)
{

//if jumping
if(jumping)
{
//Moves object
Ypos = Ypos * TimeDelta + (float).5 * GRAVITY * (TimeDelta * TimeDelta);

//Terminal velocity
if(vVelocity > -120)
{
vVelocity = -120;
}
}
}
///////////////////////////////

the only problem with this is it has no velocity in it!! i dont know what s = ut + 1/2*a*t^2 is but i implemented the other one you gave me and it just sticks the dude on the cealing forever.

is there anyone in the world who has gotten this to work!?!?! some sample code, your game, whatever it takes!! this should not be that hard!!!!


----------------------
i code therefore i am.

Aero DX - Coming to a bored Monitor near you!


Sorry I wasn''t thinking u isn''t yPos it''s the initial velocity. These equations come from newton''s laws:

a = [0, 9.8]

differentiate to get velocity

v = [u1, u2 + 9.8t]

differentiate to get displacement

s = [u1t + c1, u2t + 0.5*9.8*t^2 + c2]


That''s how I implemented my jump physics. u1 is your initial x velocity, u2 is your initial y velocity. These equations take 0,0 to be the bottom left corner though so you might have to modify the signs if your 0,0 is top left. c2 is your initial height.

You can use velocity equation to check when he''s falling back down , if velocity is negative he''s falling back down and you can do check for collisions downwards, if velocity is positive he''s moving updwards and you can check to see if he hit a ceiling.

you can make him jump faster and higher by modifying his initial velocity u.


Share this post


Link to post
Share on other sites