Need help reloading scenes

So basically my game works flawlessly on the first execution of the game , everything works as it is supposed too. When I try to repeat the game everything goes to bad here are some examples:

  • Game Ending Instantly

  • Random Collisions (Causing Game to end)

  • After 5-6 repeats i usally will get an error “toFront is a nil value” or something else that is been working for the past 5 times, and is now all the sudden broken

menu.lua

local storyboard = require( "storyboard" ) local scene = storyboard.newScene() -- include Corona's "widget" library local widget = require "widget" local function onPlayBtnRelease(event) -- go to level1.lua scene storyboard.gotoScene( "level1", "fade", 500 ) return true end function scene:createScene( event ) local screenGroup = self.view -- Drawing background local background = display.newImageRect( "assets/backgroundColor.png", display.contentWidth, display.contentHeight ) background:setReferencePoint( display.TopLeftReferencePoint ) background.x, background.y = 0, 0 screenGroup:insert(background) cloud = display.newImage("assets/nebula.png") screenGroup:insert(cloud) cloud2 = display.newImage("assets/nebula.png") cloud2.y = 500 cloud2.x = 500 cloud3 = display.newImage("assets/nebula.png") screenGroup:insert(cloud2) cloud3.y = 345 cloud3.x = 430 screenGroup:insert(cloud3) star =display.newImage("assets/starSmall.png") star.x = math.random(5 ,display.contentWidth ) star.y = math.random(5,display.contentHeight) screenGroup:insert(star) star1 =display.newImage("assets/starSmall.png") star1.x = math.random(5 ,display.contentWidth ) star1.y = math.random(5,display.contentHeight) screenGroup:insert(star1) star2 =display.newImage("assets/starSmall.png") star2.x = math.random(5 ,display.contentWidth ) star2.y = math.random(5,display.contentHeight) screenGroup:insert(star2) star3 =display.newImage("assets/starSmall.png") star3.x = math.random(5 ,display.contentWidth ) star3.y = math.random(5,display.contentHeight) screenGroup:insert(star3) star4 =display.newImage("assets/starSmall.png") star4.x = math.random(5 ,display.contentWidth ) star4.y = math.random(5,display.contentHeight) screenGroup:insert(star4) star5 =display.newImage("assets/starSmall.png") star5.x = math.random(5 ,display.contentWidth ) star5.y = math.random(5,display.contentHeight) screenGroup:insert(star5) star6 =display.newImage("assets/starSmall.png") star6.x = math.random(5 ,display.contentWidth ) star6.y = math.random(5,display.contentHeight) screenGroup:insert(star6) star7 =display.newImage("assets/starSmall.png") star7.x = math.random(5 ,display.contentWidth ) star7.y = math.random(5,display.contentHeight) screenGroup:insert(star7) star8 =display.newImage("assets/starSmall.png") star8.x = math.random(5 ,display.contentWidth ) star8.y = math.random(5,display.contentHeight) screenGroup:insert(star8) -- create/position logo/title image on upper-half of the screen printScore = display.newEmbossedText("Space Race", 0, 0, native.systemFont, 48, { 255, 255, 255, 255 }) printScore.x = display.contentWidth/2 printScore.y = display.contentHeight \*.2 printScore:setTextColor( 240 ,248,255 ) screenGroup:insert(printScore) print("im a menu") playBtn = widget.newButton { left = 100, top = 200, id = "playBtn", label = "Play !", onRelease = onPlayBtnRelease } playBtn.x = display.contentWidth/2 playBtn.y = display.contentHeight \*.4 screenGroup:insert(playBtn) end function scrollClouds(self,event) if self.y \> display.viewableContentHeight + 400 then self.y = -100 self.x = math.random(0,display.contentWidth) printScore:toFront() else self.y = self.y + .5 end end function scrollStars(self,event) if self.y \> display.contentHeight + 5 then self.y = math.random(0, 10) self.x = math.random(0,display.contentWidth) else self.y = self.y + 3 end end -- Called immediately after scene has moved onscreen: function scene:enterScene( event ) local group = self.view local prior\_scene = storyboard.getPrevious() --s storyboard.purgeScene( prior\_scene ) -- storyboard.removeScene("level1") cloud.enterFrame = scrollClouds Runtime:addEventListener("enterFrame", cloud) cloud2.enterFrame = scrollClouds Runtime:addEventListener("enterFrame", cloud2) cloud3.enterFrame = scrollClouds Runtime:addEventListener("enterFrame", cloud3) -- add stars-- star.enterFrame = scrollStars Runtime:addEventListener("enterFrame", star) star1.enterFrame = scrollStars Runtime:addEventListener("enterFrame", star1) star2.enterFrame = scrollStars Runtime:addEventListener("enterFrame", star2) star3.enterFrame = scrollStars Runtime:addEventListener("enterFrame", star3) star4.enterFrame = scrollStars Runtime:addEventListener("enterFrame", star4) star5.enterFrame = scrollStars Runtime:addEventListener("enterFrame", star5) star6.enterFrame = scrollStars Runtime:addEventListener("enterFrame", star6) star7.enterFrame = scrollStars Runtime:addEventListener("enterFrame", star7) star8.enterFrame = scrollStars Runtime:addEventListener("enterFrame", star8) end -- Called when scene is about to move offscreen: function scene:exitScene( event ) local group = self.view Runtime:removeEventListener("enterFrame", cloud) Runtime:removeEventListener("enterFrame", cloud2) Runtime:removeEventListener("enterFrame", cloud3) Runtime:removeEventListener("enterFrame", star) Runtime:removeEventListener("enterFrame", star1) Runtime:removeEventListener("enterFrame", star2) Runtime:removeEventListener("enterFrame", star3) Runtime:removeEventListener("enterFrame", star4) Runtime:removeEventListener("enterFrame", star5) Runtime:removeEventListener("enterFrame", star6) Runtime:removeEventListener("enterFrame", star7) Runtime:removeEventListener("enterFrame", star8) end function scene:destroyScene( event ) local group = self.view playBtn:removeSelf( ) end scene:addEventListener( "createScene", scene ) scene:addEventListener( "enterScene", scene ) scene:addEventListener( "exitScene", scene ) scene:addEventListener( "destroyScene", scene ) return scene

 level1.lua

----------------------------------------------------------------------------------------- -- -- menu.lua -- ----------------------------------------------------------------------------------------- local storyboard = require( "storyboard" ) local scene = storyboard.newScene() -- include Corona's "widget" library local widget = require "widget" local function onPlayBtnRelease(event) -- go to level1.lua scene storyboard.gotoScene( "level1", "fade", 500 ) return true end function scene:createScene( event ) local screenGroup = self.view -- Drawing background local background = display.newImageRect( "assets/backgroundColor.png", display.contentWidth, display.contentHeight ) background:setReferencePoint( display.TopLeftReferencePoint ) background.x, background.y = 0, 0 screenGroup:insert(background) cloud = display.newImage("assets/nebula.png") screenGroup:insert(cloud) cloud2 = display.newImage("assets/nebula.png") cloud2.y = 500 cloud2.x = 500 cloud3 = display.newImage("assets/nebula.png") screenGroup:insert(cloud2) cloud3.y = 345 cloud3.x = 430 screenGroup:insert(cloud3) star =display.newImage("assets/starSmall.png") star.x = math.random(5 ,display.contentWidth ) star.y = math.random(5,display.contentHeight) screenGroup:insert(star) star1 =display.newImage("assets/starSmall.png") star1.x = math.random(5 ,display.contentWidth ) star1.y = math.random(5,display.contentHeight) screenGroup:insert(star1) star2 =display.newImage("assets/starSmall.png") star2.x = math.random(5 ,display.contentWidth ) star2.y = math.random(5,display.contentHeight) screenGroup:insert(star2) star3 =display.newImage("assets/starSmall.png") star3.x = math.random(5 ,display.contentWidth ) star3.y = math.random(5,display.contentHeight) screenGroup:insert(star3) star4 =display.newImage("assets/starSmall.png") star4.x = math.random(5 ,display.contentWidth ) star4.y = math.random(5,display.contentHeight) screenGroup:insert(star4) star5 =display.newImage("assets/starSmall.png") star5.x = math.random(5 ,display.contentWidth ) star5.y = math.random(5,display.contentHeight) screenGroup:insert(star5) star6 =display.newImage("assets/starSmall.png") star6.x = math.random(5 ,display.contentWidth ) star6.y = math.random(5,display.contentHeight) screenGroup:insert(star6) star7 =display.newImage("assets/starSmall.png") star7.x = math.random(5 ,display.contentWidth ) star7.y = math.random(5,display.contentHeight) screenGroup:insert(star7) star8 =display.newImage("assets/starSmall.png") star8.x = math.random(5 ,display.contentWidth ) star8.y = math.random(5,display.contentHeight) screenGroup:insert(star8) -- create/position logo/title image on upper-half of the screen printScore = display.newEmbossedText("Space Race", 0, 0, native.systemFont, 48, { 255, 255, 255, 255 }) printScore.x = display.contentWidth/2 printScore.y = display.contentHeight \*.2 printScore:setTextColor( 240 ,248,255 ) screenGroup:insert(printScore) print("im a menu") playBtn = widget.newButton { left = 100, top = 200, id = "playBtn", label = "Play !", onRelease = onPlayBtnRelease } playBtn.x = display.contentWidth/2 playBtn.y = display.contentHeight \*.4 screenGroup:insert(playBtn) end function scrollClouds(self,event) if self.y \> display.viewableContentHeight + 400 then self.y = -100 self.x = math.random(0,display.contentWidth) printScore:toFront() else self.y = self.y + .5 end end function scrollStars(self,event) if self.y \> display.contentHeight + 5 then self.y = math.random(0, 10) self.x = math.random(0,display.contentWidth) else self.y = self.y + 3 end end -- Called immediately after scene has moved onscreen: function scene:enterScene( event ) local group = self.view local prior\_scene = storyboard.getPrevious() --s storyboard.purgeScene( prior\_scene ) -- storyboard.removeScene("level1") cloud.enterFrame = scrollClouds Runtime:addEventListener("enterFrame", cloud) cloud2.enterFrame = scrollClouds Runtime:addEventListener("enterFrame", cloud2) cloud3.enterFrame = scrollClouds Runtime:addEventListener("enterFrame", cloud3) -- add stars-- star.enterFrame = scrollStars Runtime:addEventListener("enterFrame", star) star1.enterFrame = scrollStars Runtime:addEventListener("enterFrame", star1) star2.enterFrame = scrollStars Runtime:addEventListener("enterFrame", star2) star3.enterFrame = scrollStars Runtime:addEventListener("enterFrame", star3) star4.enterFrame = scrollStars Runtime:addEventListener("enterFrame", star4) star5.enterFrame = scrollStars Runtime:addEventListener("enterFrame", star5) star6.enterFrame = scrollStars Runtime:addEventListener("enterFrame", star6) star7.enterFrame = scrollStars Runtime:addEventListener("enterFrame", star7) star8.enterFrame = scrollStars Runtime:addEventListener("enterFrame", star8) end -- Called when scene is about to move offscreen: function scene:exitScene( event ) local group = self.view Runtime:removeEventListener("enterFrame", cloud) Runtime:removeEventListener("enterFrame", cloud2) Runtime:removeEventListener("enterFrame", cloud3) Runtime:removeEventListener("enterFrame", star) Runtime:removeEventListener("enterFrame", star1) Runtime:removeEventListener("enterFrame", star2) Runtime:removeEventListener("enterFrame", star3) Runtime:removeEventListener("enterFrame", star4) Runtime:removeEventListener("enterFrame", star5) Runtime:removeEventListener("enterFrame", star6) Runtime:removeEventListener("enterFrame", star7) Runtime:removeEventListener("enterFrame", star8) end function scene:destroyScene( event ) local group = self.view playBtn:removeSelf( ) end scene:addEventListener( "createScene", scene ) scene:addEventListener( "enterScene", scene ) scene:addEventListener( "exitScene", scene ) scene:addEventListener( "destroyScene", scene ) return scene

reset.lua

local storyboard = require( "storyboard" ) local scene = storyboard.newScene() function scene:createScene( event ) local group = self.view resetLevels() storyboard.gotoScene("level1") end function scene:willEnterScene( event ) local group = self.view end function resetLevels() storyboard.purgeScene("level1") storyboard.removeScene("level") end -- Called immediately after scene has moved onscreen: function scene:enterScene( event ) local group = self.view end -- Called when scene is about to move offscreen: function scene:exitScene( event ) local group = self.view ----------------------------------------------------------------------------- -- INSERT code here (e.g. stop timers, remove listeners, unload sounds, etc.) ----------------------------------------------------------------------------- end -- Called prior to the removal of scene's "view" (display group) function scene:destroyScene( event ) local group = self.view ----------------------------------------------------------------------------- -- INSERT code here (e.g. remove listeners, widgets, save state, etc.) ----------------------------------------------------------------------------- end -- Called if/when overlay scene is displayed via storyboard.showOverlay() function scene:overlayBegan( event ) local group = self.view local overlay\_name = event.sceneName -- name of the overlay scene ----------------------------------------------------------------------------- -- This event requires build 2012.797 or later. ----------------------------------------------------------------------------- end -- Called if/when overlay scene is hidden/removed via storyboard.hideOverlay() function scene:overlayEnded( event ) local group = self.view local overlay\_name = event.sceneName -- name of the overlay scene ----------------------------------------------------------------------------- -- This event requires build 2012.797 or later. ----------------------------------------------------------------------------- end --------------------------------------------------------------------------------- -- END OF YOUR IMPLEMENTATION --------------------------------------------------------------------------------- -- "createScene" event is dispatched if scene's view does not exist scene:addEventListener( "createScene", scene ) -- "willEnterScene" event is dispatched before scene transition begins scene:addEventListener( "willEnterScene", scene ) -- "enterScene" event is dispatched whenever scene transition has finished scene:addEventListener( "enterScene", scene ) -- "exitScene" event is dispatched before next scene's transition begins scene:addEventListener( "exitScene", scene ) -- "didExitScene" event is dispatched after scene has finished transitioning out scene:addEventListener( "didExitScene", scene ) -- "destroyScene" event is dispatched before view is unloaded, which can be -- automatically unloaded in low memory situations, or explicitly via a call to -- storyboard.purgeScene() or storyboard.removeScene(). scene:addEventListener( "destroyScene", scene ) -- "overlayBegan" event is dispatched when an overlay scene is shown scene:addEventListener( "overlayBegan", scene ) -- "overlayEnded" event is dispatched when an overlay scene is hidden/removed scene:addEventListener( "overlayEnded", scene ) --------------------------------------------------------------------------------- return scene

I have also attached the zip file of this game (it’s open source any way   :D )

I don’t see the toFront() function defined above. Are you certain your Runtime listeners being removed? Normally Runtime listeners can’t be removed in different Storyboard functions without them being forward declared first. I’d suggest including print statements and running the “restarts” in simulator to ensure the listeners are removed correctly.

Not sure I follow. Couldnt find the link to the files, and in the codes you posted both “menu.lua” and “level1.lua” are the same… also, I couldnt find how the “game ends” so that I could try to understand what causes the game to end prematurelly.

Have you discovered your problem in the last 3 weeks since you posted? If not, giving a link to the entire project (zipped up) would be good – I think people are more likely to try something if they don’t have to copy/paste a bunch of files. :slight_smile:

A couple tips that might help you track down the problem (or a future problem):

  1. Write fewer lines of code. :slight_smile: I know, you need as many as you need, and knowing how to do the same job with fewer lines of code comes with experience, but anytime you’re writing almost the exact same lines of code over and over, that’s the place for a loop.

For example, creating 9 stars and naming them star-star8 works, but it’s wasteful of your time. It also makes it harder to tweak things because you have to make nine changes.

In this chunk of code I created 9 stars just like you did:

local stars = {} local function createStars(numStars) for x = 1, numStars do     local star = display.newImage("assets/starSmall.png")     star.x = mRandom(5, screenWidth )     star.y = mRandom(5, screenHeight)     screenGroup:insert(star)     stars[#stars+1] = star end end

Actually, that code doesn’t create 9 stars, it creates as many stars as you want. In the sample storyboard scene I’ll post below you’ll see how it’s used (called from the scene:createScene() function).

  1. Don’t put any more code in createScene() than you have to. As you’ll see in the sample below I don’t put the star creation routine inside createScene(), I put it outside that and then call it from that function. The main reason is so I can call it from somewhere else if I want, such as restarting the scene. In your code you’re leaving the storyboard scene and re-entering it to set things up again, but there’s not really a good reason to do that. You can write your code so the user can play umpteen different levels and never leave the scene. Creating functions and calling them from inside createScene() and enterScene() is a big step toward doing that.

I hope this helps. If you wan/need clarification on what I’m doing in the code below, just ask.

 Jay

Here’s the sample storyboard scene that creates 9 stars and scrolls them endlessly.

local storyboard = require( "storyboard" ) local scene = storyboard.newScene() local screenLeft = display.screenOriginX local screenTop = display.screenOriginY local screenHeight = display.contentHeight - screenTop \* 2 local screenWidth = display.contentWidth - screenLeft \* 2 local mRandom = math.random local screenGroup local stars = {} local function scrollStars(event) for x = 1, #stars do if stars[x].y \> screenHeight + 20 then stars[x].y = mRandom(screenTop-20, screenTop-10) stars[x].x = mRandom(screenLeft, screenWidth) else stars[x].y = stars[x].y + 2 end end end local function createStars(numStars) for x = 1, numStars do     local star = display.newImage("assets/starSmall.png")     star.x = mRandom(5, screenWidth )     star.y = mRandom(5, screenHeight)     screenGroup:insert(star)     stars[#stars+1] = star end end -- Called when the scene view does not exist: function scene:createScene( event ) screenGroup = self.view createStars(9) end -- Called immediately after scene has moved onscreen: function scene:enterScene( event ) local group = self.view Runtime:addEventListener("enterFrame", scrollStars) end -- Called when scene is about to move offscreen: function scene:exitScene( event ) local group = self.view Runtime:removeEventListener("enterFrame", scrollStars) end scene:addEventListener( "createScene", scene ) scene:addEventListener( "enterScene", scene ) scene:addEventListener( "exitScene", scene ) return scene

I recommend you check out this tutorial:   http://coronalabs.com/blog/2013/08/20/tutorial-reloading-storyboard-scenes/

Rob

I don’t see the toFront() function defined above. Are you certain your Runtime listeners being removed? Normally Runtime listeners can’t be removed in different Storyboard functions without them being forward declared first. I’d suggest including print statements and running the “restarts” in simulator to ensure the listeners are removed correctly.

Not sure I follow. Couldnt find the link to the files, and in the codes you posted both “menu.lua” and “level1.lua” are the same… also, I couldnt find how the “game ends” so that I could try to understand what causes the game to end prematurelly.

Have you discovered your problem in the last 3 weeks since you posted? If not, giving a link to the entire project (zipped up) would be good – I think people are more likely to try something if they don’t have to copy/paste a bunch of files. :slight_smile:

A couple tips that might help you track down the problem (or a future problem):

  1. Write fewer lines of code. :slight_smile: I know, you need as many as you need, and knowing how to do the same job with fewer lines of code comes with experience, but anytime you’re writing almost the exact same lines of code over and over, that’s the place for a loop.

For example, creating 9 stars and naming them star-star8 works, but it’s wasteful of your time. It also makes it harder to tweak things because you have to make nine changes.

In this chunk of code I created 9 stars just like you did:

local stars = {} local function createStars(numStars) for x = 1, numStars do     local star = display.newImage("assets/starSmall.png")     star.x = mRandom(5, screenWidth )     star.y = mRandom(5, screenHeight)     screenGroup:insert(star)     stars[#stars+1] = star end end

Actually, that code doesn’t create 9 stars, it creates as many stars as you want. In the sample storyboard scene I’ll post below you’ll see how it’s used (called from the scene:createScene() function).

  1. Don’t put any more code in createScene() than you have to. As you’ll see in the sample below I don’t put the star creation routine inside createScene(), I put it outside that and then call it from that function. The main reason is so I can call it from somewhere else if I want, such as restarting the scene. In your code you’re leaving the storyboard scene and re-entering it to set things up again, but there’s not really a good reason to do that. You can write your code so the user can play umpteen different levels and never leave the scene. Creating functions and calling them from inside createScene() and enterScene() is a big step toward doing that.

I hope this helps. If you wan/need clarification on what I’m doing in the code below, just ask.

 Jay

Here’s the sample storyboard scene that creates 9 stars and scrolls them endlessly.

local storyboard = require( "storyboard" ) local scene = storyboard.newScene() local screenLeft = display.screenOriginX local screenTop = display.screenOriginY local screenHeight = display.contentHeight - screenTop \* 2 local screenWidth = display.contentWidth - screenLeft \* 2 local mRandom = math.random local screenGroup local stars = {} local function scrollStars(event) for x = 1, #stars do if stars[x].y \> screenHeight + 20 then stars[x].y = mRandom(screenTop-20, screenTop-10) stars[x].x = mRandom(screenLeft, screenWidth) else stars[x].y = stars[x].y + 2 end end end local function createStars(numStars) for x = 1, numStars do     local star = display.newImage("assets/starSmall.png")     star.x = mRandom(5, screenWidth )     star.y = mRandom(5, screenHeight)     screenGroup:insert(star)     stars[#stars+1] = star end end -- Called when the scene view does not exist: function scene:createScene( event ) screenGroup = self.view createStars(9) end -- Called immediately after scene has moved onscreen: function scene:enterScene( event ) local group = self.view Runtime:addEventListener("enterFrame", scrollStars) end -- Called when scene is about to move offscreen: function scene:exitScene( event ) local group = self.view Runtime:removeEventListener("enterFrame", scrollStars) end scene:addEventListener( "createScene", scene ) scene:addEventListener( "enterScene", scene ) scene:addEventListener( "exitScene", scene ) return scene

I recommend you check out this tutorial:   http://coronalabs.com/blog/2013/08/20/tutorial-reloading-storyboard-scenes/

Rob