phadaphunk
phadaphunk

Reputation: 13313

Jumping Vs. Gravity

I'm working on my first XNA 2D game and I have a little problem. If I jump, my sprite jumps but does not fall down. And I also have another problem, the user can hold spacebar to jump as high as he wants and I don't know how to keep him from doing that. Here's my code: The Jump :

    if (FaKeyboard.IsKeyDown(Keys.Space))
        {
            Jumping = true;
            xPosition -= new Vector2(0, 5);
        }

        if (xPosition.Y >= 10)
        {
            Jumping = false;
            Grounded = false;
        }

The really simple basic Gravity:

    if (!Grounded && !Jumping)
        {
            xPosition += new Vector2(1, 3) * speed;
        }

Here's where's the grounded is set to True or False with a Collision

    Rectangle MegamanRectangle = new Rectangle((int)xPosition.X, (int)xPosition.Y, FrameSizeDraw.X, FrameSizeDraw.Y);
        Rectangle Block1Rectangle = new Rectangle((int)0, (int)73, Block1.Width, Block1.Height);
        Rectangle Block2Rectangle = new Rectangle((int)500, (int)73, Block2.Width, Block2.Height);

        if ((MegamanRectangle.Intersects(Block1Rectangle) || (MegamanRectangle.Intersects(Block2Rectangle))))
        {
            Grounded = true;
        }
        else
        {
            Grounded = false;
        }

The grounded bool and The gravity have been tested and are working. Any ideas why? Thanks in advance and don't hesitate to ask if you need another Part of the Code.

Upvotes: 5

Views: 5443

Answers (4)

ssube
ssube

Reputation: 48337

A relatively simple way to handle jumping is to implement gravity as a vector and jumping/moving as an impulse.

For example:

foreach (Object obj in GameWorld)
{
    obj.Velocity *= 0.5; // Slow it down slightly
    obj.Velocity += GravityPerSecond * FrameTime; // Gravity adjusted for time
    obj.Move(obj.Velocity); // Handle collision and movement here
}

The velocity should be a vector with the same dimensions as the world, and Move a method that moves the object as far as possible in the vector given.

Jump code:

OnKeyDown(Key k)
{
    if (k == Key.Space)
    {
        obj.Velocity += Vector2(0, 10); // Add an upward impulse
    }
}

This will cause the object to move up for a bit, then begin to fall. You can use similar impulses for other effects (movement, explosions, collision). You will need to have collision modify the velocity when two objects collide, for bouncing.

This is an extremely simple physics system that will make future changes much simpler, and could allow some interesting level design (change gravity and such). It simplifies handling jumping by abstracting it out from complex IsJumping code to a single mechanic.

To prevent jumping without standing on an object, you'd need to do a collision test, or track when objects collide/stop colliding for the down direction. It might also be possible to check if the object's vertical velocity is zero and allow jumping only then (would prevent jumping while falling or moving up).

Upvotes: 5

Larry Smithmier
Larry Smithmier

Reputation: 2731

I believe this might be the answer:

change your

    if (FaKeyboard.IsKeyDown(Keys.Space))
    {
        Jumping = true;
        xPosition -= new Vector2(0, 5);
    }

    if (xPosition.Y >= 10)
    {
        Jumping = false;
        Grounded = false;
    }

to

    if (!Jumping && FaKeyboard.IsKeyDown(Keys.Space))
    {
        Jumping = true;
        Grounded = false;
    }

    if (Jumping)
    {
        xPosition -= new Vector2(0, 5);
    } 

    if (xPosition.Y >= 10)
    {
        Jumping = false;
    }

The other answers given with velocity are really better approaches, but this might be close enough to get you started again.

Upvotes: 2

Dracorat
Dracorat

Reputation: 1194

Jumping shouldn't be a boolean unless you need it for something like an animation or an ability that can only be used while jumping.

Instead, you should be using vector movement and when the player is touching the ground and press their jump button, add an upward jump vector to your motion.

Then, gravity needs to be a downward vector acting against the player and it will handle itself.

Upvotes: 0

NicoTek
NicoTek

Reputation: 1167

Here is a very rustic solution to making a jump go up and down:

const float SCALE = 20.0f; //SPEED!!!
if (jump <= 15 && jump != 0)
            {
                humanPosition.Y -= SCALE * speed;
                jump++;
            }
            else if (jump > 15)
            {
                humanPosition.Y += SCALE * speed;
                jump++;
                if (jump == 32)
                {
                    jump = 0;
                    humanPosition.Y = 307;
                }
            }

And is activated by

            else if (keyboard.IsKeyDown(Keys.Up))
        {
            jump = 1;
            humanPosition.Y -= SCALE * speed;
        }

What this does is set in motion the jump by setting it to 1 Also if you want to restrict jumping to only when the character is on the ground you can add a condition similar to this

if (humanPosition.Y != GROUNDLEVEL){}

Upvotes: 1

Related Questions