How to handle animations?

Godot Version

``extends CharacterBody2D

var speed = 300.0
const JUMP_VELOCITY = -400.0
const RUN_SPEED = 350.0
const SLIDE_SPEED = 700.0

var sliding = false
var sliding_cooldown = false

@onready var health = 100

@onready var playersprite = $playersprite
@onready var playeranimation = $playersprite/playeranimation

func _process(delta: float) → void:
if velocity.x == 0:
print(velocity.x)
anim_handler()

func _physics_process(delta: float) → void:

if not is_on_floor():
	velocity += get_gravity() * delta

# Handle jump.
if Input.is_action_just_pressed("space") and is_on_floor():
	velocity.y = JUMP_VELOCITY


var direction := Input.get_axis("left", "right")
if direction and sliding == false:
	velocity.x = direction * speed
else:
	velocity.x = lerp(velocity.x, direction * SLIDE_SPEED, delta * 5.0)

if Input.is_action_just_pressed("slide") and sliding_cooldown == false:
	playeranimation.play("idle")
	speed = SLIDE_SPEED
	$Timer.start()
	
anim_handler()

move_and_slide()

func anim_handler():
if velocity.x > 0:
playeranimation.play(“player_walking”)
$playersprite.scale.x = 7
$playercollision.scale.x = 1
elif velocity.x < 0:
playeranimation.play(“player_walking”)
$playersprite.scale.x = -7
$playercollision.scale.x = -1
if velocity.x == 0:
playeranimation.stop()
playeranimation.play(“idle”)

func _on_timer_timeout() → void:
sliding_cooldown = true
playeranimation.play(“idle”)
speed = RUN_SPEED
$cooldown.start()

func _on_cooldown_timeout() → void:
sliding_cooldown = false``

Question

I was thinking how should I make the animations so the code would be cleanier to read and also how to stop walking animation and start idle animation when player doesnt move

Hi,

Your code seems fine to me, I guess you could have a separate script for the visual or something like that, but at least you have a function handling animations so I’d say that’s a good start.
A few things you could do:

Your current code looks like this (I’m just pasting it again with proper formatting for reference/comparison purpose):

func anim_handler():
    if velocity.x > 0:
        playeranimation.play('player_walking')
        $playersprite.scale.x = 7
        $playercollision.scale.x = 1
    elif velocity.x < 0:
        playeranimation.play('player_walking')
        $playersprite.scale.x = -7
        $playercollision.scale.x = -1
    if velocity.x == 0:
        playeranimation.stop()
        playeranimation.play('idle')

1/ If velocity.x is either greater than 0 or less than 0, then you don’t need to check afterward if it’s equal to 0, just use an “else” case:

func anim_handler():
    if velocity.x > 0:
        # ...
    elif velocity.x < 0:
        # ...
    else:
        # ...

2/ Instead of assigning values such as -1/1 and -7/7 based on whether or not velocity.x is positive, you can use the sign of velocity.x (which will be 1 if it’s positive, -1 if not):

$playersprite.scale.x = sign(velocity.x) * 7
$playercollision.scale.x = sign(velocity.x)

And since using sign will automatically handle both positive and negative velocities, you don’t need your two conditions anymore, just one to check if velocity is different than 0:

if velocity.x != 0:
    playeranimation.play('player_walking')
    $playersprite.scale.x = sign(velocity.x) * 7
    $playercollision.scale.x = sign(velocity.x)

3/ Not 100% sure but I think you don’t need to stop the animation before playing the idle, so you could remove the line in the else block.

Final code would look like this:

func anim_handler():
	if velocity.x != 0:
		playeranimation.play('player_walking')
		$playersprite.scale.x = sign(velocity.x) * 7
		$playercollision.scale.x = sign(velocity.x)
	else:
		playeranimation.play('idle')

I may have not understood the question but you’re already doing that in the anim_handler function, since you’re playing the animations based on velocity.x, which is a proper way of checking if the character is moving or not.

Because velocity.x is getting lerped towards 0, it won’t ever be exactly 0. For floats you should always use is_equal_approx() or is_zero_approx() instead of ==.

	if not is_zero_approx(velocity.x):
1 Like