Change sprites between animations in cycle (SOLVED)

Hey! Can anyone help me pls?

I have a path (table with coords). GO is moving through that path randomly changing sprites on every step.

Problem is that I get only one sprite change from first to last.

for step =1, 10 do
	moveto = path[step].coords
	go.animate ('.', "position", go.PLAYBACK_ONCE_FORWARD, moveto, go.EASING_LINEAR, speed, duration, changeDir)
end

function changeDir ()
	msg.post ("#character", "play_animation", {id = hash("sprite_" .. randomNumber)})
end

This will loop through all 10 steps immediately and make 10 go.animate() calls immediately. It will however only complete the 10th go.animate() call. The rest of them should be ignored.

I assume what you really want is to move to the next step when the first animation has completed?

Store a step counter somewhere and increment and get next moveto value when the go.animate() callback is invoked.

1 Like

britzl Should it be some kind of on_update function? Cause I’ve tried to set a pause until callback from animation is true, and it didn’t help.

you can do it like

local step = 0
local changeDir

changeDir = function()
    if step < NUMBER_OF_STEPS then
        go.animate(..., changeDir) --call itself in go.animate callback
        step = step + 1
    end
end

Hmmmm… not sure how that supposed to work. O_o Pathfinding is just stopped working, and sprite still changes only once.

Where that msg. post should be?

@kidkiedis and @vergil12345678

go.animate() does not block code execution when called. It will start the animation but your Lua code will immediately execute the next line.

This means that any for loop where you call go.animate() in every iteration will basically call go.animate() 10 times in a row without waiting for the animation to finish.

This means that you can’t use a for-loop *

We need some other construct if we want the animation to go through each point in the path. The go.animate() function has a convenient callback function that we can use for this purpose. We start the first animation to the first step through the path. When we get the callback we take the next step, until the path has reached its end. Something like this:

local take_step = nil

take_step = function(self)
	self.step = self.step + 1
	if self.step > #self.path then
		return
	end
	moveto = self.path[self.step].coords
	go.animate ('.', "position", go.PLAYBACK_ONCE_FORWARD, moveto, go.EASING_LINEAR, speed, duration, take_step)
end

function init(self)
	self.path = {}
	self.step = 0
	-- calculate path somehow
	take_step(self)
end

Or if we’re allowed to remove steps from the path:

local take_step = nil

take_step = function(self)
	local p = table.remove(self.path, 1)
	if not p then
		return
	end
	moveto = p.coords
	go.animate ('.', "position", go.PLAYBACK_ONCE_FORWARD, moveto, go.EASING_LINEAR, speed, duration, take_step)
end

function init(self)
	self.path = {}
	-- calculate path somehow
	take_step(self)
end

*=You can if you use a coroutine but let’s ignore that for now

4 Likes

Thanks! I’ll try that right now.
Just to be sure, I have small syntax questions…

take_step = function (self) …
#self.path
are just another way to say
function take_step (self) …
table.maxn(path)
but just for a spawned object?

Sry, I know that I should’ve check Lua syntax manual…

These are not equivalent. The length operator returns the length of the array part of a table. The length is the number of sequential keys from 1 and upwards.

table.maxn() gives the highest numerical index in your table.

local t = {
	[0] = "zero",
	[1] = "a",
	[2] = "b",
	[3] = "c",
	[4] = "d",
	[5] = nil,
	[6] = "f",
	[9999] = "yoda",
}

print(#t) -- 6
print(table.maxn(t)) -- 9999

Note that while the length operator returns a length of 6 you will get into trouble if iterating using ipairs() which will stop at the first nil value (ie key 5)

1 Like

Oh… got it! I’am using maxn all the way just with an array of tables. Now I see why it works for me.

Looks like that take_step function finally works, still making some tweaks, but seems like it did a job. Huuge thanks as always! :upside_down_face: