7
\$\begingroup\$

I'm new to game development and am looking for some help on improving my jump handling for a simple side scrolling game I've made. I would like to make the jump last longer if the key is held down for the full length of the jump, otherwise if the key is tapped, make the jump not as long. Currently, how I'm handling the jumping is the following:

Player.prototype.jump = function () {
    // Player pressed jump key
    if (this.isJumping === true)
    {
        // Set sprite to jump state
        this.settings.slice = 250;

        if (this.isFalling === true)
        {
            // Player let go of jump key, increase rate of fall
            this.settings.y -= this.velocity;
            this.velocity -= this.settings.gravity * 2;
        }
        else
        {
            // Player is holding down jump key
            this.settings.y -= this.velocity;
            this.velocity -= this.settings.gravity;
        }

    }

    if (this.settings.y >= 240)
    {
        // Player is on the ground
        this.isJumping = false;
        this.isFalling = false;
        this.velocity = this.settings.maxVelocity;
        this.settings.y = 240;
    }
}

I'm setting isJumping on keydown and isFalling on keyup. While it works okay for simple use, I'm looking for a better way handle jumping and gravity. It's a bit buggy if the gravity is increased (which is why I had to put the last y setting in the last if condition in there) on keyup, so I'd like to know a better way to do it. Where are some resources I could look at that would help me better understand how to handle jumping and gravity? What's a better approach to handling this? Like I said, I'm new to game development so I could be doing it completely wrong. Any help would be appreciated.

\$\endgroup\$

1 Answer 1

7
\$\begingroup\$

Here's how I would suggest handling it:

First, have your Player class store a variable, jumpForce, which is a 2D-vector similar to velocity and gravity. Now, also have a constant, initialJumpForce, which is the immediate force that will be exerted on your player when the jump key is first pressed. When the jump key is pressed, and the player is grounded (e.g. Player.settings.y is 240), then:

jumpForce = initialJumpForce;

And, each update:

// Calculate the net force acting on the player.
var netForce = this.jumpForce - this.settings.gravity;
this.velocity += netForce * deltaTime;

// Deteriorate the jumping force.
this.jumpForce -= this.settings.gravity;
// Do something to ensure that jumpForce doesn't become negative.

Note that an extra variable, deltaTime, appeared. This is something you must use when integrating velocity and position in an update loop. deltaTime will be the amount of time, in seconds, that has passed since the last frame.

Whenever the jump key is released, immediately set Player.jumpForce back to 0. This way, gravity takes over entirely on your player. Essentially, holding down the jump key keeps the slowly diminishing jumping force alive to act upon your player while in the air.

You might also consider applying an impulse, or direct change in velocity when the jump key is pressed. While jumpForce will get the dynamics you want with jump controls, it will take time to act upon the player, making jumping appear sluggish. So, in addition to setting jump force, you could do something simple like:

this.velocity.y = 50;

I picked 50 arbitrarily... not sure what units you're using, but it's a value you can play with; same with initialJumpForce. Hope this helps :)

\$\endgroup\$
3
  • \$\begingroup\$ This is a great place to start. A quick question on deltaTime to make sure I'm understanding it correctly. Would it just be one second divided by my framerate? For instance, if my frames per second is 30, then deltaTime would be 1/30, or .033? \$\endgroup\$
    – opes
    Commented Nov 13, 2012 at 7:00
  • 2
    \$\begingroup\$ @sprawl Yup, that is correct. Be warned though, if you assume that your framerate is fixed at 30, you could get unexpected results. Usually framerate will fluctuate slightly, especially if you start doing some heavy calculations. It's better to use a system timer and recalculate each frame how much time has passed since the last frame. E.g. dt = getTotalElapsedSeconds() - totalElapsedSecondsLastFrame; \$\endgroup\$ Commented Nov 13, 2012 at 7:18
  • \$\begingroup\$ @ktodisco Thanks for the information. I'll go ahead and give it a go. This was really informative and I really appreciate it. Thanks! \$\endgroup\$
    – opes
    Commented Nov 13, 2012 at 19:01

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .