Scene Not Removing After Going To New Scene

I have this little game working however I am unable to get the current scene removed before I go to a new scene.

Game is simple, I have falling objects, and a character, if the character collides with a specific object type then score is increased, but if the character collides with another specific object type then the game is supposed to end and go to the main menu. Which works, but if I go back to the game scene the game is still going, and if I add scene.removeScene() then I get an error.

Error: 

Attempt to index field 'view' (a nil value)

Here is the code in question FYI: I have tried typing in the actual scene name into the removeScene() function

local function playerCollision (self, event) if event.phase == "began" then if event.other.type == "food" then score = score + 1 print(score) else composer.removeScene(composer.getSceneName( "current" ), true) composer.gotoScene("mainMenu", {effect="slideRight", time=300}) end event.other:removeSelf() end end --event lister for movement bg:addEventListener("touch", movePlayer) currentPlayer.collision = playerCollision currentPlayer:addEventListener("collision", currentPlayer) end

Here is the full code 

local composer = require("composer") local scene = composer.newScene() local bg local name local score = 0 local pileUp = true local mRandom = math.random local mAbs = math.abs local physics = require("physics") physics:start() physics.setDrawMode("hybrid") local currentPlayer local ground local objects = {"apple.png", "mango.png", "orange.png", "pear.png", "bomb.png", "bomb.png", "bomb.png"} local math = require("math") function scene:create(e) bg = display.newImageRect( "images/background2.png", width\*2, height ) bg.x = 0 bg.y = y name = display.newText(e.params.player..":"..score,0,0,system.nativeFont,24) name.x = 60 name.y = 0 name:setFillColor(.4,0,.2) currentPlayer = display.newCircle( x, display.actualContentHeight-150, 25 ) physics.addBody(currentPlayer, "static", {density=1, friction = .5, radius = 25}) ground = display.newRect(x,display.actualContentHeight-40,display.actualContentWidth, 50) scene.view:insert(bg) scene.view:insert(name) scene.view:insert(currentPlayer) scene.view:insert(ground) end function scene:show(e) local function spawnObjects() local objIdx = mRandom(#objects) local objName = objects[objIdx] local object = display.newImageRect("images/"..objName, 45,45) object.x = mRandom(20, display.actualContentWidth-100) object.y = mRandom(-10, 0) object.rotation = mRandom(-60, -10 ) if objIdx \< 5 then object.type = "food" else object.type = "bomb" end scene.view:insert(object) physics.addBody(object, "dynamic", {density=1, friction = .5, radius = 25}) end timer.performWithDelay(mRandom(1500, 4000),spawnObjects, 0) -- Move player local function movePlayer(event) if event.phase == "began" then local speed = (1500/display.actualContentWidth - display.screenOriginX)\*(mAbs(currentPlayer.x - event.x)) transition.to(currentPlayer, {time=speed, x = event.x}) end end local function playerCollision (self, event) if event.phase == "began" then if event.other.type == "food" then score = score + 1 print(score) else composer.removeScene(composer.getSceneName( "current" ), true) composer.gotoScene("mainMenu", {effect="slideRight", time=300}) end event.other:removeSelf() end end --event lister for movement bg:addEventListener("touch", movePlayer) currentPlayer.collision = playerCollision currentPlayer:addEventListener("collision", currentPlayer) end function scene:hide(e) if e.phase == "will" then end end scene:addEventListener("create", scene) scene:addEventListener("show", scene) scene:addEventListener("hide", scene) return scene

Unrelated…

I assume this fails because the physics world is locked during collision events:

event.other:removeSelf()

When you say

the game is still going

do you mean that the display objects etc which you added to the scene are still there?

That is what I would expect because you don’t have any code removing any of it.

I think you are running into the classic problem where developers expect a scene to get recycled automatically.

When you add  composer.removeScene() where are you putting it? If you put it within the scene being removed you might hit issues.

You cannot remove the scene you are currently in.  There is no reason to. Calling composer.gotoScene() will hide the current scene when it brings the new scene to view. The only reason to remove a scene is to free memory is the scene is taking up too much, but you remove it after it’s off-screen in that case. The other quasi-legit reason to remove a scene is if you know you’re going back to the scene and you want to do a complete reset of the scene in minimal code.

Rob

i tested your code

before removing the scene you need to cancel the timer that spawns objects, which means you need to assign it to a variable like this

xyz=timer.performWithDelay(mRandom(1500, 4000),spawnObjects, 0)

you would also need a Boolean flag to exit the function like this

somewhere above:

local exitFlag=false&nbsp;

spawn function:

local function spawnObjects() &nbsp; &nbsp; &nbsp; &nbsp; if exitFlag==true then &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return true &nbsp; &nbsp; &nbsp; &nbsp; end &nbsp; &nbsp; &nbsp; &nbsp; local objIdx = mRandom(#objects) &nbsp; &nbsp; &nbsp; &nbsp; local objName = objects[objIdx] &nbsp; &nbsp; &nbsp; &nbsp; local object = display.newImageRect("images/"..objName, 45,45) &nbsp; &nbsp; &nbsp; &nbsp; object.x = mRandom(20, display.actualContentWidth-100) &nbsp; &nbsp; &nbsp; &nbsp; object.y = mRandom(-10, 0) &nbsp; &nbsp; &nbsp; &nbsp; object.rotation = mRandom(-60, -10 ) &nbsp; &nbsp; &nbsp; &nbsp; if objIdx \< 5 then &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; object.type = "food" &nbsp; &nbsp; &nbsp; &nbsp; else &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; object.type = "bomb" &nbsp; &nbsp; &nbsp; &nbsp; end &nbsp; &nbsp; &nbsp; &nbsp; scene.view:insert(object) &nbsp; &nbsp; &nbsp; &nbsp; physics.addBody(object,&nbsp; "dynamic", {density=1, friction = .5, radius = 25}) &nbsp; &nbsp; end

Player Collision function:

local function playerCollision (self, event) &nbsp; &nbsp; &nbsp; &nbsp; if event.phase == "began" then &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if event.other.type == "food" then &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; score = score + 1 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; print(score) &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; else &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; exitFlag=true &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; timer.cancel(xyz) &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; composer.removeScene("main2") &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; composer.gotoScene("main3") &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; end &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; event.other:removeSelf() &nbsp; &nbsp; &nbsp; &nbsp; end &nbsp; &nbsp; end

i have been programming with Corona for 5 years now,i thought i was doing everything correctly, a few months ago i read an article for Rob Miracle on something similar … i found out that i was not doing anything correctly :slight_smile: … all my apps and games were working fine to the eye … but internally i was not removing variables or objects, timers… events… properly

after reading that article … my code is much better, and i always clear objects successfully

hope this helps

Regards,

Tariq

Unrelated…

I assume this fails because the physics world is locked during collision events:

event.other:removeSelf()

When you say

the game is still going

do you mean that the display objects etc which you added to the scene are still there?

That is what I would expect because you don’t have any code removing any of it.

I think you are running into the classic problem where developers expect a scene to get recycled automatically.

When you add  composer.removeScene() where are you putting it? If you put it within the scene being removed you might hit issues.

You cannot remove the scene you are currently in.  There is no reason to. Calling composer.gotoScene() will hide the current scene when it brings the new scene to view. The only reason to remove a scene is to free memory is the scene is taking up too much, but you remove it after it’s off-screen in that case. The other quasi-legit reason to remove a scene is if you know you’re going back to the scene and you want to do a complete reset of the scene in minimal code.

Rob

i tested your code

before removing the scene you need to cancel the timer that spawns objects, which means you need to assign it to a variable like this

xyz=timer.performWithDelay(mRandom(1500, 4000),spawnObjects, 0)

you would also need a Boolean flag to exit the function like this

somewhere above:

local exitFlag=false&nbsp;

spawn function:

local function spawnObjects() &nbsp; &nbsp; &nbsp; &nbsp; if exitFlag==true then &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return true &nbsp; &nbsp; &nbsp; &nbsp; end &nbsp; &nbsp; &nbsp; &nbsp; local objIdx = mRandom(#objects) &nbsp; &nbsp; &nbsp; &nbsp; local objName = objects[objIdx] &nbsp; &nbsp; &nbsp; &nbsp; local object = display.newImageRect("images/"..objName, 45,45) &nbsp; &nbsp; &nbsp; &nbsp; object.x = mRandom(20, display.actualContentWidth-100) &nbsp; &nbsp; &nbsp; &nbsp; object.y = mRandom(-10, 0) &nbsp; &nbsp; &nbsp; &nbsp; object.rotation = mRandom(-60, -10 ) &nbsp; &nbsp; &nbsp; &nbsp; if objIdx \< 5 then &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; object.type = "food" &nbsp; &nbsp; &nbsp; &nbsp; else &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; object.type = "bomb" &nbsp; &nbsp; &nbsp; &nbsp; end &nbsp; &nbsp; &nbsp; &nbsp; scene.view:insert(object) &nbsp; &nbsp; &nbsp; &nbsp; physics.addBody(object,&nbsp; "dynamic", {density=1, friction = .5, radius = 25}) &nbsp; &nbsp; end

Player Collision function:

local function playerCollision (self, event) &nbsp; &nbsp; &nbsp; &nbsp; if event.phase == "began" then &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if event.other.type == "food" then &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; score = score + 1 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; print(score) &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; else &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; exitFlag=true &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; timer.cancel(xyz) &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; composer.removeScene("main2") &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; composer.gotoScene("main3") &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; end &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; event.other:removeSelf() &nbsp; &nbsp; &nbsp; &nbsp; end &nbsp; &nbsp; end

i have been programming with Corona for 5 years now,i thought i was doing everything correctly, a few months ago i read an article for Rob Miracle on something similar … i found out that i was not doing anything correctly :slight_smile: … all my apps and games were working fine to the eye … but internally i was not removing variables or objects, timers… events… properly

after reading that article … my code is much better, and i always clear objects successfully

hope this helps

Regards,

Tariq