"Tap" and Listeners not working after changing scenes.

Hey Guys,

Looking at some guidance as to what could be causing my enemy[i] (array of enemies) and my collision listener to stop working when switching from my gamescene.lua to menuscene.lua and back to my gamescene.lua

I have the following code on both my enterScene and Exit Scene

function scene:enterScene( event ) local group = self.view -- INSERT code here (e.g. start timers, load audio, start listeners, etc.) --Setup Physics physics.start() physics.setDrawMode("normal") print("Total Bugs on Enter: " .. TotalBugs) --Create Bug timer tmr\_createBug = timer.performWithDelay(gameSpeed, createBugs, 0) --Setup Listeners Runtime:addEventListener( "collision", onCollision ) --Setup Sounds --Setup Level Variables score = 0 gameSpeed = 2000 bugsKilled = 0 juiceCollected = 0 ---- MAY NEED TO MOVE THIS AND CREATE MENY BACK TO ENTER SCENE lives = 10 TotalBugs = 0 --Create Game Menu createGameMenu(group) -- Create a timer that counts the elapsed seconds timeKeep = stopwatch.new() local function onFrame(event) survivalText.text = ("Survival: " .. timeKeep:toElapsedString()) end Runtime:addEventListener("enterFrame", onFrame) end

unction scene:exitScene( event ) local group = self.view -- INSERT code here (e.g. stop timers, remove listeners, unload sounds, etc.) --Stop timers timer.cancel( tmr\_createBug ) transition.cancel("bugTransitions" ) menuActivated = false --Remove Listeners Runtime:removeEventListener("enterFrame", onFrame) Runtime:removeEventListener("collision", onCollision ) --Stop Physics physics.stop() --Remove Sounds for i = TotalBugs,1, -1 do if bug[i] ~= nil then bug[i]:removeEventListener( "tap", bugKilled ) transition.cancel( bug[i] ) display.remove( bug[i] ) bug[i] = nil end end print("Total Bugs: " .. TotalBugs) -- if group ~= nil then -- for i = group.numChildren, 1, -1 do -- group[i]:removeSelf( ) -- group[i] = nil -- end -- end -- Remove all Layers and Dsiplay Groups if gameOverLayer ~= nil then for l=gameOverLayer.numChildren,1,-1 do local child = gameOverLayer[l] child.parent:remove( child ) end end if gameLayer ~= nil then for o=gameLayer.numChildren,1,-1 do gameLayer[o]:removeSelf( ) gameLayer[o] = nil end end local removeAll; removeAll = function(group) if group.enterFrame then Runtime:removeEventListener("enterFrame", group); end if group.tap then group:removeEventListener("touch", group); Runtime:removeEventListener("touch", group); end for i = group.numChildren, 1, -1 do if group[i].numChildren then removeAll(group[i]); else if group[i].enterFrame then Runtime:removeEventListener("enterFrame", group[i]); end if group[i].tap then group[i]:removeEventListener("tap", group[i]); Runtime:removeEventListener("tap", group[i]); end end end end removeAll(group); end

Hey Guys,

Just wanted to know if anyone could shed some light on the above, I have been stumped on this for days with no-fix. 

Thanks

Danny

OK so after a few hours I got the Collision Event listener working when switching back and forth from my Game>Menu>Game but still having issues with the “Tap” event listener not working when switching back into the game scene 

I suspect the issue is with no possibly “fully removing” the tap listener before switching back to the menu in my exitScene part but not sure.

Any idea’s?

For those who were wondering it appears I have fixed the problem. Whether this is the correct way to do it probably not but it appears to be working for now.

On my menuScene “scene:EnterScene” function I added the following code

-- INSERT code here (e.g. start timers, load audio, start listeners, etc.) local prior\_scene = storyboard.getPrevious() if prior\_scene then print( "Here" ) storyboard.removeScene( prior\_scene ) end

@Rob Miracle would this be correct as it appears to be the only thing making my “Tap” listener work again when switching between my game scene and the main menu scene.

might be a silly question, but are your variables localised in the module generally or within your createScene() method?  

i found this very useful: http://www.develephant.net/a-simple-storyboard-framework-for-corona-sdk-part-1/

using “storyboard.removeAll()” gives you the benefit of scene navigation/ asset disposal without needing to worry too much about the other details of storyboard.

Since you didn’t post your createScene code, I’m going to have to guess that’s where you are creating the object and adding a tap handler, correct?

If that’s the case you are being bitten by the way Storyboard (and Composer) work.  There are distinct states for your scene to be in:

1.  created 

2.  entered

3.  exited

4.  destroyed

If the scene **does not** exist, then it’s createScene() function is called.  You are likely adding your tap handler here.  Then when the scene is on the screen, enterScene() is called.  When you goto another scene, exitScene() is called.  You are killing your tap handler here.  When you go back to this scene, it still exists, so there is no need to call createScene() again, so your tap handler never gets recreated.

There are three solutions to this.

1.  Add the tap handler in createScene and simply don’t remove it.  When the object is transitioned off screen, the user can’t interact with it, so you don’t have to worry about it causing problems.  When the scene comes back, the tap handler is ready to go again.  This is probably the preferred way.

2.  Call storyboard.removeScene() on the scene you are going to just before you go to it.  This will kill the scene from memory forcing the createScene() function to fire as if the scene were new and not saved in memory.  This is the brute force way to do this, but it’s the programmer “easy” thing to do.

3.  Remember that enterScene() and exitScene() always happen in pairs.  If you do something in enterScene() (like start a timer, transition, etc) you need to stop/remove it in exitScene().  In your case since you’re killing the tap handler in exitScene() you need to create the tap handler in enterScene().  You can still have the object created in createScene() as long as your not destroying it in exitScene().

Rob

Thanks again Rob, Legend;

#1 appears to have resolved my problem and thanks for letting me better understand how storyboard works.

Working on my first game I appear to be coming across alot of issues but that’s just me getting used to the SDK and LUA in general, you’ll probably see alot more posts from me.

ATM I appear to be having a issue with some collisions not working correctly but I’ll work on figuring it out for a few more hours before I seek help.

thankfully after this my later projects will be more refined and alot easier as I’, working on separate modules for some functionality.

Thanks

Danny

Hey Guys,

Just wanted to know if anyone could shed some light on the above, I have been stumped on this for days with no-fix. 

Thanks

Danny

OK so after a few hours I got the Collision Event listener working when switching back and forth from my Game>Menu>Game but still having issues with the “Tap” event listener not working when switching back into the game scene 

I suspect the issue is with no possibly “fully removing” the tap listener before switching back to the menu in my exitScene part but not sure.

Any idea’s?

For those who were wondering it appears I have fixed the problem. Whether this is the correct way to do it probably not but it appears to be working for now.

On my menuScene “scene:EnterScene” function I added the following code

-- INSERT code here (e.g. start timers, load audio, start listeners, etc.) local prior\_scene = storyboard.getPrevious() if prior\_scene then print( "Here" ) storyboard.removeScene( prior\_scene ) end

@Rob Miracle would this be correct as it appears to be the only thing making my “Tap” listener work again when switching between my game scene and the main menu scene.

might be a silly question, but are your variables localised in the module generally or within your createScene() method?  

i found this very useful: http://www.develephant.net/a-simple-storyboard-framework-for-corona-sdk-part-1/

using “storyboard.removeAll()” gives you the benefit of scene navigation/ asset disposal without needing to worry too much about the other details of storyboard.

Since you didn’t post your createScene code, I’m going to have to guess that’s where you are creating the object and adding a tap handler, correct?

If that’s the case you are being bitten by the way Storyboard (and Composer) work.  There are distinct states for your scene to be in:

1.  created 

2.  entered

3.  exited

4.  destroyed

If the scene **does not** exist, then it’s createScene() function is called.  You are likely adding your tap handler here.  Then when the scene is on the screen, enterScene() is called.  When you goto another scene, exitScene() is called.  You are killing your tap handler here.  When you go back to this scene, it still exists, so there is no need to call createScene() again, so your tap handler never gets recreated.

There are three solutions to this.

1.  Add the tap handler in createScene and simply don’t remove it.  When the object is transitioned off screen, the user can’t interact with it, so you don’t have to worry about it causing problems.  When the scene comes back, the tap handler is ready to go again.  This is probably the preferred way.

2.  Call storyboard.removeScene() on the scene you are going to just before you go to it.  This will kill the scene from memory forcing the createScene() function to fire as if the scene were new and not saved in memory.  This is the brute force way to do this, but it’s the programmer “easy” thing to do.

3.  Remember that enterScene() and exitScene() always happen in pairs.  If you do something in enterScene() (like start a timer, transition, etc) you need to stop/remove it in exitScene().  In your case since you’re killing the tap handler in exitScene() you need to create the tap handler in enterScene().  You can still have the object created in createScene() as long as your not destroying it in exitScene().

Rob

Thanks again Rob, Legend;

#1 appears to have resolved my problem and thanks for letting me better understand how storyboard works.

Working on my first game I appear to be coming across alot of issues but that’s just me getting used to the SDK and LUA in general, you’ll probably see alot more posts from me.

ATM I appear to be having a issue with some collisions not working correctly but I’ll work on figuring it out for a few more hours before I seek help.

thankfully after this my later projects will be more refined and alot easier as I’, working on separate modules for some functionality.

Thanks

Danny