Think of a scene as complete app. It does all the work for what is currently on screen. In other words a Menu scene, a game setting scene or a game over scene doesn’t need to know anything about your game scene (* other than some data!). Your enterFrame listener, timers, physics, and objects are all best contained within the one scene.
Now some events, like back key handling on Android, or low memory events, in app purchases and such can be in main.lua and handle events that come in.
But Composer is really cool because you can call composer.getScene(“current”) from say an In App purchase transaction to get the current scene. If you’ve created functions in that scene that you add to the scene object you can then reference them elsewhere.
Lets say someone where your game.lua scene you define a function:
local coins function scene.handleBuyCoinsPurchase( numCoins ) coins = coins + numCoins end
Now in your in app purchase transaction listener you can do:
local function transactionCallback( event ) local transaction = event.transaction local tstate = event.transaction.state if tstate == "purchased" then local currentScene = composer.getScene( "current" ) currentScene.handleBuyCoinsPurchase( 100 ) end .... end
If there are data variables that need to be shared between scenes or app wide, there are multiple ways to do it.
-
Pass paramters. composer.gotoScene() takes an options table that can include a child table that can contain key-value pairs. They are available in scene:create() and scene show:
composer.gotoScene( “game”, { time=500, effect = “crossFade”, params = { key1 = “value”, key2 = 10 } } )
Then in scene:show()
function scene:show( event ) local params = event.params key1 = params.key1 key2 = params.key2 ...
Thats a great option for passing data that doesn’t need to be constantly updated.
- Composer variables. You can always add methods and member values to the composer object. You could do:
composer.coins = 0
in the transaction callback example above, instead of a function, you could just set the value directly:
composer.coins = composer.coins + 1
but you don’t know what all values we may be using in the Composer object or want to use in the future. This is an unsafe operation. But we built in two functions: value = composer.getVariable( “variableName” ) and composer.setVariable( “variableName”, “someValue” ). This allows you to use composer to carry values between scenes.
- You could use Globals, but globals are not recommended for many reasons. But you can created a data table that can be required into each of your scenes to act like your own personal “global” table without the headache’s of globals. See: http://coronalabs.com/blog/2013/05/28/tutorial-goodbye-globals/
This should give you plenty of ways for inter-module communications. But with regards to enterFrame listeners, physics, timers, transitions and such, those are best started in scene:show()'s “did” phase and cancelled/stopped/removed in scene:hide()'s “will” phase. You don’t want them running while the scene is transitioning to the next scene or continuing to run while the scene is off screen.
Finally the Engineers just added a way to create custom events and dispatch them. Check the latest daily build and the daily build documentation.
Rob