Jump Input Buffer implementation

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By INKnight

I’m trying to implement a jump input buffer to my game, the problem is: the jump have a max and min height. When the player releases the jump button mid air, the jump will stop. When the buffered jump is triggered, the max value is used and releasing the button don’t work.

The script:

_input(event):

if [states.idle, states.run].has(state):
        if event.is_action_pressed("jump"):
            if parent.can_jump():
                parent.jump()
    if parent.bufferTimer < parent.bufferMax:
        if parent.can_jump():
            parent.jump()
    
    if event.is_action_pressed("jump"):
        parent.bufferTimer = 0
    
    if state == states.jump:
        if event.is_action_released("jump") && parent.velocity.y < parent.min_jump_velocity:
            parent.velocity.y = parent.min_jump_velocity

_physics_process(delta):

if bufferTimer < bufferMax:
        bufferTimer += 1

jump():

velocity.y = max_jump_velocity
    jumpGraceTimer = 0
    is_jumping = true

Btw, am I doing this right? Is there a better way to do this?

So what exactly is the problem here?

  1. Releasing the jump button mid air stops the regular jump - but shouldn’t
  2. Releasing the jump button mid air doesn’t stop the buffered jump - but should
  3. Buffered jumps use the max value (of what?) - but shouldn’t (what instead?)

Apart from that, there is a lot of missing information as well:

  1. Which type does the node have?
  2. Which type does the parent have?
  3. What does the can_jump-function?
  4. When do you change states? Based on what conditions?
  5. What are jumpGraceTimer and is_jumping for?
  6. What are (min|max)_jump_velocity supposed to do?
  7. With which values do you run your code?

njamster | 2020-02-12 14:14

1 - It should and already works.
2 - It should and dont work
3 - Buffered jumps are jumping to the maximum jump height, and don’t respond to releasing the button. Releasing the button should set the velocity.y to minimum jump height.


1 - It’s a KinematicBody2D
2 - Node2D
3 - Can_jump checks if the player is on floor.
4 - The states are changed based on a State-Machine, when player is grounded, the state is [idle], and if it’s velocity.x is greater than 0 and is on ground the state is [run]
5 - jumpGraceTimer is not important in this context, it gives the player 5 frames to jump after he isn’t on the ground. is_jumping checks if the player is jumping (mid air).
4 - The min jump velocity is the minimum height the player can jump, and the max jump velocity is the maximum height the player can jump. By releasing the jump button mid air, the velocity.y is set to min_jump_velocity.

INKnight | 2020-02-13 00:54

:bust_in_silhouette: Reply From: njamster

Here’s how I would do it:

extends KinematicBody2D

const GRAVITY = Vector2(0, 9.8)
const FLOOR_NORMAL = Vector2.UP

const MAX_JUMP_HEIGHT = -500
const MIN_JUMP_HEIGHT = -200

var velocity = Vector2.ZERO
var buffer_frames_left = 0

func _physics_process(delta):
	velocity += GRAVITY

	if buffer_frames_left > 0:
		if is_on_floor():
			velocity.y = MAX_JUMP_HEIGHT
			buffer_frames_left = 0
		else:
			buffer_frames_left -= 1
	elif Input.is_action_just_pressed("ui_accept"):
		if is_on_floor():
			velocity.y = MAX_JUMP_HEIGHT
		else:
			buffer_frames_left = 60
	elif Input.is_action_just_released("ui_accept"):
		velocity.y = max(velocity.y, MIN_JUMP_HEIGHT)

	velocity = move_and_slide(velocity, FLOOR_NORMAL)

Maybe that helps you finding the issue in your implementation.

Thanks! That worked

INKnight | 2020-02-14 00:00