Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

The jump algorithm I've used for a long time(and cribbed from an old co-worker) uses three variables, going to a second derivative: velocity, acceleration, and "power." The first two are pretty explanatory, the third is applied to acceleration and decremented each frame to a minimum of 0, and is instantly zeroed when jump is released early, allowing gravity to start pulling down acceleration. (Acceleration is also usually zeroed at release for a tighter top.)

Tuning these has let me reproduce pretty much any controllable jump arc - for example, the jump in Metroid has a lot of "float" to it at release time. This is doable by making acceleration at release equal to inverse of gravity.



In physics, the name for what you call “power” – the derivative of acceleration, and the third derivative of position – is “jerk”. https://en.wikipedia.org/wiki/Jerk_%28physics%29


I came up with the same thing a while back. I was hacking on a side-scroller and spent a lot of time trying to get the feel right. The detailed explanation:

To start a jump, the user presses the jump button while the character is standing. There is a "grace period" where you can still jump if the character isn't on the ground now, but was a few frames ago. This is important to be able to jump right as the character reaches the edge of a platform. Without this, you have to jump earlier than you feel you should.

Once a jump has started, we track how long the jump button has been held down. Every frame, the character's Y velocity is modified by the "jump acceleration". This acceleration starts at some high value, and ramps down linearly the longer the jump button is held down.

For example, the first frame of jumping may add -10 to velocity, then -8, -6, -4, -2, until finally zero. I found this acceleration ramp was the key to getting the jump to feel snappy yet responsive. The first frame gives the biggest velocity boost, so the character immediately leaps into the air. Then later frames give a diminishing effect so that you can more precisely dial in how much oomph you want the jump to have.

Gravity is then applied on top of this. In code, it looks like:

    // Start jump.
    if ((Actor.LastOnGround <= JumpAllowedFrames) && UserInput.JumpHeld) {
      jumpFrames = 1;
    }

    // Accelerate upwards while holding jump button.
    if (jumpFrames > 0) {
      velocity.Y -= JumpSpeed * (MaxJumpFrames - jumpFrames) / MaxJumpFrames;

      if (!UserInput.JumpHeld) {
        // Stop accelerating if player releases button.
        jumpFrames = 0;
      } else if (jumpFrames >= MaxJumpFrames) {
        // Can only accelerate for so long.
        jumpFrames = 0;
      } else {
        // Keep jumping.
        jumpFrames++;
      }
    }

    // Apply gravity.
    velocity.Y += Physics.Gravity;
I was really happy with how this turned out. Actually, now that I dig into this several-year-old code, it kind of makes me want to resurrect the project. :)




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: