How to play character animations? (SOLVED)

Hello reader.
I am currently trying to make a zelda like game with animations for movement but have come to some problems, the animations play but at an abnormal frame rate and dont seem to stop when standing still. Here is my code

function init(self)
    msg.post(".", "acquire_input_focus") 
    self.vel = vmath.vector3()     
end

function update(self, dt)
    local pos = go.get_position() 
    pos = pos + self.vel * dt 
    go.set_position(pos) 
    
    self.vel.x = 0 
    self.vel.y = 0
end

function on_input(self, action_id, action)
    if action_id == hash("up") then
        self.vel.y = 15
        elseif action_id == hash("down") then
        self.vel.y = -15
        msg.post("#robo", "play_animation", {id = hash("down M")})
        elseif action_id == hash("left") then
        self.vel.x = -15
        msg.post("#robo", "play_animation", {id = hash("left M")}) 
        elseif action_id == hash("right") then
        self.vel.x = 15
        msg.post("#robo", "play_animation", {id = hash("right M")})
    end
end

Any suggestions to how to fix this problem would be highly appreciated

It looks like you are using sprite animations. You can control much of its behaviour on the animations properties in the atlas. The speed is controlled by the FPS (frames per second) and the looping is controlled by the Playback.
47

You act on all input, meaning that if you press ”up”, for instance, you get 60 inputs/s and the animation restarts each frame.

What you want to do is to only play a new animation when the input changes. Alternatively, only play when user presses the button, avoiding all repeats when the button is held down:

if action_id == hash("up") and action.pressed then
  ...
1 Like

Thank you for the reply, however I still seem to be facing the same problem.
So I did a little reading and found an idea of how the animations might work but not quite sure how to apply them to the code

1st idea:
Have the sprite respond to the direction of movement

If self velocity.x < 0 then
msg.post("#robot", “play_animation”, {id = hash(“walk left”)})
( Or is it called play_animation(self, “walk left”)

If self velocity.x > 0 then
msg.post("#robot", “play_animation”, {id = hash(“walk right”)})
( Or is it called play_animation(self, “walk right”)

2nd idea:
have animations play based on booleans

if action_id == hash(“left”) then set ( move left = true )
if ( move left = true ) then
msg.post("#robot", “play_animation”, {id = hash(“walk right”)})
( Or is it called play_animation(self, “walk right”)

if action_id == hash(“left”) then set ( move right = true )
if ( move right = true ) then
msg.post("#robot", “play_animation”, {id = hash(“walk right”)})
( Or is it called play_animation(self, “walk right”)

I may be mixing up lua with other languages but is it possible to apply these codes to defold scripts and if so where would they be placed

  • function update_animations(self)

  • function play_animation(self, anim)

  • function update(self, dt)

Thank you for taking the time to read this

Have a look at this example: https://github.com/britzl/publicexamples/tree/master/examples/play_animation

It shows how to play animations based on user input and stop animations when a key is released.

This is almost perfect,
But now the animations frames are still out of control.
Although I set the animations to play at 10 fps when creating them they still play at an insanely high speed.

This will also cause a few issues when moving in diagonals.

I once used another app named stencyl to make a few games and there was a section for animations to be added where one could place conditions on motion like so:

If I were to reuse this kind of logic in defold where would it be placed ?

function update_animations(self)

function play_animation(self, anim)

function update(self, dt)

( I currently dont fully comprehend the differences between these functions )

Thank you for taking the time to read this

update_animations() and play_animation() are custom functions written by the user (you). They won’t exist or ever be called unless you do it.

When you create a new script, Defold automatically adds all the “lifecycle functions” to it:

  • init — called when the script instance is created
  • final — called when the script instance is destroyed
  • update — called every frame
  • on_message — called every time the script gets a message
  • on_input — called every time the script gets input (if it has acquired input focus)
  • on_reload — called when the script is hot reloaded

These functions will be called by the engine at certain points during the life of the script instance and your game. They won’t actually do anything until you add code to them. All the code in your game will branch out from these functions.

Then there are the engine API functions. Basically all of these will be prefaced by the name of the library that they are in, like: go.get_position() (from the Game Object library), msg.post() (from the Message library), or vmath.length() (from the Vector Math library). You have to call these yourself, but what they do is pre-defined and isn’t meant to be changed.

Then there are user-defined functions (like update_animations or play_animation). You can create as many of these as you want. Basically anytime you have a sequence of things that you want to do multiple times in the same script, you should put those things in a function (otherwise you will have to write the same code multiple times). You should always define them as local or you may get very weird bugs.


The colored blocks that Stencyl uses are basically identical to text code. If you took away the colored shapes so you just had the text, that would be very close to the code you need to write for Defold.

Stencyl’s “When Creating” is the same as Defold’s init(), and for all simple cases, Stencyl’s “When Drawing” and “When Updating” are combined in Defold’s update().

5 Likes

Could you please try checking the Variable Dt option in game.project and see if this helps? It sounds as if you’re graphics driver isn’t respecting the vsync and runs full speed.

1 Like

This worked, the animations are now playing as the frame I specified. Thank you !!!

2 Likes