SCRIPT DOESN’T EXECUTE AS INTENDED USING GUI.ANIMATE()
No errors today to use in the heading.
This is going to be something stupid, I know it.
I’ve written a game object to display instructions and controls at the beginning of every level via a series of sprites and animations. It may be skipped as well as accessed through the pause menu.
It doesn’t work. It pauses the game while nothing happens until you pause and unpause it yourself.
There is a sequencing I’ve had in mind when designing it:
-
proxy_manager
loads the level
- all game objects initiate
-
level_manager
sends a "pause"
message to everything and a "start"
message to the intro gui (called starter_gui
)
- the
starter_gui
runs through 5 animation functions and a countdown timer or until being skipped and sends a resume
message to the level_manager
- the game proceeds as intended
Using debugging pprint()
functions, the desired log ought to look a bit like:
Desired log
INFO:DLIB: SSDP: Started on address xxx.xxx.x.xxx
DEBUG:SCRIPT: Loaded url: [manager:/controller#PRXY_intro]
DEBUG:SCRIPT: Unloaded url: [manager:/controller#PRXY_intro]
DEBUG:SCRIPT: Loaded url: [manager:/controller#PRXY_main]
DEBUG:SCRIPT: Unloaded url: [manager:/controller#PRXY_main]
DEBUG:SCRIPT: Loaded url: [manager:/controller#PRXY_pong]
DEBUG:SCRIPT: Updated all objects in P0N6 with pause_game
DEBUG:SCRIPT: Told starter in P0N6 to initiate starter procedure
DEBUG:SCRIPT: TEXTURES SET
DEBUG:SCRIPT: STARTER ANIMATION 1
DEBUG:SCRIPT: STARTER ANIMATION 2
DEBUG:SCRIPT: STARTER ANIMATION 3
DEBUG:SCRIPT: STARTER ANIMATION 4
DEBUG:SCRIPT: STARTER ANIMATION 5
DEBUG:SCRIPT: STARTER COUNTDOWN FINISHED
DEBUG:SCRIPT: STARTER COMPLETE
DEBUG:SCRIPT: Updated all objects in P0N6 with hash: [resume_game]
INFO:DLIB: SSDP: Done on address xxx.xxx.x.xxx
Instead I get this
INFO:DLIB: SSDP: Started on address xxx.xxx.x.xxx
DEBUG:SCRIPT: Loaded url: [manager:/controller#PRXY_intro]
DEBUG:SCRIPT: Unloaded url: [manager:/controller#PRXY_intro]
DEBUG:SCRIPT: Loaded url: [manager:/controller#PRXY_main]
DEBUG:SCRIPT: Unloaded url: [manager:/controller#PRXY_main]
DEBUG:SCRIPT: Loaded url: [manager:/controller#PRXY_pong]
DEBUG:SCRIPT: Updated all objects in P0N6 with pause_game
DEBUG:SCRIPT: Told starter in P0N6 to initiate starter procedure
DEBUG:SCRIPT: TEXTURES SET
DEBUG:SCRIPT: STARTER ANIMATION 1
-- the logs stop here until I press 'Escape'
DEBUG:SCRIPT: STARTER COMPLETE
DEBUG:SCRIPT: STARTER COUNTDOWN FINISHED
DEBUG:SCRIPT: STARTER SKIPPED SUCCESSFULLY
DEBUG:SCRIPT: Updated all objects in P0N6 with hash: [resume_game] --> pressing escape skips the intro and so resumes the game
DEBUG:SCRIPT: Updated all objects in P0N6 with hash: [pause_game] --> pressing escape also pauses the game, which will be a future bug when stuff actually works
INFO:DLIB: SSDP: Done on address xxx.xxx.x.xxx
Normally I’d currate the code to be readable on the blog, but honestly I have no idea what messes up, and I’ve been banging my head at this for a few days so…
The entire `starter_.gui_script`
local hide_all
local set_textures
local anim1
local anim2
local anim3
local anim4
local anim5
local skip_explanation
local countdown
local finish_it
--[[
TO DO:
* make a messaging system to define textures -- CHECK
* make mock/final textures at least for debugging purposes -- CHECK
* make a countdown function, -- CHECK
* make a function that displays the gui and hides it appropriately -- CHECK
* make all the animation and skip functionality -- CHECK
* add pause menu "show hints" button that brings the gui back up. -- CHECK
* make it work
]]--
function init(self)
msg.post(".", "acquire_input_focus")
-- this makes coding the rest easier-ish
self.nodes = {
TIPS = gui.get_node("tips"),
TIPS_CHILD = {gui.get_node("explanation"), gui.get_node("controls")},
CONTROLS = {gui.get_node("p1_controls"), gui.get_node("p2_controls")},
CNTDWN = gui.get_node("countdown"),
CNTDWN_TXT = gui.get_node("countdown_txt"),
SKIP = gui.get_node("skip_prompt"),
SKIP_TXT = gui.get_node("skip_prompt_txt"),
}
-- this list will make displaying the correct items easy per level
self.textures = {
CONTROLS = {},
EXAMPLES = {},
}
self.collection = msg.url().socket --> first message ought to define the current level collection.
self.level_manager = msg.url("level_manager") --> the full url returns an error for some reason???
hide_all(self)
end
function on_message(self, message_id, message, sender)
if message_id == hash("start") then
--self.collection = sender.socket
set_textures(self)
hide_all(self)
--now do some actual stuff
anim1(self)
end
end
function on_input(self, action_id, action)
if action.released then
if action_id == hash("lefCtrl")
or action_id == hash("riCtrl")
or action_id == hash("ctrX")
or action_id == hash("enter")
or action_id == hash("pause") then
skip_explanation(self)
end
end
end
function hide_all(self)
for i, n in pairs(self.nodes) do
if type(n) == "table" then
for ii, nn in pairs(n) do
gui.set_enabled(nn, false)
end
else
gui.set_enabled(n, false)
end
end
end
function set_textures(self, cllction, ctrl_p1, ctrl_p2)
cllction = cllction or "default"
ctrl_p1 = ctrl_p1 or "default_controls"
ctrl_p2 = ctrl_p2 or "default_controls"
--get textures
self.textures.EXAMPLES = {
cllction .. "_starter",
cllction .. "_anim"
}
self.textures.CONTROLS = {
ctrl_p1,
ctrl_p2
}
--set textures.
-- gui.set_texture --> set the atlas
-- gui.play_flipbook --> set specific sprite or animation
gui.play_flipbook(self.nodes.TIPS_CHILD[1], self.textures.EXAMPLES[1])
gui.play_flipbook(self.nodes.CONTROLS[1], self.textures.CONTROLS[1])
gui.play_flipbook(self.nodes.CONTROLS[2], self.textures.CONTROLS[2])
pprint("TEXTURES SET")
end
--animation time
function anim1(self)
local node = self.nodes.TIPS_CHILD[1]
local now_colour = gui.get_color(node)
now_colour.w = 0
local to_colour = now_colour
to_colour.w = 1
gui.set_enabled(node, true)
gui.set_color(node, now_colour)
gui.animate(node, gui.PROP_COLOR, to_colour, gui.EASING_LINEAR, 2.5, 0, anim2, gui.PLAYBACK_ONCE_FORWARD)
pprint("STARTER ANIMATION 1")
end
function anim2(self)
pprint("STARTER ANIMATION 2 - beginning")
local node = self.nodes.TIPS_CHILD[1]
gui.set_enabled(node, true)
gui.play_flipbook(node, self.textures.EXAMPLES[2], anim3)
pprint("STARTER ANIMATION 2 - end")
end
function anim3(self)
local node = self.nodes.TIPS_CHILD[1]
local now_colour = gui.get_color(node)
now_colour.w = 1
local to_colour = now_colour
to_colour.w = 0
gui.set_enabled(node, true)
gui.set_color(node, now_colour)
gui.animate(node, gui.PROP_COLOR, to_colour, gui.EASING_LINEAR, 2.5, 0, anim4, gui.PLAYBACK_ONCE_FORWARD)
pprint("STARTER ANIMATION 3")
end
function anim4(self)
gui.set_enabled(self.nodes.TIPS_CHILD[1], false)
local node = self.nodes.TIPS_CHILD[2]
gui.set_enabled(node, true)
local now_colour = gui.get_color(node)
now_colour.w = 0
gui.set_color(node, now_colour)
local to_colour = now_colour
to_colour.w = 1
gui.animate(node, gui.PROP_COLOR, to_colour, gui.EASING_LINEAR, 2.5, 0, anim5, gui.PLAYBACK_ONCE_FORWARD)
pprint("STARTER ANIMATION 4")
end
function anim5(self)
gui.set_enabled(self.nodes.TIPS_CHILD[1], false)
local node = self.nodes.TIPS_CHILD[2]
gui.set_enabled(node, true)
local now_colour = gui.get_color(node)
now_colour.w = 1
gui.set_color(node, now_colour)
local to_colour = now_colour
to_colour.w = 2
gui.animate(node, gui.PROP_COLOR, to_colour, gui.EASING_LINEAR, 2.5, 5, countdown, gui.PLAYBACK_ONCE_FORWARD)
pprint("STARTER ANIMATION 5")
end
--skip first part
function skip_explanation(self)
local anmtbls = {
self.nodes.TIPS_CHILD[1],
self.nodes.TIPS_CHILD[2],
}
for ind, node in pairs(anmtbls) do
gui.cancel_animation(node, gui.PROP_COLOR)
end
gui.cancel_flipbook(anmtbls[2])
countdown(self)
pprint("STARTER SKIPPED SUCCESSFULLY")
end
-- countdown time
function countdown(self)
-- countdown duration
local tmr = 3 --seconds
local node = self.nodes.CNTDWN
local node_txt = self.nodes.CNTDWN_TXT
gui.set_enabled(node, true)
gui.set_enabled(node_txt, true)
gui.set_text(self.nodes.CNTDWN_TXT, tostring(tmr))
for i = tmr, 0, -1 do
timer.delay(1, false, function (obj, handle, elapsed)
--print("Executed timer from: " .. tostring(obj) .. ", with handle: " .. tostring(handle) .. " after: " .. tostring(elapsed) .. "s")
end)
gui.set_text(node_txt, tostring(i))
end
finish_it(self)
pprint("STARTER COUNTDOWN FINISHED")
end
-- and end
function finish_it(self)
msg.post(self.level_manager, "resume_game")
hide_all(self)
pprint("STARTER COMPLETE")
end
The entire `level_manager.script`
local update_all
local get_positions
local reset_positions
local restart_game
function init(self)
msg.post(".", "acquire_input_focus")
self.objects = {
"/ball",
"/player1",
"/player2",
}
self.positions = get_positions(self)
msg.post(".", "show_hints")
end
function on_message(self, message_id, message)
if message_id == hash("pause_game") then
update_all(self, message_id)
elseif message_id == hash("resume_game") then
update_all(self, message_id)
elseif message_id == hash("show_hints") then
update_all(self, "pause_game")
local receiver = msg.url("starter")
msg.post(receiver, "start")
print("Told starter in P0N6 to initiate starter procedure")
--pprint(receiver)
elseif message_id == hash("restart_game") then
restart_game(self)
else
-- nothing
end
end
function update_all(self, message_id)
for i, t in pairs(self.objects) do
msg.post(t, message_id)
pprint("Updated all objects in P0N6 with " .. tostring(message_id))
end
end
function get_positions(self)
local positions = {}
for i, t in pairs(self.objects) do
local pos = go.get_position(t)
positions[i] = pos
end
return positions
end
function reset_positions(self)
for i, t in pairs(self.positions) do
go.set_position(t, self.objects[i])
end
print("Reset all objects' positions in P0N6")
end
function restart_game(self)
reset_positions(self)
msg.post("ball", "restart_game", {time = 3})
print("Told ball in P0N6 to reset.")
end
while we’re at it, the level_manager
also fails to reset positions of game objects in the function reset_positions(self)
and I do not understand why. Is there any limitations or quirks on manipulating other objects’ positions?
function reset_positions(self)
for i, t in pairs(self.positions) do
go.set_position(t, self.objects[i])
end
print("Reset all objects' positions in P0N6")
end
If anyone has the time, will and ability to check the code for why it doesn’t work (other than poor coding practices and ‘it’s bad’) I would greatly appreciate. This is I thikn the last task I want to complete before moving on to building new world collections and mini-games.