简体   繁体   中英

C# XNA 2D Platformer Jumping Logic

I'm working on a 2D platformer as a learning experiment and currently having a little trouble with the jumping logic. I understand that gravity should be applied to the player, which affects the jumping and descending process. Here's how I currently have it implemented.

isJumping is just a bool that I use to know if the player should be going up or down and whether they're currently mid-jump, so they don't jump again.

spriteJumpPosition is the value I use to limit how high the player jumps (default is 0, upper limit of 10 is hard-coded below).

void UpdateGravity()
    {
        // Check if player is currently jumping
        if (isJumping == true)
        {
            if (spriteJumpPosition < 10)
            {
                spritePosition.Y += (float)gravity;
                spriteJumpPosition += gravity;
            }
            else if ( spriteJumpPosition >= 10 )
            {
                isJumping = false;
                spritePosition.Y -= (float)gravity;
                spriteJumpPosition -= gravity;
            }
        }
        else if ( isJumping == false )
        {
            if (spriteJumpPosition > 0)
            {
                spriteJumpPosition -= (int)gravity;
                spritePosition.Y -= (float)gravity;
            }
        }
    }

With the above code, the current behavior is that the player moves down a bit (maybe 2-3 frames) then starts going up, with isJumping = false and never stops. What am I doing wrong here? Is this just the complete wrong way to go about this?

Pretty much completely wrong, I'm afraid. Do you know about position , velocity and acceleration ?

Velocity is a change in position over time. Acceleration is a change in velocity over time. Gravity is a downwards acceleration, hence things get faster as they fall.

Here is some code that might help to illustrate the concept:

Vector2 position;
Vector2 velocity;
readonly Vector2 gravity = new Vector2(0, -9.8f);

// Update:
float time = (float)GameTime.ElapsedGameTime.TotalSeconds;
velocity += gravity * time;
position += velocity * time;

If you shoot an object upwards with this code, you can get a (pretty-much) realistic trajectory. This is a good starting point for a jump.

The simplest way to start the jump would be to add some upwards velocity when the jump key is pressed. The above code will bring the character back down.

However it's worth noting that good platformers employ a lot of tricks to make the jump feel better. Most particularly so that the height of the jump can be modulated by how long the jump button is pressed. It is important to make this feel responsive, by having the player start moving downwards immediately. A quick way to do this is to set the velocity to zero and apply extra gravity while the player is moving downwards. But this is really something you must tune.

What are you using for collision detection/response? That will affect it a bit. However, you need velocity and position at the very least. An example might be:

class Player 
{
    Vector2 Position;
    Vector2 Velocity;
}

// in the constructor:

Position = new Vector2 (YOUR POSITION HERE);
Velocity = Vector2.Zero;

Then you add Velocity to Position each time step (make a Player.Update() method and call it from your default Update method). Then when you want to move, add to Velocity each timestep. For example, detect whenever the right key is pressed and add 0.5f to the X part of Velocity . Do the opposite (subtract it) for the left key, and modify Y for up and down. This will cause a sliding effect, as if on ice. For gravity, just add a small amount to the Y part each time step to make the player "fall".

To make the player jump (the easy way) just set the Y velocity to -5 or something whenever space is pressed. The character will move up, and eventually fall down because of your "gravity" as mentioned before.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM