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")