Scene problem

Hey,

I have two scenes: lvl1, restart1

lvl1

local composer = require( "composer" ) local scene = composer.newScene() ---My scene code--- function scene:destroy( event ) --objects remove code-- end scene:addEventListener( "destroy", scene ) return scene

restart1

local composer = require( "composer" ) local scene = composer.newScene() composer.removeScene("lvl1") composer.removeHidden() composer.gotoScene("lvl1") return scene

If I go: lvl1 -> restart1 -> lvl1

then some functions is not working. Why?

That’s not a very good description of what’s wrong. Which functions are not working? Is that all the code you have in restart1.lua? If so, you’re missing code. Not every function gets called every time you call goto - create and destroy don’t get called every time, for example.

Because of the order that things happen in, you can’t execute these line:

composer.removeScene(“lvl1”)
composer.removeHidden()
composer.gotoScene(“lvl1”)

in the scene’s main chunk.  These need to go into the scene’s scene:show() event.   Your scene needs to implement a create as well and actually create a scene.

Rob

local composer = require( "composer" ) local scene = composer.newScene() composer.removeScene("lvl1") composer.removeHidden() composer.gotoScene("lvl1") return scene

If it’s all code in restart1 and remove/goto should be in functon:show, what should be in function:create?

Your restart scene needs to be a scene.  In your scene:create() put in a background, a message saying “Game over” or “Try again?” and give them a button to select to go back.

I suspect you’re trying to work around restarting a scene by deleting the old scene so it will reset when it restarts.  There are two ways to do this.  The first is to use a cut scene, which is what you’re trying to do.  This allows you to blow away the game scene and which will start it back to the original.  But the idea behind a cut scene is, well that it’s a scene.  This is why I say to make the scene something that the user has to interact with.  This gives you time to remove the level scene in the composer:show()'s did phase.  This allows your cut scene to be created and shown while simultaneously removing the level scene.  The lines:

composer.removeScene(“lvl1”)
composer.removeHidden()
composer.gotoScene(“lvl1”)

need to go inside scene:show():

function scene:show( event )      if event.phase == "did" then          composer.removeScene("lvl1")          composer.removeHidden()          composer.gotoScene("lvl1")     end end

If you do not want a visible cut-scene, then your choice is to manually reset everything that you need to reset in your lvl1 scene.  This should be done in the scene’s composer:show() in the “will” phase.

But I highly recommend using the visual cut scene method.

Rob

Thanks.

I don’t want to do visible cutscene.

My idea is something like that:

in lvl1 is game over, click restart button -> invisible restart1 -> new game in lvl1

Questions:

  1. composer.removeScene(“lvl1”) is using scene:destroy, which is in lvl1 code?

  2. How I can restart timer?

The cut scene lets you use a simple hack of removing the scene and forcing to to be recreated from scratch.  If you refuse to use the cut scene, then you need to reset your timers, reposition objects, etc. in the scene:show()'s will phase.  Then start your timers and such in the did phase.

Rob

Another problem:

In scene:create I added

local function movelevel1(event)

and if I will in scene:show add 

Runtime:addEventListener( "enterFrame", movelevel1 )

then:

  A2EuZjA.png

How can I fix it?

Move the function “movelevel1” out of scene:create() to the main chunk.  In other words:

local function movelevel1(event) ... end   function scene:create( event ) ... end

Rob

If I moved it, then:

lYMfboa.png

MyGridlvl1 is in function code.

You need to learn about “Scope”.  Please read this tutorial:
 

http://coronalabs.com/blog/2011/09/21/tutorial-scopes-for-functions/

and watch this video:

https://www.youtube.com/watch?v=b12YEOIry60

Rob

Thanks… but I don’t understand anything.

Can you explain me how it’s working? Example my function.

Thanks a lot, I’m noob.

For me to explain this to you, I will have to basically write, word for word what was in the tutorial I posted above.  Here is another video that might help:

http://www.youtube.com/watch?v=2ATlcGP2zMY 

Watch this, go back re-read the tutorial and try to get a grasp on what scope means.  Simply put, depending on where you create/delcare things determines where they are visible.   Corona is also a one pass system, which means that you can use something before you declare it.  That is I can’t call my function before I declare it:

doSomething()

local function doSomething()

     print(“Hello World”)

end

results in an error.  When Lua tries to run doSomething(), it is nil.  It has not been defined yet, and you get that error.  On the other hand:

local function doSomething()

     print(“Hello World”)

end

doSomething()

Will result in “Hello World” being printed because now when you try and run “doSomething()”, it’s been defined and Lua knows what to do with it.

Rob

OK. I must pre-declare myGridlvl1 or scene:create?

If myGridlvl1 has to be after the first time you use it, then you would pre-declare it.  The easiest thing is to move function toward the top before you use them.

Rob

My code:

function scene:create( event ) ... end local function movelevel1(event) ... end function scene:show( event ) ... end

In function scene:show is

Runtime:addEventListener( "enterFrame", movelevel1 )

In function scene:create is

local myGridlvl1 = display.newRect (160, 100, 1000, 22) myGridlvl1:setFillColor (0,0,0) local myGrid2lvl1 = display.newRect (160, 350, 1000, 22) myGrid2lvl1:setFillColor (0,0,0)

And there’s still the same error. I tried to pre-declare myGridlvl1 and myGrid2lvl1 before function movelevel1 and it’s not working.

At the very top of your scene, do:

local myGridlvl1

local myGrid2lvl1

Then in create scene, leave the “local” off.

Rob

Another:

  1. My Collision event isn’t working. Here is code:

    local myCircle1 function scene:create( event ) myCircle1 = display.newImage( “circle.png”, 90, 225, 35 ) myCircle1.ID = “Circle1” myCircle1.collision = Collision myGridlvl1 = display.newRect (160, 100, 1000, 22) myGrid2lvl1 = display.newRect (160, 350, 1000, 22) myGridlvl1.ID = “Crash1” myGrid2lvl1.ID = “Crash1” function endGamelevel1() local endtext1 = display.newText (“You lost!”, 160, 50, font, 32) endtext1:setFillColor (0,0,0) timer.cancel(timer1) Runtime:removeEventListener(“enterFrame”, movelevel1) button1:removeEventListener(“tap”, tap) myCircle1:removeEventListener(“collision”, myCircle1) local function restart (event) composer.gotoScene( “restart1” ) end local restartbutton1 = display.newImage(“restart.png”, 150, 200, 100, 100) restartbutton1:addEventListener( “tap”, restart ) end end local function Collision(self, event) if (event.phase == “began”) then if (self.ID == “Circle1” and event.other.ID == “Crash1”) then endGamelevel1 () end end end function scene:show( event ) myCircle1:addEventListener(“collision”, myCircle1) end

  2. Composer.goto don’t working. Code:

    function scene:create( event ) local function level2 (event) composer.gotoScene(“tolvl2”) end end function scene:show( event ) local timer1 = timer.performWithDelay( 5000, level2) end

Thanks.

PS. Rob, you’re great :slight_smile:

You really need to learn more about scope.  Consider this block of your code:

function scene:create( event )     local function level2 (event)          composer.gotoScene("tolvl2")     end end function scene:show( event )     local timer1 = timer.performWithDelay( 5000, level2) end

Since you are trying to call “level2”, level2 has to be visible to the scene:show() function.  But the level2 function is inside scene:create() and declared local.  Therefore it’s only visible inside of scene:create() and scene:show() cannot access it.  You need to do something like this:

local function level2 (event)      composer.gotoScene("tolvl2") end   function scene:create( event ) -- other scene create things... end function scene:show( event )     local timer1 = timer.performWithDelay( 5000, level2) end

By moving the function outside of the scene:create() function it becomes visible to the entire module.

local myGridlvl1 local myGrid2lvl1 local myCircle1 local function Collision(self, event) if (event.phase == "began") then if (self.ID == "Circle1" and event.other.ID == "Crash1") then endGamelevel1 () end end end function endGamelevel1() \<code\> end

Where I must put this code?

 myCircle1.ID = "Circle1" myGridlvl1.ID = "Crash1" myGrid2lvl1.ID = "Crash1"

If it’s in main chunk is error.