How to make simple animation controller for rogue like game?

Hi, all!
I’m new with Defold and trying to make game Similar to Hyper Light Drifter.
Now i’m making run and idle animation for my hero.
So, I can’t find simple way how to manage my animations while I control hero by WASD keys.
My script does not work properly. When I press key animation doesn’t start. It starts only then I release key
I hope someone knows how to make a simple animation controller and can help me.
Many thanks!

function init(self)
	msg.post(".", "acquire_input_focus")
	self.dir = vmath.vector3()
	self.up = 0
	self.down = 0
	self.left = 0
	self.right = 0
	self.speed = 100
	self.horz = 0
	self.vert = 0
	msg.post("test_gun#sprite" , "disable")
end

function final(self)
	msg.post(".", "release_input_focus")
end

function update(self, dt)
	local pos = go.get_position()
	self.dir.x = self.right - self.left
	self.dir.y = self.up - self.down
	if self.dir.x ~= 0 or self.dir.y ~= 0 then
		self.dir = vmath.normalize(self.dir) 
	end
	if self.dir.x == 0 and self.dir.y == 0 then
		if self.horz > 0 then
			msg.post("#sprite", "play_animation", {id = hash("right")})
		else
			msg.post("#sprite", "play_animation", {id = hash("left")})
		end
		if self.vert > 0 then 
			msg.post("#sprite", "play_animation", {id = hash("up")})
		else 
			msg.post("#sprite", "play_animation", {id = hash("down")})
		end
	end
	if self.dir.x > 0 then
		msg.post("#sprite", "play_animation", {id = hash("right_run")})
	elseif self.dir.x < 0 then
		msg.post("#sprite", "play_animation", {id = hash("left_run")})
	end
	if self.dir.y > 0 then
		msg.post("#sprite", "play_animation", {id = hash("up_run")})
	elseif self.dir.y < 0 then
		msg.post("#sprite", "play_animation", {id = hash("down_run")})
	end
	pos = pos + self.dir * self.speed * dt
	go.set_position(pos)
	self.horz = self.dir.x
	self.vert = self.dir.y
end

function on_message(self, message_id, message, sender)

end

function on_input(self, action_id, action)
	if action_id == hash("move_up") then
		if action.pressed then
			self.up = 1
		elseif action.released then
			self.up = 0
		end
	elseif action_id == hash("move_down") then
		if action.pressed then
			self.down = 1
		elseif action.released then
			self.down = 0
		end
	elseif action_id == hash("move_left") then
		if action.pressed then
			self.left = 1
		elseif action.released then
			self.left = 0
		end
	elseif action_id == hash("move_right") then
		if action.pressed then
			self.right = 1
		elseif action.released then
			self.right = 0
		end	
	end
end

function on_reload(self)
    -- Add reload-handling code here
    -- Remove this function if not needed
end

It looks like you’re sending play_animation messages every frame. (I think) this will continuously restart the animation so you’ll be frozen on the first frame.

Try keeping track of which animation is playing and only send the play_animation message when the animation changes.

1 Like

@benjames171 is correct. If you send a “play_animation” message every frame the animation will constantly restart.

You need to keep track of the currently playing animation and only call “play_animation” if another animation than the current one should be played. See this example:


http://britzl.github.io/publicexamples/play_animation/index.html

Thanks for help!
I forget that you have a wonderful set of examples!

1 Like

@britzl In your example, shouldn’t the message in final() be “release_input_focus”? Or does “remove_input_focus” also work?

Oh, you’re right. It should be release_input_focus. Thanks!

2 Likes