Creating Composer scenes programmatically.

Just found out yours code on github. Great idea! Thanks.

Corona Labs , when you will do your job better? Make your solutions flexible :wink:

Last time I’m disappointed in your platform…

@vadimic, you can still use the scene template but use it inside a creator function.

Something like this:

local function dynamicSceneCreator( scene\_name ) local composer = require( "composer" ) local scene = composer.newScene( scene\_name ) -- ----------------------------------------------------------------------------------------------------------------- -- All code outside of the listener functions will only be executed ONCE unless "composer.removeScene()" is called. -- ----------------------------------------------------------------------------------------------------------------- -- local forward references should go here -- ------------------------------------------------------------------------------- -- "scene:create()" function scene:create( event ) local sceneGroup = self.view -- Initialize the scene here. -- Example: add display objects to "sceneGroup", add touch listeners, etc. end -- "scene:show()" function scene:show( event ) local sceneGroup = self.view local phase = event.phase if ( phase == "will" ) then -- Called when the scene is still off screen (but is about to come on screen). elseif ( phase == "did" ) then -- Called when the scene is now on screen. -- Insert code here to make the scene come alive. -- Example: start timers, begin animation, play audio, etc. end end -- "scene:hide()" function scene:hide( event ) local sceneGroup = self.view local phase = event.phase if ( phase == "will" ) then -- Called when the scene is on screen (but is about to go off screen). -- Insert code here to "pause" the scene. -- Example: stop timers, stop animation, stop audio, etc. elseif ( phase == "did" ) then -- Called immediately after scene goes off screen. end end -- "scene:destroy()" function scene:destroy( event ) local sceneGroup = self.view -- Called prior to the removal of scene's view ("sceneGroup"). -- Insert code here to clean up the scene. -- Example: remove display objects, save state, etc. end -- ------------------------------------------------------------------------------- -- Listener setup scene:addEventListener( "create", scene ) scene:addEventListener( "show", scene ) scene:addEventListener( "hide", scene ) scene:addEventListener( "destroy", scene ) -- ------------------------------------------------------------------------------- return scene end

Then just call the creator before going to that scene:

local function gotoDynamicScene( scene\_name ) if composer.getScene( scene\_name ) == nil then dynamicSceneCreator( scene\_name) end composer.gotoScene( scene\_name ) end

luisherranz , amazing idea! Thanks a lot. Only one small thing, doesn’t possible to use loadScene method that to build pre-loader things :frowning:

Also just checked now your solutions, and have got the WARNING when I try to use composer:gotoScene(…):

WARNING: Cannot create path for resource file ‘Tab1.ccscene’ b/c it does not exist.

I have not tested it but I don’t see why it wouldn’t work. Just make sure to create it first:

dynamicSceneCreator( "my\_scene\_1" ) dynamicSceneCreator( "my\_scene\_2" ) composer.loadScene( "my\_scene\_1" )

The cssscene warning comes from Corona, from their new Composer GUI. I would not worry about it.

Yes, @alexf, many thanks. As @paulscottrobson said, it would be great to add that to the documentation.

yes, it works now. First of all, need to make loadScene and after that use gotoScene.

btw, if you put true to second param, for example, composer.loadScene(scene_name, true, params). The create() event won’t be called. Only when you use false, create() will be called.

another issue:

composer.gotoScene( tabs[1].title ) composer.gotoScene( tabs[2].title )

result:

scene:show will Tab1 scene:hide will Tab1 scene:hide did Tab1 scene:show will Tab2 scene:show did Tab2 scene:show did Tab2

solution:

composer.gotoScene( tabs[1].title ) timer.performWithDelay( 0, function() composer.gotoScene( tabs[2].title ) end )

Hi guys, please help to find solutions how to create and load dynamically scenes. So, for example. we have only one template .lua file with general scene code. And need to create 3 scenes with different names but same structure from template .lua file

Well, you can use alexf’s idea and pre-create it. Or my OOP Composer, which would allow you to declare it as an class and create instances for the various scenes. My Bitmap Font demo app does something like this, creating different scenes using the same basic template with small differences.

If this is a level scene you could have it data driven, so everything uses the same scene, but the things that go in the scene are (say) pulled from an XML file.

Paul, thank you for answer. Where I can find your OOP Composer to check out?

It’s at https://github.com/autismuk/Scene-Manager - there’s a simple demo showing a couple of scenes and an overlay. The Font Demo program at https://github.com/autismuk/Font-Demo does something similar to what you want to do and uses it.

It has one main scene (the menu) and six sub scenes, which are very similar but slightly different (the font effect changes) and it creates a scene class which can be modified via the constructor, and it then creates six instances of the scene to add to the composer equivalent.

It’s a bit beta but I think it works :slight_smile:

Just found out yours code on github. Great idea! Thanks.

Corona Labs , when you will do your job better? Make your solutions flexible :wink:

Last time I’m disappointed in your platform…

@vadimic, you can still use the scene template but use it inside a creator function.

Something like this:

local function dynamicSceneCreator( scene\_name ) local composer = require( "composer" ) local scene = composer.newScene( scene\_name ) -- ----------------------------------------------------------------------------------------------------------------- -- All code outside of the listener functions will only be executed ONCE unless "composer.removeScene()" is called. -- ----------------------------------------------------------------------------------------------------------------- -- local forward references should go here -- ------------------------------------------------------------------------------- -- "scene:create()" function scene:create( event ) local sceneGroup = self.view -- Initialize the scene here. -- Example: add display objects to "sceneGroup", add touch listeners, etc. end -- "scene:show()" function scene:show( event ) local sceneGroup = self.view local phase = event.phase if ( phase == "will" ) then -- Called when the scene is still off screen (but is about to come on screen). elseif ( phase == "did" ) then -- Called when the scene is now on screen. -- Insert code here to make the scene come alive. -- Example: start timers, begin animation, play audio, etc. end end -- "scene:hide()" function scene:hide( event ) local sceneGroup = self.view local phase = event.phase if ( phase == "will" ) then -- Called when the scene is on screen (but is about to go off screen). -- Insert code here to "pause" the scene. -- Example: stop timers, stop animation, stop audio, etc. elseif ( phase == "did" ) then -- Called immediately after scene goes off screen. end end -- "scene:destroy()" function scene:destroy( event ) local sceneGroup = self.view -- Called prior to the removal of scene's view ("sceneGroup"). -- Insert code here to clean up the scene. -- Example: remove display objects, save state, etc. end -- ------------------------------------------------------------------------------- -- Listener setup scene:addEventListener( "create", scene ) scene:addEventListener( "show", scene ) scene:addEventListener( "hide", scene ) scene:addEventListener( "destroy", scene ) -- ------------------------------------------------------------------------------- return scene end

Then just call the creator before going to that scene:

local function gotoDynamicScene( scene\_name ) if composer.getScene( scene\_name ) == nil then dynamicSceneCreator( scene\_name) end composer.gotoScene( scene\_name ) end

luisherranz , amazing idea! Thanks a lot. Only one small thing, doesn’t possible to use loadScene method that to build pre-loader things :frowning:

Also just checked now your solutions, and have got the WARNING when I try to use composer:gotoScene(…):

WARNING: Cannot create path for resource file ‘Tab1.ccscene’ b/c it does not exist.

I have not tested it but I don’t see why it wouldn’t work. Just make sure to create it first:

dynamicSceneCreator( "my\_scene\_1" ) dynamicSceneCreator( "my\_scene\_2" ) composer.loadScene( "my\_scene\_1" )

The cssscene warning comes from Corona, from their new Composer GUI. I would not worry about it.

yes, it works now. First of all, need to make loadScene and after that use gotoScene.

btw, if you put true to second param, for example, composer.loadScene(scene_name, true, params). The create() event won’t be called. Only when you use false, create() will be called.

another issue:

composer.gotoScene( tabs[1].title ) composer.gotoScene( tabs[2].title )

result:

scene:show will Tab1 scene:hide will Tab1 scene:hide did Tab1 scene:show will Tab2 scene:show did Tab2 scene:show did Tab2

solution:

composer.gotoScene( tabs[1].title ) timer.performWithDelay( 0, function() composer.gotoScene( tabs[2].title ) end )

Hi Luisherranz, your dynamic scene creation method seems really useful. We are currently using the ping pong method between 2 composer scenes, filling create scene with new data each time. But all on one page would be much tidier.

At this point we get a littany of errors but mainly “attempt to concatenate global ‘sceneName’ (a nil value)” which is coming from the original composer.gotoScene(“scene_1”, options) in main.lua…

Could you possibly post a working example of your one page composer solution? The first error we got was that composer didn’t exist when running the gotoDynamicScene so we required composer before the dynamicSceneCreator function. But maybe this means we have set the page up in correctly against your example?

Anyway, a working example would be most appreciated and in fact should be the main method as how to use composer. Why bother repeating the same structure over 26 scenes in our case if one page populated with new data will work.

Thanks Luisherranz.