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. :)
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:
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. :)