Public Group

# Jumping Physics

This topic is 2166 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

Hello, I am working on some physics in my game and more specifically jumping. When I it the jump button I set a bool m_bJumped to true so that in the update function I can alter the Y velocity:

if(event.key.code == sf::Keyboard::Z && m_sfVelocity.y == 0) m_bJumped = true;


Then in the update function:

...

if(m_bJumped == true) {

m_sfVelocity.y = -300 * deltaT.asSeconds();
m_bJumped = false;
}

...

m_sfVelocity.y += 5 * deltaT.asSeconds();

...

if(checkCollision(std::floor(m_sfEntity.getPosition().x / 32), std::floor((m_sfEntity.getPosition().y +
m_sfSize.y + m_sfVelocity.y) / 32), lvl) == true)
m_sfVelocity.y = 0;



The check collision function checks to see if the tile below the player is solid and if so to set the Y velocity to 0 so it will stop moving down. The jumping works but is is very random. Some times it jumps 7 tiles and some times it jumps 9. One time it jumped all 20 tiles. How do I make the jumping more stable? Thanks.

EDIT: The deltaT is a sf::Time object that is passed in every frame.

Edited by Crusable

##### Share on other sites

You don't need to multiply -300 by deltaT.asSeconds().  You want the jump velocity to be a constant (-300) and then use delta time to update it (as you are).

You are seeing the effect of slightly different frame times which is making the velocity start at different values.

##### Share on other sites

I would do it like this

int AmountTimeGoingUpOnJump= 250;//Miliseconds THIS WILL VARY ON YOUR DECISION
bool isJumping = false;//If this is true, increase his velocity until he meats max treshold, else decrease it until he meats max treshold or meats a solid surface
int unitPosX, unitPosY;
SomeTimeHoldingClass StartJumpTime;//Time when the jump started
SomeTimeHoldingClass GetCurrentTime();//returns current time

//Now the user presses "Z" call startJump.
StartJump(){StartJumpTime = GetCurrentTime();}
LoopJump(){if(CurrentTime - StartJumpTime > AmountTimeGoingUpOnJump){isJumping = false;/*No velocity increase, also somwhere check if nothing bellow him to decrease velocity*/}
else {isJumping = true, /*make his velocity increase*/}}


if(m_bJumped == true) {

m_sfVelocity.y = -300 * deltaT.asSeconds();
m_bJumped = false;
}

Also as it stands m_bJumped=false sould be set when the "unit" meats ground so you prevent air jumps

m_sfVelocity.y += 5 * deltaT.asSeconds();

Here you sould check for max velocity if you want.

I mean the more you jump the faster you go?

You go half way speeding(Going up only X amount of time) then you still going up but slowing down, until the velocity goes from + to - and then you start to decline

Edited by BaneTrapper

##### Share on other sites

You don't need to multiply -300 by deltaT.asSeconds().  You want the jump velocity to be a constant (-300) and then use delta time to update it (as you are).

You are seeing the effect of slightly different frame times which is making the velocity start at different values.

I changed it to this and the jump is a lot more stable.

I would do it like this

int AmountTimeGoingUpOnJump= 250;//Miliseconds THIS WILL VARY ON YOUR DECISION
bool isJumping = false;//If this is true, increase his velocity until he meats max treshold, else decrease it until he meats max treshold or meats a solid surface
int unitPosX, unitPosY;
SomeTimeHoldingClass StartJumpTime;//Time when the jump started
SomeTimeHoldingClass GetCurrentTime();//returns current time

//Now the user presses "Z" call startJump.
StartJump(){StartJumpTime = GetCurrentTime();}
LoopJump(){if(CurrentTime - StartJumpTime > AmountTimeGoingUpOnJump){isJumping = false;/*No velocity increase, also somwhere check if nothing bellow him to decrease velocity*/}
else {isJumping = true, /*make his velocity increase*/}}

if(m_bJumped == true) {

m_sfVelocity.y = -300 * deltaT.asSeconds();
m_bJumped = false;
}

Also as it stands m_bJumped=false sould be set when the "unit" meats ground so you prevent air jumps

m_sfVelocity.y += 5 * deltaT.asSeconds();

Here you sould check for max velocity if you want.

I mean the more you jump the faster you go?

You go half way speeding(Going up only X amount of time) then you still going up but slowing down, until the velocity goes from + to - and then you start to decline

This would work and thank you for the suggestion, but I wanted the entity to act like a projectile. Thanks for the help.

##### Share on other sites

You almost have it just right I believe.  However, I would re-think the logic behind allowing the player to jump.  Currently, you allow them to jump if their y velocity is 0.

What happens when the player reaches his jumping apex , just before he starts to fall?  Well, the velocity might be 0. and he'd have the ability to jump again right there.

My suggestion would be to allow a player to jump when he's touching the ground.  And, why not go ahead and set his y velocity when you set the jump variable to true? Something like this:

void TPlayer::Update(float deltaSeconds)
{
...
if (IsJumpButtonPressed() && IsPlayerOnGround()) {
Velocity.Y += JUMP_VELOCITY;
}
...
// Apply gravity
Velocity.Y -= GRAVITY_VELOCTY * deltaSeconds;
...
// Later in the code, you adjust the player's position and also check if he's on the ground
Position.X += Velocity.X;
Position.Y += Velocity.Y;

if (IsPlayerOnGround()) {
Velocity.Y = 0;
}


• 18
• 18
• 11
• 21
• 16