One flipbook animation after another

How do I play one animation after another?
I am trying to make my character to play attack animation when I click and then play idle animation after playing the attack animation once.

--First animation
gui.animate(animate_node, gui.PROP_POSITION, new_pos1, gui.EASING_LINEAR,
animation_speed, 0, function()
    --Second animation after completing the first
     gui.animate(animate_node, gui.PROP_POSITION, new_pos2, gui.EASING_LINEAR,
animation_speed)
end)

More details: https://defold.com/ref/stable/gui/#gui.animate:node-property-to-easing-duration-[delay]-[complete_function]-[playback]

Oh, I am using game object, not gui. Using the flipbook animation of sprite.

Yes. Sorry, I misunderstood.

sprite.play_flipbook(url,anim_id1,function()
    sprite.play_flipbook(url,anim_id2)
end)

I’m sorry but what is the function()? I’m new and I do not understand.
This is my code right now.

function on_input(self, action_id, action)
	--flipbook animation
	if action_id == hash("right") and action.pressed then
		sprite.play_flipbook("#sprite", "walk")
		self.right = true
		self.left = false
	elseif action_id == hash("left") and action.pressed then
		sprite.play_flipbook("#sprite", "walk")
		self.left= true
		self.right=false
	elseif action_id == hash("touch") and action.pressed then
		ssprite.play_flipbook("#sprite","attack",function()
			sprite.play_flipbook("sprite","idle")
		end)
	end

i fixed the ssprite

hi!

Just to make things a little clearer, you need this.

In your code, you put

sprite.play_flipbook("#sprite", "jump", anim_done)

then at the top of that .script file, you need:

local function anim_done(self, message_id, message, sender)
      sprite.play_flipbook("#sprite", "run")
end
1 Like
sprite.play_flipbook("#sprite", "jump", anim_done)

Here there are four pieces of information:
sprite.play_flipbook (we’re going to play a sprite animation)
“#sprite” (this is the address of the sprite that’s going to play the animation)
“jump” (this is the name of the animation that we’re going to play)
anim_done (when the animation is finished, we’re going to run a function called anim_done.

You define what “anim_done” is yourself, by creating a local function with that name, which must be at the top of your .script file. It can be something as simple as:

local function anim_done(self, message_id, message, sender)
    sprite.play_flipbook("#sprite", "run")
end
2 Likes

I’m sorry but this is not working either

local function anim_done(self, message_id, message, sender)
	sprite.play_flipbook("#sprite", "idle")
end
function on_input(self, action_id, action)
	--flipbook animation
	if action_id == hash("right") and action.pressed then
		sprite.play_flipbook("#sprite", "walk")
		self.right = true
		self.left = false
	elseif action_id == hash("left") and action.pressed then
		sprite.play_flipbook("#sprite", "walk")
		self.left= true
		self.right=false
	elseif action_id == hash("touch") and action.pressed then
		sprite.play_flipbook("#sprite","attack",anim_done)
	
	end

My game object is keeps play “attack” animation when I click.

Sorry for bothering too much

Is your attack animation set to loop forward in the atlas?

I fixed it to once forward but I still have issue playing idle animation after that once forward attack animation ends.

do you have an animation called “idle” in your atlas?

when I changed model_animation_done from your earlier reply to animation_done, it started to work!
Thank you al for the advice.

Oops! you are right. The name of the function was wrong in my example. I’ll change it.

Although I haven’t used this module, I did notice that it’s available in the Asset Portal: https://defold.com/assets/deftimeline/

Description: Easy way to make animations play in sequence.

Yes, but it regards animating properties - it ould be however easily expanded to also animate flipbooks - additionally we can animate a cursor of flipbook animation :wink:

If we talk about libraries for sequence animations, I’ll recommend this small one:

It’s allow you write animations like:

sequence.run_once(function()
  -- Run animations one after another
  sequence.sprite_play_flipbook(url, id)
  sequence.sprite_play_flipbook(url, another_id)
end)

4 Likes

Instead of thinking about playing the animations in sequence, have you considered modeling the states of the character? The code below is just an example of the idea (not tested), but it’s a very useful pattern.

local STATE_IDLE = "IDLE"
local STATE_ATTACK = "ATTACK"
local STATE_WALK = "WALK"

local state = STATE_IDLE

function set_state_idle()
	state = STATE_IDLE
	sprite.play_flipbook("#sprite", "idle")
end

function set_state_walk(direction)
	state = STATE_WALK
	sprite.play_flipbook("#sprite", "walk")
    sprite.set_hflip(direction < 0)
end

function set_state_attack()
	state = STATE_ATTACK
	sprite.play_flipbook("#sprite", "attack", function()
		-- go to idle.  could also have conditional logic to go to walking
		set_state_idle()
	end)
end

function on_input(self, action_id, action)
	if action_id == hash("right") and action.pressed then
		set_state_walk(1)
	elseif action_id == hash("left") and action.pressed then
		set_state_walk(-1)
	elseif action_id == hash("right") or action_id == hash("left") and action.released then
		set_state_idle()
	elseif action_id == hash("touch") and action.pressed then
		set_state_attack()
	end
end

This questions shows that there are many different ways of achieving basically the same thing. I prefer the answer by Insality if you need to chain flipbook animations. It’s very conveninent to not have to nestle callbacks. Coroutines to the rescue!

Some additional links with related examples: