Godot Version
godot-4
Question:
` So, I’m new to Godot. I’m not a complete beginner to programming, but I’m still close to a noob and don’t know much of the terminology yet.
Here’s the issue I’m struggling with:
I’ve started implementing my character controller using a node-based state machine (fumbling in the dark a bit here). I already had a working 2D player controller with a jump buffer and coyote time.
Now, while refactoring my code to use the state machine approach, I’ve encountered a problem with the jump buffer. By all accounts, as far as my inexperienced eyes can tell, it should work correctly, and it does about 90% of the time. However, in some cases, the buffer just doesn’t work.
In really simple terms: while in the air, if you press space, it sets buffer_on to true and starts a timer that, when done, resets buffer_on to false. If the player is on the ground (is_on_floor() == true) and buffer_on is true, the player enters the jump state. Otherwise, it goes into the landed state.
After using print commands for debugging, I noticed that in some cases, while in the air state, the check for buffer_on and is_on_floor() fails, causing the player to go into the landing state.
If anyone could take a look at the code or offer advice, I’d really appreciate it. I’m fairly new to this, so please go easy on me! `
extends State
class_name AirState
@export var ground_state : State
@export var landing_state : State
@export var jumping_state : State
# Called when the node enters the scene tree for the first time.
# Holds the coyote timer instance so it can be disconnected or stopped.
var buffer_timer = null
var buffer_timer_started = false # Tracks if the timer has been started
func state_process(delta):
if character.is_on_floor():
if not p_jump_buffered:
next_state=landing_state
else:
# Reset buffered jump and timer before transitioning to jumping state
p_jump_buffered = false
reset_buffer_timer()
print("you jumped from jump buffer")
next_state = jumping_state
else:
boost_left_check()
func state_input(event : InputEvent):
# Check if jump is pressed and buffer timer has not been started
if event.is_action_pressed("jump_move"):
reset_buffer_timer()
# Start buffer timer
print(" you started the buffer timer")
p_jump_buffered = true
buffer_timer = get_tree().create_timer(character.player_jump_buffer_time)
buffer_timer.timeout.connect(buffer_timeout)
buffer_timer_started = true #Prevent multiple buffer timers
# handles doubble jump if player has enough boost stat
if p_can_jump:
if character.act_boost_amount >= 1:
boost_reduce(1)
p_jump_buffered=false
reset_buffer_timer()
next_state = jumping_state
# check if player has boost
func boost_left_check():
if character.act_boost_amount <= 0:
p_jump_available = false
p_can_jump = false
else:
p_jump_available = true
p_can_jump = true
# reduce the amount of boost if any left
func boost_reduce(amount: int):
if character.act_boost_amount > 0:
character.act_boost_amount -= amount
# reduce the jump amount if there is any left
func jump_reduce(amount: int):
if character.act_jump_amount > 0:
character.act_jump_amount -= amount
func buffer_timeout() -> void:
p_jump_buffered = false
buffer_timer_started = false
print('buffer time ended ended')
func reset_buffer_timer():
if buffer_timer:
buffer_timer.timeout.disconnect(buffer_timeout) # Disconnect the timeout
buffer_timer = null
print("buffer timer reset")
buffer_timer_started = false