Jump to content
  • Advertisement
Sign in to follow this  
Subliminalman

Unity 2D Jumping

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

If you intended to correct an error in the post then please contact us.

Recommended Posts

Currently I am working on a 2d fighting game and the jumping system I have currently creates a funky looking jump that I don't like. Here's a graph of what the jump looks like in 2d space in relation to the sprites X,Y Position while jumping.

sprite jump



I looked through a few of the topics here and tried to incorporate their methods, namely the one from this topic http://www.gamedev.net/community/forums/topic.asp?topic_id=559493 but it keeps my sprite at the top of the screen without it coming back down for some reason.

Here is the current code I am using


private void Jump()
{

if (canJump)
{
if (isJumping && !moving)
{
//velocity.Y = (float)gameTime.ElapsedGameTime.Milliseconds * acceleration.Y * (float)0.5;

isOnGround = false;
position.Y = position.Y - jumpSpeed;
position.X = position.X + velocity.X;

if (position.Y <= (groundLevel - jumpHeight))
{
moving = true;
}
}

if (moving)
{
position.Y = position.Y + (jumpSpeed/2);//velocity.Y;
position.X = position.X + velocity.X;
//currentState = CharState.JUMP;
}

if (position.Y > groundLevel && !isOnGround)
{

//velocity.Y = 0;
velocity.X = 0;
isJumping = false;
position.Y = groundLevel;
isOnGround = true;
moving = false;

canJump = false;
currentState = CharState.IDLE;
currentFrame.X = 0;
}
}

else
{

if (currentFrame.X > 2)
{
canJump = true;
}
}
}



Any help would be awesome thanks!

Share this post


Link to post
Share on other sites
Advertisement
You should change your approach...

Your players should receive a constant gravity (an acceleration that increases their velocity downwards unless it's touching the ground) each frame, and the action of jumping should apply an upwards velocity to the player.

That way, upon pressing jump, the player's y velocity shoots up, and the gravity makes that upwards movement decay until the player starts freefalling back down to the ground.

Share this post


Link to post
Share on other sites
So I'm still having trouble, the sprite will either not get off the ground or it will go shooting straight up into the air and not come back down.

Here's the two equations I'm using.

float gravity = -0.9;
Vector2 acceleration = new Vector2(0, 5);

velocity.Y += (float)gameTime.ElapsedGameTime.Milliseconds * gravity;


or I use

velocity.Y = (float)gameTime.ElapsedGameTime.Milliseconds * acceleration.Y + gravity;


position.Y = position.Y - velocity.Y;
position.X = position.X + velocity.X;



then in my Sprites class in it's update loop I have it do this

//pseudo
update(GameTime gameTime)
{
if(upButton.GetState() == ButtonState.IsPressed)
{
velocity.Y +=10;
}
}



I dont know exactly what I am doing wrong

Share this post


Link to post
Share on other sites
You have several problems. You're mixing accelerations, velocities and positions.
Quote:
velocity.Y += (float)gameTime.ElapsedGameTime.Milliseconds * gravity;

or I use

velocity.Y = (float)gameTime.ElapsedGameTime.Milliseconds * acceleration.Y + gravity;

position.Y = position.Y - velocity.Y;
position.X = position.X + velocity.X;

What do you use?

If you want to use the second velocity equation, you need to apply the delta-time to gravity also. And the result is a change in velocity so you need to add that to the original velocity. I.e.,

velocity.Y += (float)gameTime.ElapsedGameTime.Milliseconds * (acceleration.Y + gravity); // not the parentheses.

Also, you need to apply the delta-time to the velocity in your position equations:

position.Y = position.Y - velocity.Y * delta-time; // EDIT Question: why do you subtract?
position.X = position.X + velocity.X * delta-time;

[Edited by - Buckeye on December 29, 2010 9:51:55 PM]

Share this post


Link to post
Share on other sites

float gravity = -0.9; // You may have to adjust this value depending on what
// units you are using. Play around with it.
// Vector2 acceleration = new Vector2(0, 5); // get rid of this

// You should determine how much time has elapsed first and save it, to
// keep the code concise. In fact, you should pass this value as a parameter
// to the function where you do physics updates.
float elapsedTime = gameTime.ElapsedGameTime.Milliseconds;

velocity.Y += elapsedTime * gravity; // use this one


// DO NOT use velocity.Y = elapsedTime * acceleration.Y + gravity;
// That means that the guy is wearing a rocket pack, and furthermore that
// gravity has no concept of time elapsed.

// position.Y = position.Y - velocity.Y; // This is the problem: you must also
// account for time elapsed when you update the position with velocity.
// Also, velocity is a signed quantity, so you should always be adding it,
// not subtracting it. Establish a consistent sign convention. E.g. if you want
// the positive Y axis to be up (as in math), then gravity is negative,
// and if you want the positive Y axis to be down (as in screen coordinates),
// then gravity is positive. But either way, you always ADD acceleration to
// velocity, and always ADD velocity to position.
position.Y += elapsedTime * velocity.Y;
// Same thing in the X direction.
position.X = position.X + velocity.X;


//pseudo
update()
// The function that handles key presses should probably not
// care about elapsed time.
{
if(upButton.GetState() == ButtonState.IsPressed
&& onGround() // important! Only set the Y-velocity once.
// You should also check that the button has been released since the
// last time the player landed - you don't want him to bounce up and down
// repeatedly if he holds the button for a long time.
{
velocity.Y = 10; // set, don't add.
}
}

Share this post


Link to post
Share on other sites
Ok I have it working now with a beautiful curve! Thank you everyone who helped me out!

Here's the end code I have


float gravity = -0.09f;
private void Jump(GameTime gameTime)
{
float elapsedTime = (float)gameTime.ElapsedGameTime.Milliseconds * speed;

if (canJump)
{
if (isJumping && !moving)
{
isOnGround = false;

velocity.Y += elapsedTime * gravity;
position.Y -= elapsedTime * velocity.Y; // I found that if I had
//this negative and the gravity negative it worked but didn't work with the recommended way
// for screen coordinates. I don't understand why it didn't work like that but hey it works.
position.X += velocity.X;
}
}
}




Thank you again everyone! feel free to use this code :D

Share this post


Link to post
Share on other sites
This just doesn't make sense:
position.Y -= elapsedTime * velocity.Y;

I assume you do that since PC 0,0 is upper left. You should negate gravity, ie, make gravity a positive number, which means, for PC graphics, it will push down the screen. That's technically the right way to do it IMO.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!