How can I have the player jump higher if the jump key is held down longer? I am currently just reducing gravity as long as the key is held and the player is jumping, but this looks odd.
First you need to decide what you want the jump to look like.
In real life, the jump height is decided at the moment that you leave the ground. You can't keep jumping higher while you're already in mid-air.
So if you can control your jump height while you're already in the air, you're going to get some sort of "jet-pack"-like effect.
I seem to remember a sidescroller that had two different jump heights, I think it was one of the super mario games. The higher jump occured when you held the jump button, and the jump was then actually a two part jump, starting with the initial regular jump, followed by a second impulse that took you higher.
So, what do you want your jump to look like? What sort of control do you want the player to have over the jump?
What I would start with is this:
Leave gravity alone (i.e. never change it). When a player presses the jump button, apply the jump force as long as the player is pressing the jump button (up to some time limit). Then when the player releases the jump button, he cannot apply any jump force again (i.e. he can't initiate a jump again) until he touches the ground first, at which point jumps are re-enabled.
I have seen some people do this:
You may need to use trial and error (or "logical guessing") to find suitable values for those "some number"s, unless you know how to do it.
When the character jumps using the method I originally described above, it "rises up" faster then "falling back downwards". The drag, however, slows down the vertical speed. Since we set the vertical speed to be proportional to the
There are other ways to solve this problem though, like decreasing the affect of gravity on the character as it falls. However, we need to find how much we should reduce the gravity.
Case Study: Infinite Mario
This is what I found (from line 206 of Mario.java by Markus Persson (Notch)):
This is similar to the suggestion from Olhovsky, but in this case the force will be proportional to the amount of time passed after the player pressed the jump key.
However, some values for the constants (e.g. "gravityConstant" and "jumpConstant") will give an unrealistic jump though. But sometimes games don't have to be realistic! (update see the update section above)
This question is more than a year old already, but I hope this helps!
As Olhovsky has said, the jump height is decided the moment you leave the ground, not after that.
If you really want to avoid the jetpack effect, I only see two ways: a key combination to jump higher, or fundamentally changing the way the jump key works:
Instead of making the player jump as soon as the key is pressed, delay the jump until the key is released. So basically the duration of the key press controls how much spring tension in the player’s legs is built up, and subsequently released.
Of course, this fundamentally alters the game mechanics and may be unfamiliar for the player. But the effect could be quite interesting and may well be worth the unfamiliarity.
I've found another solution in David Gouveia's answer to the question " How to make a character jump?"
His idea was to set a velocity when the player pushes down the jump button. In every frame it only computes the gravity. However, when the player releases the button, it sets the velocity to a smaller value if the velocity is greater than it. The velocity is only decremented each frame by the gravity.
I shouldn't steal his answer, so go ahead and read his post. His solution is under the "Variable Height Jump" section.
So really people came up with many different ways to solve this problem...