Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

This question already has an answer here:

A player and the world are modeled using a physics engine. Jumping is modeled by applying a vertical upward force to the player's physics body when the jump button is pressed.

The upward force is being applied every update tick that the button is held. This makes the player accelerate upward so long as the button is held, potentially forever, rather than limiting the jump to a predetermined maximum jump height

How can this be fixed so that pressing the jump button allows a limited jump height, even if the button is held down indefinitely?

share|improve this question

marked as duplicate by Byte56, bummzack, Josh Petrie, Tetrad Feb 26 '13 at 3:55

This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.

1  
Note that applying a force for a long time is not jumping, it’s more like some kind of thruster effect. –  Sam Hocevar Feb 25 '13 at 6:48

2 Answers 2

Jumping is usually just one impulse, rather than a continuous force. Many games don't allow influencing this force and just allow moving sideways. (Or not even that.)

if(onGround && jumpKeyPressed)
{
  yDir -= 90;
  onGround = false;
}
if(!onGround)
{
  yDir += gravity * dTime;
  /* Check for collisions on y-Direction */
}

If you really want to make it possible to the player to influence the jump height, you can use a initial impulse and make the influence on it less than gravity.

jumpInfluence = gravity / 2;
[...]
if(!onGround)
{
  if(jumpKeyPressed)
    yDir -= jumpInfluence * dTime;
  [...]
}

If you really want the player to influence the jump even more you'll need to decrease the influence over time.

[...]
if(jumpKeyPressed)
  yDir -= (jumpInfluence / (1.f+timeSinceJump)) * dTime;
[...]

In this case after a second the influence is halved, after 2 seconds it's a third etc.

share|improve this answer

One simple solution is to keep a timer and a boolean. When the button is first pressed, if the boolean is false and the player is on the ground, apply the force and start set thee timer to some specific and set the boolean to true. When the button is released, set the boolean to false. If the boolean is true, decrement the timer by the time delta. Keep applying the force each frame so long as the boolean is true and the timer hasn't expired.

bool is_jumping = false
float jump_timer = 0.0

jump_pressed () { 
  if (!is_jumping && is_on_ground())) {
    is_jumping = true
    jump_timer = 0.5
  }
}

jump_released () {
  is_jumping = false
}

update (float time_delta) {
  if (is_jumping) {
    jump_timer = max(0.0, jump_timer - time_delta)
    if (jump_timer > 0.0)
      apply_jump_force()
  }
}

Finding the ideal timer length and force will take some tweaking. You could with some work derive the right values to get a particular jump height, but I would play with the values until you get something that feels right.

The advantages of this approach are that pressing the button for longer results in a higher jump, which is what you want if you want your platformer to feel "right" (like Mario).

If you want stiffer controls, you could allow a fixed jump velocity. Just set that boolean when the player jumps, and reset it when the player lands.

 bool is_jumping = false

 jump_pressed () {
   if (!is_jumping && is_on_ground())
     is_jumping = true
     apply_jump_force()
   }
 }

 update () {
   if (is_on_ground())
     is_jumping = false
 }

Be mindful that will require a little more work if update is called after jump_pressed is called but before physics updates and the jump force is applied. You might need an extra bool or check to avoid resetting is_jumping on that first frame.

More advanced versions can start the jump after the button is released (measuring how long the button was held) or after a timer expired (it should be a pretty short timer).

You can with this method also use fixed gradiations of jump height, e.g. a short jump if the button time is 0 - 0.05 seconds and a high jump if button time is 0.05 - 0.1 seconds. All that needs to change there is the amount of force applied for a decent effect.

Even with variable jump height, you might want a stable upward velocity, up to a point, rather than the high initial jump velocity and steady gravity acceleration. in this case, you need to each frame during jump ascent (measured again with a timer) calculate the necessary force to apply to achieve the desired velocity. This requires some knowledge of physics formulas and how your physics library updates, but is otherwise pretty simple.

share|improve this answer

Not the answer you're looking for? Browse other questions tagged or ask your own question.