Animation - Mashing attack button (SOLVED)


#1

I have read on the post stated above that animation using play_animation will always play to the end unless another animation started. Now, I pressed the attack button that plays attack animation once, it will play the animation to the end. Okay, if I pressed the attack button more than twice, the animation did not play to the end and it play only the early one. How to solve this? Thank you


#2

Not sure what you’re after here?
Do you want the animation to play to the end, even though you call a new play_animation?
If so, you can have a flag saying you’re currently playing an animation. E.g.

self.is_attack_playing = true

You can then use that to avoid playing a new animation while the first one is playing.

And when the animation is done, you reset the flag.


#3

yes i want the animation to play to the end. But i do not know how to to avoid play a new animation while the first one is playing. I already read on the animation_done, but i can’t figure out how to implement it


#4

the attack animation restarted when i pressed the attack button twice.


#5

Typing on a phone.

if self.attacking then return end
self.attacking = true
sprite.play_flipbook("#mysprite", "attack", function()
    self.attacking = false
end)

#6

it returns this following error:
Compilation failed: ‘)’ expected (to close ‘(’ at line 98) near ‘self’


#7

You need to put a ) behind the last end.

if self.attacking then return end
self.attacking = true
sprite.play_flipbook("#mysprite", "attack", function()
	self.attacking = false
end)

#8

thank you, no more error now, however it did not play attack animation. I put the code on the update. While on the input, i put the self.attacking = true.

if action.pressed then
-elseif action_id == hash(“attack”) then
self.attacking = true
end


#9

Put all of the code in on_input


#10

thank you so much, it works now. You are the best :grinning: :+1:


#11

I am wondering, why it is not working after i pressed other animation? for an example, after i play the other animation like walking, then if i press attack again it does not play? I am sorry for asking a lot.


#12

It’s probably because you play another animation which will cause the callback for the first to not get called and self.attacking remains true


#13

You can also check out my struggle with similar problem and a very helpful post here by @kashyapaayush32


#14

thank you so much. I will check it. :+1:


#15

okay thank you, I will improve on it


#16

hello, i still can not get it work. I am sorry. The attack animation did not played after walking animation is played. :tired_face:


#17

Can you share your code here?


#18

thank you for your response. When i check at the input, the attack id is received, it knows that the attack function are being launched. But the animation did not.

local ATTACK = hash("attack")
ATTACKS = {1, 2, 3, 4}

local function play_attack_anim(self, index)
	if not (self.anim == ATTACKS[index]) then 
		msg.post("#sprite", "play_animation", {id = hash("attack"..ATTACKS[index])})
		self.anim = ATTACKS[index]
		print("play animation")
	end
end

local function check_attacks(self)
	if self.completed_attacks < self.scheduled_attacks then
		play_attack_anim(self, self.completed_attacks % 3 + 1)
	elseif self.completed_attacks == self.scheduled_attacks then
		self.completed_attacks = 0
		self.scheduled_attacks = 0
	end
end

local function play_animation(self, animation)
	if self.current_animation ~= animation then
		self.current_animation = animation
		sprite.play_flipbook("#sprite", animation)
		print(animation)
	end
end

function init(self)
	--acquire input
	msg.post(".", "acquire_input_focus")

	self.scheduled_attacks = 0
	self.completed_attacks = 0
	
	self.anims = nil

	self.direction = vmath.vector3(0, 0, 0)
end

function final(self)
end

function update(self, dt)
	if self.completed_attacks == 0 and self.scheduled_attacks  == 0 then
		play_attack_anim(self, 4)
	end
end

function on_message(self, message_id, message, sender)
	if message_id == hash("animation_done") then
		self.completed_attacks = self.completed_attacks + 1
		print("attack animation complete")
	end
end

function on_input(self, action_id, action, animation)
	if action_id == ATTACK and action.pressed then
		check_attacks(self)
		self.scheduled_attacks = self.scheduled_attacks + 1
		print(self.scheduled_attacks, self.completed_attacks)
	end

	if action.pressed then

		if action_id == hash("left") then
			self.direction.x = -1
			msg.post("#sprite", "play_animation", {id = hash("move-left")})
			print("left animation complete")
		elseif action_id == hash("right") then
			self.direction.x = 1
			msg.post("#sprite", "play_animation", {id = hash("move-right")})
			print("right animation complete")
		end
	elseif action.released then

		if action_id == hash("left") then
			self.direction.x = 0
			if vmath.length(self.direction) == 0 then msg.post("#sprite", "play_animation", {id = hash("move-left")}) end
		elseif action_id == hash("right") then
			self.direction.x = 0
			if vmath.length(self.direction) == 0 then msg.post("#sprite", "play_animation", {id = hash("idle-right")}) end
		end
	end
end

function on_reload(self)
	
end

#19

Add three " " " around your code, and it will display properly. Right now, all indentation and syntax highlighting got lost, which makes it very hard to read.


#20

okay i use the preformatted text to display the code.