Animating player

Godot Version

4.7

Question

Im trying to animate the player but it’s going wrong. Only fall animation is playing. Any help?

extends CharacterBody2D
@onready var audio_stream_player_2d: AudioStreamPlayer2D = $AudioStreamPlayer2D
@onready var animated_sprite_2d: AnimatedSprite2D = $AnimatedSprite2D


const speed = 400
const jump_power= -1400

const acc = 50
const friction = 70

const gravity = 100

const max_jumps = 2
var current_jumps =1

func _physics_process(delta):
	var input_dir : Vector2 =input()
	if input_dir != Vector2.ZERO:
		accelerate(input_dir)
		#play_animation()
	else:
		add_friction()
	player_movement()
	jump()
	animate_player()
	
func input() -> Vector2:
	var input_dir = Vector2.ZERO
	
	input_dir.x = Input.get_axis("left","right")
	input_dir = input_dir.normalized()
	return input_dir
	
func accelerate(direction):
	velocity = velocity.move_toward(speed * direction, acc)
	
func add_friction():
	velocity = velocity.move_toward(Vector2.ZERO, friction)
	
func player_movement():
	move_and_slide()

func jump():
	if Input.is_action_just_pressed("jump"):
		if current_jumps < max_jumps:
			velocity.y = jump_power
			current_jumps = current_jumps + 1
			audio_stream_player_2d.play()
	else:
		velocity.y += gravity
	if is_on_floor():
		current_jumps = 1



func animate_player():
	if velocity.x > 0 or velocity.x < 0:
		animated_sprite_2d.animation = "Running"
	else:
		animated_sprite_2d.animation = "Idle"
		
	if velocity.y > 0:
		animated_sprite_2d.animation ="Jump"
	else:
		animated_sprite_2d.animation = "Fall"

Your animate_player function has two separate if/else blocks, so the function sets the animation to Running or Idle, then it immediately and always set it to Jump or Fall. You need another condition like is_on_floor to only play the jump or fall animation if the player is not touching the floor

Thanks! It worked but one more problem. The running animation has more than 1 frame but in-game it only shows one.

Can you share your edited code?

\extends CharacterBody2D
@onready var audio_stream_player_2d: AudioStreamPlayer2D = $AudioStreamPlayer2D
@onready var animated_sprite_2d: AnimatedSprite2D = $AnimatedSprite2D

const speed = 400
const jump_power= -1200

const acc = 50
const friction = 70

const gravity = 80

const max_jumps = 2
var current_jumps =1

func _physics_process(delta):
var input_dir : Vector2 =input()
if input_dir != Vector2.ZERO:
accelerate(input_dir)
#play_animation()
else:
add_friction()
player_movement()
jump()
animate_player()
if Input.is_action_just_pressed(“end”):
get_tree().quit()
func input() → Vector2:
var input_dir = Vector2.ZERO

input_dir.x = Input.get_axis("left","right")
input_dir = input_dir.normalized()
return input_dir

func accelerate(direction):
velocity = velocity.move_toward(speed * direction, acc)

func add_friction():
velocity = velocity.move_toward(Vector2.ZERO, friction)

func player_movement():
move_and_slide()

func jump():
if Input.is_action_just_pressed(“jump”):
if current_jumps < max_jumps:
velocity.y = jump_power
current_jumps = current_jumps + 1
audio_stream_player_2d.play()
else:
velocity.y += gravity
if is_on_floor():
current_jumps = 1

func animate_player():
if velocity.x > 0 or velocity.x < 0:
animated_sprite_2d.animation = “Running”
else:
animated_sprite_2d.animation = “Idle”

if not is_on_floor() and velocity.y > 0:
	animated_sprite_2d.animation ="Jump"
elif not is_on_floor() and velocity.y < 0:
	animated_sprite_2d.animation = "Fall"

The first if/else block will still run, interrupting the fall/jump animation; not sure abou tthe running animation. I would recommend using .play instead of .animation =

This is how I would write it

func animate_player():
	if is_on_floor():
		if velocity.x != 0:
			animated_sprite_2d.play("Running")
		else:
			animated_sprite_2d.play("Idle")
	else: # in air
		if velocity.y > 0:
			animated_sprite_2d.play("Jump")
		else:
			animated_sprite_2d.play("Fall")

Thanks!