Pro jumping code?

So I know how to make simple jumping code. As in, you tap the jump button and the ySpeed is set to something negative, and from there on out a “gravity” variable adds to the ySpeed until the character hits the ground.

But in professional platformers, like Mario, the longer you hold the jump button the higher you go (up to a point)

In general, what’s the math behind this superior jump code? Is there some agreed upon math that seems especially natural?

Thanks

Here’s how I do it, with a finite statemachine:

When the player is standing, and it presses up, it sets the jump velocity to -9, as well as the status to JUMPING. While in the JUMPING status, it will increase the jump velocity so it gradually gets slower. But at the same time, if the player lets go of the jump button before the jump velocity is 0(aka its still going up), divide the velocity by 2.

Of course, you can integrate movement with all that as well.

While on jumo (ySpeed negative) check if the jump button is pressed and slow down the ySpeed’s decrease (so it jumps longer).

Although I didn’t know if something like that really happened on Mario.

Hmm, how about this?

  • Set vy to maxJumpSpeed.
  • Apply acceleration due to gravity normally each turn whether jump is pressed or not
  • Count the number of turns jump is pressed.
  • When jump is released and turns < maxJumpTime, then do vy = adjustedJumpSpeed[turns];

[tr][td]Turn[/td][td]Normal vy
(g = -2)[/td][td]Adjusted vy
(Released at t = 1)
(g = -2)[/td][td]Adjusted vy
(Released at t = 2)
(g = -2)[/td][/tr]
[tr][td]0[/td][td]10[/td][td]10[/td][td]10[/td][/tr]
[tr][td]1[/td][td]8[/td][td]8[/td][td]8[/td][/tr]
[tr][td]2[/td][td]6[/td][td]4[/td][td]4[/td][/tr]
[tr][td]3[/td][td]4[/td][td]2[/td][td]0[/td][/tr]
[tr][td]4[/td][td]2[/td][td]0[/td][td]-2[/td][/tr]
[tr][td]5[/td][td]0[/td][td]-2[/td][td]-4[/td][/tr]
[tr][td]6[/td][td]-2[/td][td]-4[/td][td]-6[/td][/tr]

I tried Agro’s suggestion and found that it works pretty well. I found that dividing by 2 felt like a bit much and ended up dividing by 1.3, but the general math works

Thanks

Yeah I think I ended up lowering it because it was too much of a halt. Just remembered it off the top of my head from when I came up with it for a 2D platformer.

Maybe you add gravity for the longer you press it down.( or however jumping works) See if it works. :stuck_out_tongue:

I think the easiest way to handle this would be to activate the jump code on the Button Released function.

When the button is down, start a counter (placing a max on how big the jump can be), when the button is released, activate the jump.

int jumpPower = 0
while (buttonDown){
    if(jumpPower < maxJumpPower){
        jumpPower++;
    }
}
doJump(jumpPower);

Hope this helps,

-Pickle

This would give a “charge-up” kind of effect. He wants the jump to happen immediately, but result in a higher jump the longer the button is pressed.

I like the idea someone said previously of setting an “isJumping” flag. And really it should be a value. On update, check to see if the jump button is down. If it is, increment isJumping.
Then check to see if isJumping has reached the maximum number of frames that you allow the jump key to be held for.
Once they either let go of the jump key or the max is reached, set isJumping to 0.
Then, all you have to do in your calculations is only apply gravity (negative acceleration that alters velocity) if isJumping is 0.

adding some pseudocode…


function update()
{
if(Key.isDown(SPACEBAR) && true == canJump)
{
    if(isJumping == 0)
    {
        yV = -100; //Input initial jump velocity
    }
    isJumping++;
}
if(isJumping > maxJumpTime)
{
    isJumping = 0;
}
if(isJumping == 0) // If isJumping is 0 at this point, it means they are falling. and they can't jump again while falling unless you implement double jumps.
{
    canJump = false;
    yV += gravity;
}
this.y += yV;
}

I wanted to test some of these ideas, but was too lazy to make a prototype game. I made a few images instead. I didn’t test my table look up method because it would involve tweaking values, but it looks like it could work. I accidentally wrote vy = adjustedJumpSpeed[turns] instead of vy -= jumpSpeedAdjustment[turns] , but they’re basically the same.

Top-left: Half vy when button is released
Top-right: Double gravity after button is released
Bottom-left: Set vy to zero when button is released
Bottom-right: Subtract 2 * gravity when button is released :point: My method if every value were expectedVy - 2 * gravity

I would say the two on the right look best but are both flawed. I wonder how well they work in an actual game.

Edit: One more

vy -= 0.75 * Math.sqrt(maxTurns - turns) * gravity;

Actually, probably lessen gravity. ;D

I believe the original Mario games would set gravity to zero if the jump key was still down (up to a maximum of a second or so). Not sure if the modern ones still do that or something more complicated.

I recommend Bubka’s algorithm. That used to be naturally efficient.

Just kidding, sorry ;D (google “bubka record” for more info)

And I thought that Bubka is something like theory/algorithm >_> ;D

Doubling after the button is released is the same as halving before the button is released. Although I wrote it the way it was technically implemented, no one would have noticed if I phrased it one way or another. :persecutioncomplex: I didn’t want to change the initial velocity/gravity in my source code.