How does Composer really works?

Hi Everyone…

Here trying to understand composer.

I have worked with storyboard for 2 years, I feel it’s really good

but, Corona is now using composer, so let’s learn something new…

I open a new project, and saw the black window, that loos like flash, I did not understand anything.

But I just print some text on each scene

and I notice that the SHOW scene is called twice, and also at the end of SHOW scene

then when you HIDE the scene prints something, then goes to the WILL

and back to HIDE, and then to DID of HIDE… very confusing.

But the point is the I just type a text, made a transition

local someText = display.newText(sceneGroup, "Just put whatever", 0, 0, system.nativeFont, 70)         someText.x = display.contentCenterX         someText.y = display.contentCenterY         transition.to(someText, {time=2000, x=display.contentCenterX + 200})

And it moves the text, in Scene 1, but when I come back to the same scene

the text is already in the – x=display.contentCenterX + 200

and it creates a new text, and it moves the second text

Now I have 2 objects

What happens with

storyboard.purgeOnSceneChange = true

I remember this works for me really good at the beginning of main.lua

I hope I can understand this composer, because I guess I will HAVE to start using it right?

Thanks for all your help

Composer is virtually identical to Storyboard.

On show and hide you have to use event.phase == “will” or event.phase == “did” to differentiate. 

Create your display objects in create as that is only called once. This is my basic scene template, might be useful.

[lua]


– LIBRARIES


local composer = require"composer" – import composer library


– DISPLAY GROUPS


local grp = {}  – table to hold display groups

grp.main = display.newGroup()


– LOCAL VARIABLES


local scene = composer.newScene()

local v = {}    – table to hold local variables and avoid limit of 200


– OBJECT & FORWARD DECLARATIONS


local gfx = {}    – table to hold any graphics objects we want to access later


– GAME FUNCTIONS


local gameLoop = function (event)

end


– COMPOSER FUNCTIONS


function scene:create(event)

    grp.main = self.view

    – create initial scene objects here, add to grp.main

end

function scene:show(event)

    grp.main = self.view

    local phase = event.phase

    if phase == “did” then

      local previous =  composer.getSceneName( “previous” )

      if previous ~= “main” and previous then

          composer.removeScene(previous, false)

      end

      Runtime:addEventListener(“enterFrame”, gameLoop)

    end

end

function scene:hide(event)

    grp.main = self.view

    local phase = event.phase

    if phase == “did” then

      Runtime:removeEventListener(“enterFrame”, gameLoop)

    end

end

function scene:destroy(event)

    grp.main = self.view

end


scene:addEventListener(“create”, scene)

scene:addEventListener(“show”, scene)

scene:addEventListener(“hide”, scene)

scene:addEventListener(“destroy”, scene)

return scene

[/lua]

Victor, in Storyboard, we supported four different functions for starting a scene and leaving a scene.  When you went to a scene to “show” it, it would call willEnterScene and enterScene.  Many people don’t really need or use both.  Likewise when you are “hiding” a scene, there were two functions:  exitScene and didExitScene (I think.  My storyboard is starting to get rusty…).

When we re-imagined Storyboard 2.0 (i.e. Composer), one of the frustrating points was all of these different scene events.  We couldn’t really get rid of them because there are  many… many… many… use cases for doing things before the scene shows (but after creating the scene) and to do things after the scene shows.  Like wise, there are things you want to do before you hide the scene and in some cases, things to do after the scene is off screen.

We took those four events, collapsed them in to two and named them more rationally:  scene:show() and scene:hide().  Each scene gets called twice (“will” and “did”).  For scene:show() you get “will” before the scene starts its transition on screen and you get the “did” phase after it’s on the screen.  For scene:hide() it’s the opposite.  You get “will” while the scene is still on the screen and you get “did” after the scene has transitioned away.

Why have the two?  Look at this scenario.  You want to restart a level of a game.  You should move your player back to its starting position but you want to do that before the scene shows to the user.   Because re-creating the scene from scratch is expensive, it’s best to not remove the scene, but keep it around.  In your “will” phase of scene:show() you move things to where they need to be to start the scene, reset scores, health, etc.  But you do not want to start any timers, transitions, music playing, physics to move things until after the scene is on the screen.  You do those things in the “did” phase.

Rob

Thanks I will learn all that, but the same problem

I use this –

composer.recycleOnSceneChange = true

where I had before

storyboard.purgeOnSceneChange = true

In storyboard works…

How do I make the same thing in composer?

Those should do the same thing.

Composer is virtually identical to Storyboard.

On show and hide you have to use event.phase == “will” or event.phase == “did” to differentiate. 

Create your display objects in create as that is only called once. This is my basic scene template, might be useful.

[lua]


– LIBRARIES


local composer = require"composer" – import composer library


– DISPLAY GROUPS


local grp = {}  – table to hold display groups

grp.main = display.newGroup()


– LOCAL VARIABLES


local scene = composer.newScene()

local v = {}    – table to hold local variables and avoid limit of 200


– OBJECT & FORWARD DECLARATIONS


local gfx = {}    – table to hold any graphics objects we want to access later


– GAME FUNCTIONS


local gameLoop = function (event)

end


– COMPOSER FUNCTIONS


function scene:create(event)

    grp.main = self.view

    – create initial scene objects here, add to grp.main

end

function scene:show(event)

    grp.main = self.view

    local phase = event.phase

    if phase == “did” then

      local previous =  composer.getSceneName( “previous” )

      if previous ~= “main” and previous then

          composer.removeScene(previous, false)

      end

      Runtime:addEventListener(“enterFrame”, gameLoop)

    end

end

function scene:hide(event)

    grp.main = self.view

    local phase = event.phase

    if phase == “did” then

      Runtime:removeEventListener(“enterFrame”, gameLoop)

    end

end

function scene:destroy(event)

    grp.main = self.view

end


scene:addEventListener(“create”, scene)

scene:addEventListener(“show”, scene)

scene:addEventListener(“hide”, scene)

scene:addEventListener(“destroy”, scene)

return scene

[/lua]

Victor, in Storyboard, we supported four different functions for starting a scene and leaving a scene.  When you went to a scene to “show” it, it would call willEnterScene and enterScene.  Many people don’t really need or use both.  Likewise when you are “hiding” a scene, there were two functions:  exitScene and didExitScene (I think.  My storyboard is starting to get rusty…).

When we re-imagined Storyboard 2.0 (i.e. Composer), one of the frustrating points was all of these different scene events.  We couldn’t really get rid of them because there are  many… many… many… use cases for doing things before the scene shows (but after creating the scene) and to do things after the scene shows.  Like wise, there are things you want to do before you hide the scene and in some cases, things to do after the scene is off screen.

We took those four events, collapsed them in to two and named them more rationally:  scene:show() and scene:hide().  Each scene gets called twice (“will” and “did”).  For scene:show() you get “will” before the scene starts its transition on screen and you get the “did” phase after it’s on the screen.  For scene:hide() it’s the opposite.  You get “will” while the scene is still on the screen and you get “did” after the scene has transitioned away.

Why have the two?  Look at this scenario.  You want to restart a level of a game.  You should move your player back to its starting position but you want to do that before the scene shows to the user.   Because re-creating the scene from scratch is expensive, it’s best to not remove the scene, but keep it around.  In your “will” phase of scene:show() you move things to where they need to be to start the scene, reset scores, health, etc.  But you do not want to start any timers, transitions, music playing, physics to move things until after the scene is on the screen.  You do those things in the “did” phase.

Rob

Thanks I will learn all that, but the same problem

I use this –

composer.recycleOnSceneChange = true

where I had before

storyboard.purgeOnSceneChange = true

In storyboard works…

How do I make the same thing in composer?

Those should do the same thing.