gotoScene and doubling

hey guys.

I have a codes which has two scenes.

scene one is menu and

scene two is game

it is  a very basic game, in which when a green object collides with red object it should restart the game.

When I run the game first time, all works as expected. I have a print statement which print x when green collides with the red one once

but after restart (i.e. go to scene menu and return) second time when it collided with red one it prints x twice and on third time it prints 3 x’s and so on.

any idea what should be going wrong?

I am making all the objects nil at destroy event

Please suggest

Shei7141 

— main code

local storyboard = require "storyboard" storyboard.purgeOnScreenChange = true -- hide status bar display.setStatusBar(display.HiddenStatusBar) -- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -- common variables centerX = display.contentCenterX centerY = display.contentCenterY screenLeft = display.screenOriginX screenWidth = display.contentWidth - screenLeft \* 2 screenRight = screenLeft + screenWidth screenTop = display.screenOriginY screenHeight = display.contentHeight - screenTop \* 2 screenBottom = screenTop + screenHeight display.contentWidth = screenWidth display.contentHeight = screenHeight storyboard.gotoScene ("menu", {effect = "slideDown"}) storyboard.purgeOnSceneChange = true;

— menu code

 -- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-- common variables centerX = display.contentCenterX centerY = display.contentCenterY screenLeft = display.screenOriginX screenWidth = display.contentWidth - screenLeft \* 2 screenRight = screenLeft + screenWidth screenTop = display.screenOriginY screenHeight = display.contentHeight - screenTop \* 2 screenBottom = screenTop + screenHeight display.contentWidth = screenWidth display.contentHeight = screenHeight -------------- forward refs local background local myPic local text local backgroundMusicChannel ----~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -- loading sound volumes local startGameSound = audio.loadSound("sound/startTrack.mp3") local tahaRunSound = audio.loadSound("sound/zoom.wav") local storyboard = require ("storyboard") local scene = storyboard.newScene() storyboard.purgeOnSceneChange = true; local function playSc (event) storyboard.gotoScene ("Game") return true -- print ("go to Game Mode") end function scene: createScene(event) local group = self.view -- background = display.newText( "test" , 0, 0, "Arial", 40 ) -- background background = display.newImage("background.png") background.width = screenWidth background.height= screenHeight background:scale (1.4,1.4) background.x = centerX background.y = centerY -- group:insert (background) transition.to( background, { time=4000, alpha=0.1, xScale = 1, yScale =1} ) -- background music backgroundMusicChannel = audio.play( startGameSound, { loops=-1 } ) -- group.insert (backgroundMusicChannel) function showTitle() gameTitle = display.newImage("gametitle.png") gameTitle.x = centerX gameTitle.y = screenTop +90 gameTitle:scale (1,1) gameTitle.alpha = 0 gameTitle:scale(4, 4) transition.to( gameTitle, {time=500, alpha=1, xScale=3, yScale=3} ) end -- taha image myPic = display.newImage( "happy.png") myPic:scale (1,1) myPic.x = centerX myPic.y = centerY + 60 -- group:insert (myPic) transition.to( myPic, { time=2000, alpha=1, xScale = 3, yScale =3, rotation = 360, y=centerY, onComplete=showTitle } ) -- instruction text local text = display.newText( "Tap me to start", 0, 0, "Arial", 60 ) text.x = centerX text.y = display.contentHeight -30 text:setTextColor(230, 250, 12) -- group:insert (text) local function goAway(event) display.remove(event.target) audio.stop( ) display.remove(myPic) display.remove(gameTitle) display.remove( text ) playSc() text = nil return true end function fancy() transition.to ( myPic, {time = 1000, xScale = 5, yScale =5, onComplete = goAway} ) end myPic:addEventListener ( "tap", fancy ) end --------------------------------------------eneter scene function scene:enterScene( event ) local group = self.view end function scene:exitScene( event ) local group = self.view end function scene:destroyScene( event ) local group = self.view end -- "createScene" event is dispatched if scene's view does not exist scene:addEventListener( "createScene", 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 ) --- scene:addEventListener( "destroyScene", scene ) return scene

– game code

local storyboard = require "storyboard" local scene = storyboard.newScene() --~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-- hidding the status bar display.setStatusBar(display.HiddenStatusBar) --~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -- common variables centerX = display.contentCenterX centerY = display.contentCenterY screenLeft = display.screenOriginX screenWidth = display.contentWidth - screenLeft \* 2 screenRight = screenLeft + screenWidth screenTop = display.screenOriginY screenHeight = display.contentHeight - screenTop \* 2 screenBottom = screenTop + screenHeight display.contentWidth = screenWidth display.contentHeight = screenHeight local function playMe(event) storyboard.gotoScene ("removeScene") return true end -------------- forward refs local happy local angry local angry2 local angry3 local angry4 local angry5 local score = 0 local myScore local background local scoreTxt storyboard.purgeOnSceneChange = true; ------- function scene: createScene(event) local group = self.view local physics = require "physics" physics.start() physics.setGravity(0,0) -- SETUP GRAPHICS background = display.newImage("background.png") background.alpha = 0 background.width = screenWidth background.height= screenHeight group: insert (background) --background: scale (screenWidth,screenHeight) happy = display.newImage("happy.png") happy.x = screenTop + 80 happy.y = screenLeft + 80 physics.addBody(happy, "dynamic") happy:scale(2,2) happy.type = "player" group: insert (happy) angry = display.newImage("rat.png") angry.x = centerX angry.y = centerY physics.addBody(angry, "static") angry.type = "bad" group: insert (angry) angry2 = display.newImage("dragon.png") angry2.x = centerX angry2.y = centerY physics.addBody(angry2, "static") angry2.type = "bad" group: insert (angry2) angry3 = display.newImage("dog.png") angry3.x = centerX angry3.y = centerY physics.addBody(angry3, "static") angry3.type = "bad" group: insert (angry3) angry4 = display.newImage("bear.png") angry4.x = centerX angry4.y = centerY physics.addBody(angry4, "static") angry4.type = "bad" group: insert (angry4) angry5 = display.newImage("monkey.png") angry5.x = centerX angry5.y = centerY angry5: scale(0.5,0.5) physics.addBody(angry5, "static") angry5.type = "bad" group: insert (angry5) -- scoreTxt = display.newText( "0", 0, 0, "Arial", 400 ) scoreTxt.x = centerX scoreTxt.y = centerY scoreTxt.alpha = 0.5 scoreTxt: setTextColor (0.56, 0.56, 0.56) group: insert (scoreTxt) function touchScreen(event) if event.phase == "ended" then transition.to(happy,{time=300, x=event.x, y=event.y}) end -- audio.play(mySnd) end Runtime:addEventListener("touch", touchScreen) function createGoodies() local goodiePics = {"eyecandy\_1.png","eyecandy\_2.png", "eyecandy\_3.png", "eyecandy\_4.png"} goodie = display.newImage(goodiePics[math.random (#goodiePics)]) goodie.x=math.random(120,screenWidth-100) goodie.y=math.random(120,screenHeight-100) goodie: scale(3,3) physics.addBody(goodie, "static") goodie.type = "goodie" group: insert (goodie) end createGoodies() -- CREATE ANGRY MOVEMENT function moveAngry() transition.to(angry,{time=1500, x=math.random(80,screenWidth), y=math.random(60,screenHeight), onComplete=moveAngry}) transition.to(angry2,{time=1500, x=math.random(80,screenWidth), y=math.random(60,screenHeight)}) transition.to(angry3,{time=1500, x=math.random(80,screenWidth), y=math.random(60,screenHeight)}) transition.to(angry4,{time=1500, x=math.random(80,screenWidth), y=math.random(60,screenHeight)}) transition.to(angry5,{time=1500, x=math.random(80,screenWidth), y=math.random(60,screenHeight)}) end moveAngry() ------ local function goAwayThis() happy:removeSelf() angry:removeSelf() angry2:removeSelf() angry3:removeSelf() angry4:removeSelf() angry5:removeSelf() scoreTxt:removeSelf() goodie:removeSelf() background :removeSelf() playMe() end ----- function onCollision( event) local agro = event.object1 local hit = event.object2 if ( event.phase == "began" ) then if (agro.type == "player" and hit.type == "goodie") then print( agro.type .. hit.type) display.remove (goodie) score = score + 1 scoreTxt.text = score timer.performWithDelay ( 100, createGoodies ) else print( agro.type .. hit.type) goAwayThis() end end end Runtime:addEventListener("collision", onCollision) end --------------------------------------------eneter scene function scene:enterScene( event ) local group = self.view end function scene:exitScene( event ) local group = self.view end function scene:destroyScene( event ) local group = self.view happy = nil angry = nil angry2 = nil angry3 = nil angry4 = nil angry5 = nil scoreTxt = nil end -- "createScene" event is dispatched if scene's view does not exist scene:addEventListener( "createScene", 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 ) --- scene:addEventListener( "destroyScene", scene ) return scene

Are you using collision listeners, Runtime listeners or other things that you might be starting in a scene but not removing when you leave the scene?

Rob

Rob,

I have included the code in the original question.

You are using a lot of global variables which is dangerous.  You are also adding a touch event to the global run time, making the whole screen respond to touch events.  You never remove this.  Even if your game scene gets destroyed, you would keep getting these piling up on each other.  That touch function is accessing some variables that might be getting destroyed.

The same thing is happening with onCollision listener.  Since you’re purging scenes every time you change scenes, your storyboard createScene function gets called every time you enter it and that keeps adding collision listeners and touch screen handlers.

As a rule, you should not do any:  Runtime :addEventListener() calls in createScene.  Object listeners are okay, but not Runtime.  These should be created in the enterScene() function and removed in the exitScene() function.   You do not want to tie their creation to the creation of the scene.

Rob

Thanks Rob,

Is there a way you could please adjust the code. I am absolutely new to Corona… I am going to take all the tutorials from today before diving into any game devs…

I will really appreciate your assistance on this one.

Kind regards,

Shei

I can’t write your code for you.  Be patient and don’t rush.  There is a learning curve.  Go through some tutorials.  Work on getting pieces going.  Spend some time trying to learn about scope and how storyboard works.   This tutorial might help on the storyboard side:

http://coronalabs.com/blog/2013/08/20/tutorial-reloading-storyboard-scenes/

Rob

Thanks :slight_smile:

Are you using collision listeners, Runtime listeners or other things that you might be starting in a scene but not removing when you leave the scene?

Rob

Rob,

I have included the code in the original question.

You are using a lot of global variables which is dangerous.  You are also adding a touch event to the global run time, making the whole screen respond to touch events.  You never remove this.  Even if your game scene gets destroyed, you would keep getting these piling up on each other.  That touch function is accessing some variables that might be getting destroyed.

The same thing is happening with onCollision listener.  Since you’re purging scenes every time you change scenes, your storyboard createScene function gets called every time you enter it and that keeps adding collision listeners and touch screen handlers.

As a rule, you should not do any:  Runtime :addEventListener() calls in createScene.  Object listeners are okay, but not Runtime.  These should be created in the enterScene() function and removed in the exitScene() function.   You do not want to tie their creation to the creation of the scene.

Rob

Thanks Rob,

Is there a way you could please adjust the code. I am absolutely new to Corona… I am going to take all the tutorials from today before diving into any game devs…

I will really appreciate your assistance on this one.

Kind regards,

Shei

I can’t write your code for you.  Be patient and don’t rush.  There is a learning curve.  Go through some tutorials.  Work on getting pieces going.  Spend some time trying to learn about scope and how storyboard works.   This tutorial might help on the storyboard side:

http://coronalabs.com/blog/2013/08/20/tutorial-reloading-storyboard-scenes/

Rob

Thanks :slight_smile: