#Need help figuring out the code needed to implement an animation (2D platformer)

82 messages · Page 1 of 1 (latest)

cerulean cairn
#

I've been trying to figure out a way implement a jumping animation

I have a functioning Idle and Walking animation yet whenever I try to add the jumping animation, it just doesn't work

I'd appreciate some guidance

scenic relic
#

code please

cerulean cairn
#

want me to dm it or post it here?

scenic relic
#

you can post it here

cerulean cairn
#

extends CharacterBody2D

var player_state
const SPEED = 300.0
const JUMP_VELOCITY = -700.0
@onready var animated_sprite_2d_2 = $AnimatedSprite2D2

var gravity = ProjectSettings.get_setting("physics/2d/default_gravity")

func _physics_process(delta):

if abs(velocity.x) > 1:
    $AnimatedSprite2D2.play("Walk")
else:
    $AnimatedSprite2D2.play("Idle")


if not is_on_floor():
    velocity.y += gravity * delta

if Input.is_action_just_pressed("ui_accept") and is_on_floor():
    velocity.y = JUMP_VELOCITY

var direction = Input.get_axis("ui_left", "ui_right")
if direction:
    velocity.x = direction * SPEED
else:
    velocity.x = move_toward(velocity.x, 0, 14)

move_and_slide()
if Input.is_action_just_pressed("ui_left"):
    $AnimatedSprite2D2.flip_h = true
if Input.is_action_just_pressed("ui_right"):
    $AnimatedSprite2D2.flip_h = false
scenic relic
#

tip for posting code #welcome message

#

ok, I recommend you creating a state_machine or at least a variable to keep track of your states (Idle, Walk, Jump, etc)

#

to know if you jumping you can use the is_on_floor() method

#

and if you want to know if it is falling you can use the velocity.y

cerulean cairn
scenic relic
#

I see you are creating a variable for your AnimatedSPrite2D node but you are not using it. Use that variable in the code instead of $AnimatedSprite2D every time

#

you simply set the state instead of changing the animation. Then create a function to update the animation based on the state

#

to make it easer you can create an enum with your state
enum State {IDLE, WALK, JUMP}

and the player_state can be var player_state:State

cerulean cairn
#

yeah I'm just not sure what to write and where to attach all this

#

i added that :State to the 'var player_state'

#

idk where that enum goes tho

scenic relic
#

the enum goes at the top, below the node type

and the state change is instead of chaning animations, for instance:

if not is_on_floor():
    player_state = State.JUMP
elif: velocity.x != 0:
    player_state = State.WALK
else:
    player_state = State.IDLE
cerulean cairn
#

below the CharacterBody2D?

scenic relic
#

yeah. before any function

cerulean cairn
#

it says expected identifier for enum key

scenic relic
#

how did you write it?

cerulean cairn
#

extends CharacterBody2D
var player_state:State
enum State {"Idle", "Walk", "Jump"}
scenic relic
#

they can't be strings

#

just write IDLE, WALK, JUMP

#

(is good practice that constants are in UPPERCASE, not obligatory though)

cerulean cairn
#

okay, the error is gone now, what's the next step?

scenic relic
#

now you create a function to update the animation based on the state

#

and call it every frame

#

after the movement logic

cerulean cairn
scenic relic
#

just put it after move_and_slide

#

or before

#

doesn't really matter

cerulean cairn
#

alright, and how does that function look like?

scenic relic
#

you can create if staments or a match statement to check the player_state

#

you wrote an if statement before

cerulean cairn
#

i tried doing it by

if not is_on_floor():
velocity.y += gravity * delta
player_state = State.JUMP

#
If player_state == State.JUMP:
$animatedsprite2d2.play("Jump")
scenic relic
#

no, the animation function is just to change the animation based on the state. It should not have any other logic like velocity, etc

#
func update_animation():
    var animation:String = "Idle"
    match player_state:
        State.WALK: animation = "Walk"
        State.JUMP: animation = "Jump"
    animated_sprite_2d.play(animation)
cerulean cairn
#

and i'm assuming for this to work i need to delete the previous code for animations, right?

scenic relic
#

yes, you won't need those

#

I think this is a better approach because you keep all your animation logic in one place. You don't have to go through all the movement logic looking for where you are changing animations

cerulean cairn
#

there's no errors now but the animations don't work at all

#

is there another component to this i'm missing?

#

everything else in the physics function has only code regarding to physics and inputs, and the horizontal sprite flipping code

cerulean cairn
scenic relic
#

a function always go outside

cerulean cairn
#

alright then, it's outside

scenic relic
#

try printing the animation variable at the end of the update_animation function

#

see it it is changing to the right string

cerulean cairn
scenic relic
#

print(animation)

#

and again, use the variable that you set the reference to the AnimatedSprite2D node

#

if you use $AnimatedSprite2D the engine has to search for it every frame

cerulean cairn
#

the print is going on only 1 indent I'm assuming?

scenic relic
#

you can place after the last line

#

yes, one indent

cerulean cairn
#

still doesn't seem to work

#
extends CharacterBody2D

var player_state:State
enum State {IDLE, WALK, JUMP}

const SPEED = 300.0
const JUMP_VELOCITY = -700.0
@onready var animated_sprite_2d_2 = $AnimatedSprite2D2

var gravity = ProjectSettings.get_setting("physics/2d/default_gravity")


func _physics_process(delta):
    
    if not is_on_floor():
        velocity.y += gravity * delta

    if Input.is_action_just_pressed("ui_accept") and is_on_floor():
        velocity.y = JUMP_VELOCITY

    var direction = Input.get_axis("ui_left", "ui_right")
    if direction:
        velocity.x = direction * SPEED
    else:
        velocity.x = move_toward(velocity.x, 0, 14)

    move_and_slide()
    if Input.is_action_just_pressed("ui_left"):
        animated_sprite_2d_2.flip_h = true
    if Input.is_action_just_pressed("ui_right"):
        animated_sprite_2d_2.flip_h = false
    
func update_animation():
    var animation:String = "Idle"
    match player_state:
        State.WALK: animation = "Walk"
        State.JUMP: animation = "Jump"
    animated_sprite_2d_2.play(animation)
    print (animation)
scenic relic
#

what is printing?

#

oh, you are never setting the player_state

cerulean cairn
#

i need another var player_state just by itself?

scenic relic
#

no, you need to set th eplayer state in the _physics_process

#
func _physics_process(delta):
    if not is_on_floor():
        velocity.y += gravity * delta
        player_state = State.JUMP
    elif velocity.x != 0:
        player_state = State.WALK
    else:
        player_state = State.IDLE

    if Input.is_action_just_pressed("ui_accept") and is_on_floor():
        velocity.y = JUMP_VELOCITY

    var direction = Input.get_axis("ui_left", "ui_right")
    if direction:
        velocity.x = direction * SPEED
    else:
        velocity.x = move_toward(velocity.x, 0, 14)


    move_and_slide()
    update_animation()
    if Input.is_action_just_pressed("ui_left"):
        animated_sprite_2d_2.flip_h = true
    if Input.is_action_just_pressed("ui_right"):
        animated_sprite_2d_2.flip_h = false
cerulean cairn
#

still nothing

scenic relic
#

any errors?

cerulean cairn
#

no

scenic relic
#

what is the output for the print?

#

are you calling update_animation?

cerulean cairn
cerulean cairn
scenic relic
#

when you use print(animation) it should print the value in the output window when the code reaches there

#

if nothing is printing, the code is not reaching there

scenic relic
#

calling the function, like that

#

otherwise the code won't run it

cerulean cairn
#

i don't think i have that

scenic relic
#

I function only runs if you call it. You don't have to call _physics_process because that is called by the engine. But any function you create yourself needs to be called

cerulean cairn
#

it's working, holy shit

#

Alright man, thanks for helping out, I'll leave some questions regarding certain parts of the code so I can understand them better, answer them whenever you got time

#

you're a real G