Switching Scenes

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.

Creating collection proxy

Now name it main, then select the collection, obviously pick main.collection in the Collection field.

Setting the main collection to the proxy

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:

loader final outline

Next, select the root node of the loader collection and set the name to loader.

Pasted Graphic 85

Finally, we need to change the Main Collection in the bootstrap section of game.project to load the loader on startup.

Pasted Graphic 86

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.

Scroll to Top