A simple Storyboard framework for Corona SDK Part 1

Corona Level: Beginner/Intermediate

Meet Storyboard

If you’re looking to add a layer of organization to your Corona SDK project, you owe it to yourself to embrace the Storyboard module that is available in Corona SDK. While at first the Storyboard module may seem a bit like voodoo, once we take a look behind the curtain, you’ll see that Storyboard is one of your best friends. The key to Storyboard is knowing what part of it you need to use, how to use it, and how to handle a few “gotchas” that you will probably need to deal with at some point.

Creating a Template

I can’t stress enough how important it is to have an empty Storyboard template that you can either integrate into your IDE, or copy and paste per project. The reasons you would do this is because of the fact that Storyboard set up can be a little verbose. Storyboard also has a number of different built in methods and events that we might use. Having the template ready allows us to just drop in what we need in the right place. We should create a template before we move on.

For our template I have copied the current default Corona Storyboard template, which can be found here. I additionally spent a moment or two cleaning up the file to my liking. I generally strip most of the comments, and later I’ll discuss some other things that I always use in every project, so I tend to include them in my scene template as well.

The one important change I have made is adding storyboard.removeAll() to clear the previous scene.

I’ll talk about why we did that a little later.

Create a new file called “scene_template.lua” and copy and paste the following code into it to create our storyboard template:

scene_template.lua

---------------------------------------------------------------------------------
-- SCENE NAME
-- Scene notes go here
---------------------------------------------------------------------------------

local storyboard = require( "storyboard" )
local scene = storyboard.newScene()

-- Clear previous scene
storyboard.removeAll()

-- local forward references should go here --

---------------------------------------------------------------------------------
-- BEGINNING OF YOUR IMPLEMENTATION
---------------------------------------------------------------------------------

-- Called when the scene's view does not exist:
function scene:createScene( event )
  local group = self.view

end

-- Called BEFORE scene has moved onscreen:
function scene:willEnterScene( event )
  local group = self.view

end

-- Called immediately after scene has moved onscreen:
function scene:enterScene( event )
  local group = self.view

end

-- Called when scene is about to move offscreen:
function scene:exitScene( event )
  local group = self.view

end

-- Called AFTER scene has finished moving offscreen:
function scene:didExitScene( event )
  local group = self.view

end

-- Called prior to the removal of scene's "view" (display view)
function scene:destroyScene( event )
  local group = self.view

end

-- Called if/when overlay scene is displayed via storyboard.showOverlay()
function scene:overlayBegan( event )
  local group = self.view
  local overlay_name = event.sceneName  -- name of the overlay scene

end

-- Called if/when overlay scene is hidden/removed via storyboard.hideOverlay()
function scene:overlayEnded( event )
  local group = self.view
  local overlay_name = event.sceneName  -- name of the overlay scene

end

---------------------------------------------------------------------------------
-- END OF YOUR IMPLEMENTATION
---------------------------------------------------------------------------------

-- "createScene" event is dispatched if scene's view does not exist
scene:addEventListener( "createScene", scene )

-- "willEnterScene" event is dispatched before scene transition begins
scene:addEventListener( "willEnterScene", scene )

-- "enterScene" event is dispatched whenever scene transition has finished
scene:addEventListener( "enterScene", scene )

-- "exitScene" event is dispatched before next scene's transition begins
scene:addEventListener( "exitScene", scene )

-- "didExitScene" event is dispatched after scene has finished transitioning out
scene:addEventListener( "didExitScene", scene )

-- "destroyScene" event is dispatched before view is unloaded, which can be
-- automatically unloaded in low memory situations, or explicitly via a call to
-- storyboard.purgeScene() or storyboard.removeScene().
scene:addEventListener( "destroyScene", scene )

-- "overlayBegan" event is dispatched when an overlay scene is shown
scene:addEventListener( "overlayBegan", scene )

-- "overlayEnded" event is dispatched when an overlay scene is hidden/removed
scene:addEventListener( "overlayEnded", scene )

---------------------------------------------------------------------------------

return scene

Building the Scenes

As an exercise, lets set up a simple, common game scene based scenario. I would say that most of the time your simple game project structure will probably end up breaking down to something like this:

  1. Splash scene
  2. Menu scene
  3. Game scene
  4. Results scene

Well that’s easy enough. Duplicate your scene_template.lua four times, renaming them as follows:

scene_splash.lua
scene_menu.lua
scene_game.lua
scene_results.lua

Let’s quickly touch on what each scenes job is:

The Splash scene will be used to show the game title, logo, etc. It will include a “start” button at bare minimum, but could also include others like “help” and “highscore”.

The Menu scene will be where we can select game play related items like level selection, character creation, game options, etc.

The Game scene is where the game will be played out. Your user will be spending most of their time on this scene.

The Results scene is where we display game results, save highscores, retry, quit, etc.

Turning the Key

Since Storyboard is a module of Corona, we need a way to initialize the module and basically “Start ‘er up!” We’ll want to do this is soon as possible so that we can gain access to Storyboard. We will do this through the main.lua file.

The main.lua file is always, without a doubt, the first file that is run by Corona.

With this in mind, it’s the perfect place to start up our Storyboard. We can also do some other helpful actions in the main.lua as well that we will discuss later.

For now, open up or create a new main.lua file and enter the following:

-- main.lua
local storyboard = require( "storyboard" )
storyboard.gotoScene( "scene_splash" )

And with a couple of lines of code we have Storyboard activated, and are on our way to the splash scene (scene_splash.lua) via the Storyboard method storyboard.gotoScene(). At this point Storyboard has control of our splash scene, and that control can always be switched with the gotoScene() method.

Let’s glance at the the hierarchy:

storyboard

We’re all done with main.lua. That was pretty simple. but if you were to run this in your Corona simulator, you’ll most likely be staring at a black screen. Let’s do something about that.

Building the Splash scene

Open up the scene_splash.lua that we created earlier if it’s not already open. At first you might be intimidated by a screen full of methods and events staring at you, but we’ll break it down to what we will use 95% of the time.

The following methods of the scene are the ones we’ll use most:

scene:createScene()
scene:enterScene()
scene:exitScene()
scene:destroyScene()

We’ll talk about a couple other useful ones later on. For now, let’s broadly discuss these main methods we’ll be using.

The createScene() method is where we create any display objects we want on the screen when the scene first starts. Any work we do here happens “off screen” so it’s a good place to get everything visually prepped.

The enterScene() method is where we want to set up more programmatic items like timers, event listeners, kicking off an initialize function, etc. At this point the visual items you set up in createScene() are visible on screen.

The exitScene() is called when we are going to leave this scene, but still have visual elements on screen. This is a good place to remove event listeners, cancel timers and transitions, etc.

The destroyScene() is called after the exitScene() method, and is where any visual items that were added to the scenes view is removed. If you added your visual elements to the scenes view, then you will not need to worry about removing them, that will automatically happen in the destroyScene() function.

What we do need to worry about are any timers, or transitions that are active on any of the display objects.

The Anatomy of a Scene

Before we go any further, lets talk briefly about the anatomy of a scene. A scene is actually made up of two parts. One is the “view” — what the user will see on screen — and the other is the scene “memory” object, which is not visible. The scene “memory” object is what is loaded when you use storyboard.gotoScene(). The scenes “view” is created by you when you add display objects to the scenes view property.

Earlier when we created our storyboard template, we added an additional line of code to the template: storyboard.removeAll(). The reason we do this is because Storyboard in its default mode, will “cache” any scene that has been loaded. Both the scenes “memory” objects and the view objects stick around in the background unless you specifically tell them to do otherwise.

While this is a nice feature of Storyboard, it can create a lot of problems for the beginning Storyboard user. By adding the storyboard.removeAll() after we create our new scene, all previous scenes will be removed from the cache, display objects and all. This should have been the default running mode in my opinion. If a project requires more fine tuned Storyboard memory management, then those parameters should be dealt with on a per project basis. For most small projects the savings in loading speed does not outweigh the general headaches associated with it.

Later on then you feel more comfortable with Storyboard be sure to read up scene purging and scene removal. For now the storyboard.removeAll() fix will save us a lot of headaches as we get more comfortable with using Storyboard.

This exercise is broken up into 3 parts. Make sure to read them in order, as they build upon each other. If you’d rather just read along, and not manually enter the code, you can download the final source code here.

Continue on to A simple Storyboard framework Part 2

Advertisements

3 thoughts on “A simple Storyboard framework for Corona SDK Part 1

Comments are closed.