Moving Game Object in a loop on a timer (SOLVED)

I’m trying to have an NPC walk back and forth from point A to point B with a 2 second pause in between. I have a working timer module from @britzl that will print when I build.

Here is the code I have right now that doesn’t seem to be working with the timer at all.

local timer = require ("npc.timer")


function reload(self, dt)		
	local pos = go.get_position()
		if pos.x < 520 then
			pos.x = pos.x + 1
			go.set_position(pos)
		end
		if pos.x > 440 then
			pos.x = pos.x - 1
			go.set_position(pos)
		end
end


function init(self)
	timer.seconds(2, reload)
end


function final(self)
	timer.cancel_all()
end


function update(self, dt)
	timer.update(dt)
end

Appreciate any assistance in getting this to work.

Hi! I recently used go.animate and some custom easing to do something similar. So whilst I can’t help you with your problem, I can explain another way which may be quicker.

Basically, it’s animation, but at some points, a section of the easing curve is 0, so there is no movement.

local table = { 0, 1, 1, 0, 0, -1, -1, 0}
local pauses = vmath.vector(table) 
go.animate("leg1", "position.y", go.PLAYBACK_LOOP_PINGPONG, 13, pauses, 4, 0)

That would be short pause, move to the right, pause, move to the left, short pause. The two shorts pauses (the 0 at the start and the end of the table) make a long pause altogether, so the animation loops perfectly if you use pingpong.

Awesome. Thanks.

That actually helped me get it working.

I’m having another hiccup now though, that perhaps belongs in another thread. But I’ll ask here anyway. I have tile animation sequences attached to my sprite: walkRight, walkLeft, idleRight, idleLeft. I can get one to play while the game object is moving to the right and another to play while it’s moving to the left. But I want to see it move to the right with the walk animation and when it reaches the destination change to the idle state.

I’m not sure how to do that. Here is my code below.

local timer = require "npc.timer"
local anim = require "npc.anim"



function reload(self, dt)		

	local pos = go.get_position()
	if pos.x < 520 then
		go.animate(go.get_id(), "position.x", go.PLAYBACK_ONCE_FORWARD, 520, go.EASING_LINEAR, 2, 0)
		anim.play_animation("walkRight")
		--Want to transition sprite animation sequence here.
		anim.play_animation("idleRight")
	elseif pos.x > 440 then	
		go.animate(go.get_id(), "position.x", go.PLAYBACK_ONCE_FORWARD, 440, go.EASING_LINEAR, 2, 0)
		anim.play_animation("walkLeft")
		--Want to transition sprite animation sequence here.
		anim.play_animation("idleLeft")
	end

	print("NOW")
	
end


function init(self)
	timer.repeat_seconds(4, reload)
end


function final(self)
	timer.cancel_all()
end


function update(self, dt)
	timer.update(dt)
end

I’m also pulling in a anim.lua file that looks like this:

local M ={}

local current_anim

function M.play_animation(anim)
	if anim == current_anim then return end
	msg.post("#sprite", "play_animation", { id = hash(anim) })
	current_anim = anim
end


return M

Thanks again for the assist.

The way to do this is to have a callback message when the animation is done,

try here http://www.defold.com/manuals/animation/

Yep, you can use the complete_function from go.animate() to change to the idle transition once you reach the destination.

Perfect. Thanks, everyone. All of these answers were super simple and easy to implement. Here’s what I ended up with:

function reload(self, dt)		

	local function right_done(self)
		anim.play_animation("idleRight")		
	end
	
	local function left_done(self)
		anim.play_animation("idleLeft")
	end
	
	local pos = go.get_position()
	
	if pos.x < 520 then
		go.animate(go.get_id(), "position.x", go.PLAYBACK_ONCE_FORWARD, 520, go.EASING_LINEAR, 2, 0, right_done)
		anim.play_animation("walkRight")
	elseif pos.x > 440 then	
		go.animate(go.get_id(), "position.x", go.PLAYBACK_ONCE_FORWARD, 440, go.EASING_LINEAR, 2, 0, left_done)
		anim.play_animation("walkLeft")
	end	
end
1 Like

I see that this is an older thread, but I’d like to toss a bump in here if anyone was able to benefit from this thread and might be able to potentially help me out. I see that two lua scripts were referenced, anim and timer. Were they altered in any form as I have attempted to recreate this scenario on my own project and I’m not getting any form of response from the NPC that I’m trying to animate. As usual, thank you in advance for any and all help.

Try something like this (typed on a phone, bound to contain an error or two):

function init(self)
    msg.post("#", "move_left")
end

function on_message(self, message_id, message, sender)
    if message_id == hash("move_left") then
        go.animate(".", "position", go.PLAYBACK_ONCE_FORWARD, go.get_position() - vmath.vector3(200, 0, 0), go.EASING_LINEAR, 2, 0, function()
            msg.post("#", "move_right")
        end)
        sprite.play_flipbook("#mysprite", "moveLeft")
    elseif message_id == hash("move_right") then
        -- same as above but opposite direction
    end
end
3 Likes

I have movement! Thank you very much. Thats a good base for me to start working from. Thank you as always for being so helpful!

2 Likes