Jump animation only playing for one frame

Godot Version

Godot 4.1

Question

Hi! I’m still new to Godot. I’m using Godot 4.1 for now and I’m having an issue whenever I press a button to jump. I’m currently trying to make a 2D platformer.

ALL animations are working EXCEPT for the jumping animation which only plays the very first frame and gets stuck there while the player is airborne (via jumping or falling). I have no clue as to what I’m doing wrong :frowning:

My code is as follows:

extends CharacterBody2D

var run_speed: float = 180
var max_jump: float = 11
var jump_power: int = 210
var gravity: float = 9.8
var accel: float = 2100
var default_max_speed: float = 85
var max_speed: float = 85
var friction: float = 1400

var is_in_air: bool = false
var is_moving: bool = false
var is_running: bool = false

enum PlayerState { IDLE, WALKING, RUNNING, JUMPING }

var current_state: PlayerState = PlayerState.IDLE

@onready var animated_sprite_ref = $AnimatedSprite2D

func _physics_process(delta):
velocity.y += gravity
movement(delta)

func movement(delta):

if Input.is_action_just_released("run"):
	max_speed = default_max_speed

var dir = Input.get_action_strength("right") - Input.get_action_strength("left")

if (dir == 0):
	is_moving = false
	set_state(PlayerState.IDLE)

else:
	is_moving = true
	velocity.x = move_toward(velocity.x, dir * max_speed, accel * delta)
	if is_running:
		set_state(PlayerState.RUNNING)
	if !is_running:
		set_state(PlayerState.WALKING)

	if Input.is_action_pressed("run") and is_on_floor():
		max_speed = run_speed
		is_running = true

	if Input.is_action_just_released("run"):
		max_speed = default_max_speed
		is_running = false

	if is_running and animated_sprite_ref.animation != "run":
		animated_sprite_ref.play("run")

if (dir < 0):
	animated_sprite_ref.flip_h = true
elif (dir > 0):
	animated_sprite_ref.flip_h = false
elif (dir == 0):
	velocity.x = move_toward(velocity.x, 0, friction * delta)

if Input.is_action_just_pressed("jump") and is_on_floor():
	is_in_air = true
	set_state(PlayerState.JUMPING)
	velocity.y = -jump_power

if not is_on_floor():
	is_in_air = true
	set_state(PlayerState.JUMPING)

if is_in_air and not is_on_floor():
	set_state(PlayerState.JUMPING)

move_and_slide()

func set_state(new_state: PlayerState):
if current_state != new_state:
current_state = new_state
match new_state:
PlayerState.IDLE:
animated_sprite_ref.play(“idle”)
PlayerState.WALKING:
animated_sprite_ref.play(“walking”)
PlayerState.RUNNING:
animated_sprite_ref.play(“run”)
PlayerState.JUMPING:
if animated_sprite_ref.animation != “jump”:
animated_sprite_ref.play(“jump”)

this is because you start the animation every frame, i.e. every frame you have an animation trying to start again, try to start the animation only if it has not started yet

1 Like

Hi there! Alright I’ll see if putting some if statements can fix the issue. I’ll post the result when I have it!

Sorry for the late reply. I managed to fix it learning about the AnimationPlayer node which actually made the handling of animations easier!

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.