Maybe I’m misunderstanding coroutines but I’m trying to have it so several different objects can be animated simultaneously and saw the post about coroutines, but the question is how exactly do you activate one in a funciton?
local BOOKSHELF_POSITIONS_X = {480, 960,1440}
local function bookshelf_animate(url, property, playback, to, easing, duration, delay, playback)
local co = coroutine.running()
assert(co, "You must call this function from within a coroutine")
go.animate(url, property, playback, to, easing, duration, delay, function()
coroutine.resume(co)
end,playback)
coroutine.yield()
end
coroutine.wrap(function()
bookshelf_animate("/bookshelf_1", "position.x", go.PLAYBACK_ONCE_FORWARD, BOOKSHELF_POSITIONS_X[1], go.EASING_INQUART, 1)
bookshelf_animate("/bookshelf_2", "position.x", go.PLAYBACK_ONCE_FORWARD, BOOKSHELF_POSITIONS_X[2], go.EASING_INQUART, 1)
bookshelf_animate("/bookshelf_3", "position.x", go.PLAYBACK_ONCE_FORWARD, BOOKSHELF_POSITIONS_X[3], go.EASING_INQUART, 1)
end)()
local function set_book_behind_bookshelf()
BOOKSHELF_POSITIONS_X = minigames.shuffle(BOOKSHELF_POSITIONS_X)
-- how to call the coroutine?
end
In your code the animations will be run one after the other. If you don’t want this then why bother with a coroutine to synchronize things? You might as well call go.animate() three times.
I think the problem here is that you saw the post about coroutines, but you don’t need that here.
Look at this example to see how to chain animation.
local function mournloop(self) --this animation happens when it is triggered
go.animate("face", "position.x", go.PLAYBACK_LOOP_PINGPONG, 5, go.EASING_INOUTQUAD, 1.2)
end
local function mourn(self) --these animations happen first, and they happen at the same time
go.animate("body", "euler.z", go.PLAYBACK_ONCE_FORWARD, -5, go.EASING_OUTSINE, 1)
go.animate("face", "position.x", go.PLAYBACK_ONCE_FORWARD, 11, go.EASING_OUTSINE, 1,0, mournloop) --this animation triggers the mournloop function when it has finished.
end
Ah I see, thanks. The reason why I thought I might have needed coroutines was because I was trying to program the shell game or cups and ball game, so I thought I would’ve needed to find a way to play the ‘cups’ animating simultaneously (i.e. swapping positions).
There’s something I’m slightly confused about, why does it only swap the positions of the bookshelves once? From what I’m debugging it’s running what’s inside of the timer.delay function first, then checking whether the timer’s still active, so am I supposed to reverse the order of how they’re called? But then how would you create the timer?
local BOOKSHELF_POSITIONS_X = {480, 960,1440}
local function set_book_behind_bookshelf()
BOOKSHELF_POSITIONS_X = minigames.shuffle(BOOKSHELF_POSITIONS_X)
go.animate("/bookshelf_1", "position.x", go.PLAYBACK_ONCE_FORWARD, BOOKSHELF_POSITIONS_X[1], go.EASING_INQUART, 1)
go.animate("/bookshelf_2", "position.x", go.PLAYBACK_ONCE_FORWARD, BOOKSHELF_POSITIONS_X[2], go.EASING_INQUART, 1)
go.animate("/bookshelf_3", "position.x", go.PLAYBACK_ONCE_FORWARD, BOOKSHELF_POSITIONS_X[3], go.EASING_INQUART, 1)
end
local function bookshelf_cancel_swap()
go.cancel_animations("/bookshelf_1")
go.cancel_animations("/bookshelf_2")
go.cancel_animations("/bookshelf_3")
end
function init(self)
book_index = math.random(1,3)
bookshelf_swap_pos = timer.delay(5, false, function()
timer.cancel(bookshelf_swap_pos)
bookshelf_cancel_swap()
end)
while timer.trigger(bookshelf_swap_pos) do
set_book_behind_bookshelf()
end
minigames.set_countdown_timer()
end
I’m not entirely sure what you are trying to do. That while loop doesn’t look ok for instance. You really shouldn’t have any blocking loops like that anywhere in your code.
I should’ve done that from the beginning, that was my bad. So I’m trying to replicate the shell game or the cups and ball game. Right now I’m trying to figure out how to handle the cups moving, or in my case bookshelves, my idea was to shuffle the positions then pass that into each bookshelf and then animate them simultaneously. This should start when the collection is initalialised and should only last for a couple of seconds, that’s the reason why I was thinking of using a while loop and a timer, the timer would cancel the animations so the swapping positions wouldn’t happen and while the timer was active the swapping positions would occur.
Am I going about the logic in the wrong or unoptimal way?
local BOOKSHELF_POSITIONS_X = {480, 960,1440}
-- shuffle/swap the positions of the bookshelves once
-- send a message when animation has finished
local function shuffle_bookshelves()
BOOKSHELF_POSITIONS_X = minigames.shuffle(BOOKSHELF_POSITIONS_X)
go.animate("/bookshelf_1", "position.x", go.PLAYBACK_ONCE_FORWARD, BOOKSHELF_POSITIONS_X[1], go.EASING_INQUART, 1, 0)
go.animate("/bookshelf_2", "position.x", go.PLAYBACK_ONCE_FORWARD, BOOKSHELF_POSITIONS_X[2], go.EASING_INQUART, 1, 0)
go.animate("/bookshelf_3", "position.x", go.PLAYBACK_ONCE_FORWARD, BOOKSHELF_POSITIONS_X[3], go.EASING_INQUART, 1, 0, function()
msg.post("#", "bookshelves_shuffled")
end)
end
function init(self)
self.shuffle_count = 3 -- number of times to shuffle
shuffle_bookshelves()
end
function on_message(self, message_id, message, sender)
-- message sent when the bookshelves have been shuffled once
if message_id == hash("bookshelves_shuffled") then
-- decrease the shuffle count and check if we should shuffle more or if we are done
self.shuffle_count = self.shuffle_count - 1
if self.shuffle_count > 0 then
shuffle_bookshelves()
else
print("Bookshelves are shuffled!")
end
end
end
Is it possible to exclude certain values from shuffling? What I mean by that is that the positions could be shuffled but then have the same values as before, so {440, 960, 1440} shuffled could still be {440, 960, 1440}, at least from what I notice because although I’ve set my shuffle_count to be 10 sometimes it looks like it doesn’t actually shuffle at all. So I think the key would be n can’t be equal to k.
function M.shuffle(t)
for n=1,#t do
local k = math.random(#t)
t[n], t[k] = t[k], t[n]
end
return t
end
Hm, now I’m curious as to why even though I’m clicking on the right bookshelf it’s still considered wrong. I’m passing the right id and the right index, so I’m confused.
-- minigame script
function on_message(self, message_id, message, sender)
if message_id == hash("check_book_index_location") then
if message.bookshelf_id == "/bookshelf_1" and book_index == 1 or message.bookshelf_id == "/bookshelf_2" and book_index == 2 or message.bookshelf_id == "/bookshelf_3" and book_index == 3 then
label.set_text("#label", "RIGHT")
msg.post("#", "found_book", {correct_book_location = true})
else
label.set_text("#label", "WRONG")
msg.post("#", "found_book", {correct_book_location = false})
end
end
end
-- bookshelf script
function on_message(self, message_id, message, sender)
if message_id == hash("interact") then
msg.post("/main#find_book_shell_game", "check_book_index_location", { bookshelf_id = go.get_id()})
end
end