Godot Version
4.7
Question
I have a question. I want the player to jump twice while in FALL state (from IDLE to FALL). The double jump works from the ground. The double jump after a coyote jump works too. Am I just missing something obvious?
extends CharacterBody2D
enum STATE {
IDLE,
RUN,
JUMP,
FALL,
DOUBLE_JUMP,
}
const fall_gravity := 1000.0
const fall_velocity := 300.0
const run_velocity := 120.0
const jump_velocity := -280.0
const jump_deceleration := 500.0
const double_jump_velocity := -200.0
@onready var player_sprite: Sprite2D = $Player_sprite
@onready var coyote_timer: Timer = $CoyoteTimer
var active_state := STATE.FALL
var can_double_jump := false
func _ready() -> void:
switch_state(active_state)
func _physics_process(_delta: float) -> void:
process_state(_delta)
move_and_slide()
func switch_state (to_state: STATE) -> void:
var previous_state := active_state
active_state = to_state
match active_state:
STATE.FALL:
if previous_state == STATE.IDLE:
coyote_timer.start()
STATE.IDLE:
can_double_jump = true
STATE.JUMP:
velocity.y = jump_velocity
coyote_timer.stop()
STATE.DOUBLE_JUMP:
velocity.y = double_jump_velocity
can_double_jump = false
func process_state(_delta: float) -> void:
match active_state:
STATE.FALL:
velocity.y = move_toward(velocity.y, fall_velocity, fall_gravity * _delta)
handle_movement()
if is_on_floor():
switch_state(STATE.IDLE)
elif Input.is_action_just_pressed("jump"):
if coyote_timer.time_left > 0:
switch_state(STATE.JUMP)
elif can_double_jump:
switch_state(STATE.DOUBLE_JUMP)
STATE.IDLE:
handle_movement()
if not is_on_floor():
switch_state(STATE.FALL)
elif Input.is_action_just_pressed("jump"):
switch_state(STATE.JUMP)
STATE.JUMP, STATE.DOUBLE_JUMP:
velocity.y = move_toward(velocity.y, 0, jump_deceleration * _delta)
handle_movement()
if Input.is_action_just_released("jump") or velocity.y >=0:
velocity.y = 0
switch_state(STATE.FALL)
func handle_movement() -> void:
var input_direction := signf(Input.get_axis("move_left", "move_right"))
if input_direction:
player_sprite.flip_h = input_direction < 0
velocity.x = input_direction * run_velocity