So now we have a game screen and a main menu…. How do we tie them all together? Or how about splitting our game up into different scenes or levels? This part of working with Defold isn’t entirely obvious, but don’t worry, we are going to cover the process in this chapter, but it’s going to require a fair bit of surgery on our code. So let’s get our scalpels ready.
Instead of loading into main.collection, what we instead need to do is create a new collection that is going to be our traffic cop of sorts. Through the magic of collection proxy, the loader will switch between the different collections in our game.
What we need to do is create a new collection. Create a folder called loader, and inside of that folder create a new collection also named loader. While we are here, let’s also create a new script called… you guessed it… loader! Now open up loader.collection and create a Game Object inside that collection. Now we are going to put proxy’s to work. Right-click your game object and select Add Component->Collection Proxy.
Now name it main, then select the collection, obviously pick main.collection in the Collection field.
Now repeat this process for mainmenu, naming it mainmenu and mainmenu.collection instead. Finally, add the loader.script to this game object as well. In the end, it should look like:
Next, select the root node of the loader collection and set the name to loader.
Finally, we need to change the Main Collection in the bootstrap section of game.project to load the loader on startup.
Now time for the code… open loader.script and enter the following code:
local function load_menu(self) msg.post("go#mainmenu", "load") msg.post("go#mainmenu", "enable") end local function unload_menu(self) msg.post("go#mainmenu","unload") end local function load_main(self) msg.post("go#main", "load") msg.post("go#main", "enable") end function init(self) msg.post(".", "acquire_input_focus") load_menu(self) end function on_message(self, message_id, message, sender) if message_id == hash("start_game") then unload_menu(self) load_main(self) end end
One again its message passing we use to switch collections, by calling load then enable on the collection we want to be displayed. Also when we load up we start by loading the menu by default.
Now, let’s go back to mainmenu.gui_script and add some code so we can actually do something when the user picks a menu item.
function init(self) msg.post(".", "acquire_input_focus") end function on_input(self, action_id, action) if(action_id == hash("touch") and action.released == true) then local textBegin = gui.get_node("textBeginGame") if(gui.pick_node(textBegin,action.x,action.y)) then msg.post("loader:/go#loader", "start_game") end end if(action_id == hash("touch") and action.released == true) then local textExit = gui.get_node("textExitGame") if(gui.pick_node(textExit,action.x,action.y)) then msg.post("@system:", "exit", {code = 0}) end end end
Here we are checking for touches (note the touch event is created by default for us in the game.input_binding, with a left-click being the same as a single finger touch. We check to see if the location they touched contains our “textBeginGame” node, if so, we call to the loader, sending the message start_game. If on the other hand, we clicked the exit game link we exit the game by sending an exit message to @system, a special built in URL for system calls.
TADA, now we have a working multi-screen “game”, with animations, music, particle effects, and physics. Now take what you’ve learned and go make something that’s not complete crap! 😉
Good luck and happy Defolding.