Search code examples
c#xna2d

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?


Solution

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