|
|
|
|
Reply From: |
a_world_of_madness |
AnimatedSprite
won’t wait for the current animation to finish if you call play
before that.
It seems you have a mistake in the first if
statement, where you play two animations at once:
not $AnimatedSprite.play("Fall")
This line runs the play
method, gets the return value (which is void
, so the value will be null
) and then tries to use the not
boolean operator on it, which results in the value true
, which is then discarded, as you don’t use it for anything.
Removing the line will partially fix the problem, as now the "Jump"
animation runs until the player lets go of the jump button.
You’ll need to keep track of the animation playback yourself using the frame
and animation
properties of AnimatedSprite
. You can check which animation is running, and whether it’s at the last frame.
One way could be to create a method for checking whether the current frame
number is the same as the last frame of the animation:
func has_animation_ended(anim_name):
if $AnimatedSprite.animation != anim_name:
# The current animation is named something else
return true
# Get the last frame number by decrementing one from the count
var last_frame_num = $AnimatedSprite.frames.get_frame_count(anim_name)-1
return $AnimatedSprite.frame == last_frame_num
Then you can just use that whenever you need to make sure a previous animation has ended:
if has_animation_ended("Jump"):
play("Next Animation")
Just make sure to disable the "Loop"
toggle on the "Jump"
animation in the SpriteFrames asset, otherwise the jump animation might start over after reaching the last frame.
Alternatively, you could avoid tracking the frame numbers, and instead play the "Jump"
animation, and let it hold at the last frame until the player starts falling (after the jump apex). You could do this by playing the "Fall"
animation only if the velocity.y
property is positive, and the player is not on ground.
You could restructure the code like this:
if Input.is_action_pressed("jump") and is_on_floor():
velocity.y = JUMPFORCE
$AnimatedSprite.play("Jump")
velocity.y = velocity.y + FALL
if Input.is_action_pressed("Up") and not is_on_floor():
$AnimatedSprite.play("Float")
velocity.y = FLOATFALL
elif velocity.y > 0 and not is_on_floor():
$AnimatedSprite.play("Fall")
velocity = move_and_slide(velocity,Vector2.UP)
velocity.x = lerp(velocity.x,0,0.2)
Thank you so much, it worked! I was so frustrated trying to figure it out but, you made it look like a piece of cake.
Gameguider321GO!!! | 2023-01-08 20:18
Glad I could help! The way the code is currently structured works for simpler projects, but when it starts to feel you have to keep track of too many states and variables to compare, a popular solution is to use a state machine code pattern. There are also Godot specific tutorials on Official Godot Docs and GDQuest for example. An easier one to implement can also be found on Godot Tutorials
a_world_of_madness | 2023-01-08 20:34
Thanks again! Theses tutorials will definitely be useful.
Gameguider321GO!!! | 2023-01-08 20:43