Loading New Scene Before Old Closes

Hi I think I am having problems understanding composer a bit.  How I have been handling scene changes is like this.

I am using the scene template.  Every object be it text or image I add to a table called allObjects then when I need to change screens I use the following type of code below.  I put a print(“screen 1”) right before I use composer.removeScene and print(“screen 2”) right at the beginning of screen 2 and in console I always see screen 2 before screen 1.  Shouldnt composer handle this, like screen2 cannot show until screen 1 is completely destroyed?  

Even with the timer I can see in console output that screen 2 is loading before screen 1 removes itself.  

local function changeScreen(nextScreen) composer.gotoScene(nextScreen) end -- Move to Next Screen local function nextScreen() for t=#allObjects,1,-1 do allObjects[t]:removeSelf() allObjects[t] = nil end changeScreenTimer = timer.performWithDelay( 250, changeScreen("nextScreen"), 1) end end

Just to add now I can see that this error just started to occur after I started to use certain graphics.  Upon closer look at the dimensions of the graphics I can see that they are huge and I am scaling them down from (2538x832) could this be whats causing the problem?  If i change this graphic to any random graphic normal size I do not get this problem.

Firstly, if you add all objects to composer’s scene.view, you don’t need to manually remove them - composer will do this when you call removeScene. I usually call this from the ‘did’ phase of scene:show in the new scene.

Composer can’t remove the old scene before the new is shown because there is the option to have transition effects between the two.

Thanks for this I felt what I was doing was very inefficient.  I have rewritten all the code now with display groups and all code should be in relevant spaces within the scene template.  By any chance can someone please tell me if I have put the elements in the proper places and am handling destroying everything correctly before moving to next scene.

local composer = require( "composer" ) local scene = composer.newScene() -- Hide status bar display.setStatusBar( display.HiddenStatusBar ) -- Set Variables for Device Width and Height local deviceWidth = display.contentWidth local deviceHeight = display.contentHeight --Define All Objects local coinHolder, coinImageHolder, actualCoins, exitButton, pauseWindow, playButton, settingsButton, purchaseButton local difficultyWord, difficultyChooserWindow1, difficultyChooserWindow2, difficultyChooserWindow3, easyChooserWindow local json = require( "json" ) --Load Saved Game Variables local gameFilesPath = system.pathForFile( "gameFiles.json", system.DocumentsDirectory ) local gameFiles = io.open( gameFilesPath, "r") local contents = gameFiles:read( "\*a" ) local gameFilesContents = json.decode( contents ) local coinsFile = gameFilesContents[1] local livesFile = gameFilesContents[2] io.close( gameFiles) --Set Audio Volumes audio.setVolume( gameFilesContents[5], { channel=1 } ) audio.setVolume( gameFilesContents[6], { channel=2 } ) -- Set Sounds local selectLetter selectLetter = audio.loadSound( "select.wav" ) --Global Variables local pause = 0 local backGroup, difficultyGroup --Bring Difficulty Screen To Front local function chooseDifficulty(event) if pause == 0 then audio.play(selectLetter, {channel=2} ) if ( event.phase == "began" ) then pause = 1 difficultyGroup:toFront() coinHolder:toFront() coinImageHolder:toFront() actualCoins:toFront() end end end --Close Difficulty Screen local function closeDifficulty(event) pause = 0 if ( event.phase == "began" ) then audio.play(selectLetter, {channel=2} ) end difficultyGroup:toBack() end -- Move to the Easy Screen local function easyLevelsScreen() if pause == 1 then audio.play(selectLetter, {channel=2} ) composer.gotoScene( "easyLevelChooser" ) end end function scene:create( event ) local sceneGroup = self.view --Set Scene Groups backGroup = display.newGroup() sceneGroup:insert( backGroup ) difficultyGroup = display.newGroup() sceneGroup:insert( difficultyGroup ) -- Set Background local background = display.newImageRect(backGroup, "mainBackground.png", deviceWidth, deviceHeight ) background.x = display.contentCenterX background.y = display.contentCenterY -- Set Bottom Button Holder Image local mainBottom = display.newImageRect(backGroup, "mainBottom.png", deviceWidth\*.75, deviceWidth\*.22) mainBottom.x = display.contentCenterX ; mainBottom.y = deviceHeight\*.82 -- Set Title local titleTop = display.newImageRect(backGroup, "candy.png", deviceWidth\*.456, deviceWidth\*.19) titleTop.x = display.contentCenterX ; titleTop.y = deviceHeight\*.21 local mainMiddleImage = display.newImageRect(backGroup, "mainMiddle.png", deviceWidth\*.2, deviceWidth\*.11) mainMiddleImage.x = deviceWidth\*.6 ; mainMiddleImage.y = deviceHeight\*.35 local titleBottom = display.newImageRect(backGroup, "words.png", deviceWidth\*.456, deviceWidth\*.15) titleBottom.x = display.contentCenterX ; titleBottom.y = deviceHeight\*.47 -- Set Coins And Lives local healthHolder = display.newImageRect(backGroup, "topImageCounter.png", deviceWidth\*.15, deviceWidth\*.072) healthHolder.x = deviceWidth\*.91 ; healthHolder.y = deviceHeight\*.08 local healthImageHolder = display.newImageRect(backGroup, "health.png", deviceWidth\*.035, deviceWidth\*.035) healthImageHolder.x = deviceWidth\*.952 ; healthImageHolder.y = deviceHeight\*.07 coinHolder = display.newImageRect(backGroup, "topImageCounter.png", deviceWidth\*.15, deviceWidth\*.072) coinHolder.x = deviceWidth\*.74 ; coinHolder.y = deviceHeight\*.08 coinImageHolder = display.newImageRect(backGroup, "coin.png", deviceWidth\*.037, deviceWidth\*.037) coinImageHolder.x = deviceWidth\*.782 ; coinImageHolder.y = deviceHeight\*.066 actualCoins = display.newText(backGroup, coinsFile, deviceWidth\*.71, deviceHeight\*.074, "RifficFree-Bold.ttf", 15 ) local actualLives = display.newText(backGroup, livesFile, deviceWidth\*.88, deviceHeight\*.074, "RifficFree-Bold.ttf", 15 ) -- Set Play, Purchase and Settings Buttons playButton = display.newImageRect(backGroup, "playButton.png", deviceWidth\*.15, deviceWidth\*.15 ) playButton.x = display.contentCenterX ; playButton.y = deviceHeight\*.77 settingsButton = display.newImageRect(backGroup, "settingsButton.png", deviceWidth\*.11, deviceWidth\*.11 ) settingsButton.x = (display.contentCenterX-(deviceWidth\*.17)) ; settingsButton.y = deviceHeight\*.8 purchaseButton = display.newImageRect(backGroup, "purchaseButton.png", deviceWidth\*.11, deviceWidth\*.11 ) purchaseButton.x = display.contentCenterX+(deviceWidth\*.17) ; purchaseButton.y = deviceHeight\*.8 -- Declare Variables For Difficulty Chooser Menu exitButton = display.newImageRect(difficultyGroup, "exit.png", deviceWidth\*.08, deviceWidth\*.08 ) pauseWindow = display.newImageRect(difficultyGroup, "pauseWindow.png", deviceWidth\*.82, deviceHeight ) difficultyWord = display.newImageRect(difficultyGroup, "difficulty.png", deviceWidth\*.35, deviceWidth\*.092 ) difficultyChooserWindow1 = display.newImageRect(difficultyGroup, "difficultyChooser4.png", deviceWidth\*.18, deviceHeight\*.49 ) difficultyChooserWindow2 = display.newImageRect(difficultyGroup, "difficultyChooser3.png", deviceWidth\*.18, deviceHeight\*.49 ) difficultyChooserWindow3 = display.newImageRect(difficultyGroup, "difficultyChooser2.png", deviceWidth\*.18, deviceHeight\*.5 ) easyChooserWindow = display.newImageRect(difficultyGroup, "difficultyChooser1.png", deviceWidth\*.18, deviceHeight\*.49 ) --X, Y Coordinates of Difficulty Objects difficultyWord.x = display.contentCenterX ; difficultyWord.y = deviceHeight\*.16 difficultyChooserWindow1.x = deviceWidth\*.78 ; difficultyChooserWindow1.y = deviceHeight\*.61 difficultyChooserWindow2.x = deviceWidth\*.593 ; difficultyChooserWindow2.y = deviceHeight\*.61 difficultyChooserWindow3.x = deviceWidth\*.408 ; difficultyChooserWindow3.y = deviceHeight\*.61 easyChooserWindow.x = deviceWidth\*.222 ; easyChooserWindow.y = deviceHeight\*.61 pauseWindow.x = display.contentCenterX ; pauseWindow.y = display.contentCenterY - (deviceHeight\*.01) exitButton.x = deviceWidth\*.84 ; exitButton.y = deviceHeight\*.23 --Create Event Listeners playButton:addEventListener( "touch", chooseDifficulty ) -- Set Play Button Touch Listener exitButton:addEventListener( "touch", closeDifficulty ) -- Set Exit Screen Button Touch Listener easyChooserWindow:addEventListener( "touch", easyLevelsScreen ) end --Once Screen Loads function scene:show( event ) local sceneGroup = self.view local phase = event.phase if ( phase == "will" ) then elseif ( phase == "did" ) then closeDifficulty("notEvent") --Close Difficulty Elements When Screen Starts end end --Terminate Screen function scene:hide( event ) local sceneGroup = self.view local phase = event.phase if ( phase == "will" ) then elseif ( phase == "did" ) then audio.stop( 2 ) composer.removeScene( "menu" ) end end --Destroy Screen function scene:destroy( event ) local sceneGroup = self.view package.loaded["json"] = nil selectLetter = nil audio.dispose( selectLetter ) selectLetter = nil end -- Scene event function listeners scene:addEventListener( "create", scene ) scene:addEventListener( "show", scene ) scene:addEventListener( "hide", scene ) scene:addEventListener( "destroy", scene ) return scene

Firstly, if you add all objects to composer’s scene.view, you don’t need to manually remove them - composer will do this when you call removeScene. I usually call this from the ‘did’ phase of scene:show in the new scene.

Composer can’t remove the old scene before the new is shown because there is the option to have transition effects between the two.

Thanks for this I felt what I was doing was very inefficient.  I have rewritten all the code now with display groups and all code should be in relevant spaces within the scene template.  By any chance can someone please tell me if I have put the elements in the proper places and am handling destroying everything correctly before moving to next scene.

local composer = require( "composer" ) local scene = composer.newScene() -- Hide status bar display.setStatusBar( display.HiddenStatusBar ) -- Set Variables for Device Width and Height local deviceWidth = display.contentWidth local deviceHeight = display.contentHeight --Define All Objects local coinHolder, coinImageHolder, actualCoins, exitButton, pauseWindow, playButton, settingsButton, purchaseButton local difficultyWord, difficultyChooserWindow1, difficultyChooserWindow2, difficultyChooserWindow3, easyChooserWindow local json = require( "json" ) --Load Saved Game Variables local gameFilesPath = system.pathForFile( "gameFiles.json", system.DocumentsDirectory ) local gameFiles = io.open( gameFilesPath, "r") local contents = gameFiles:read( "\*a" ) local gameFilesContents = json.decode( contents ) local coinsFile = gameFilesContents[1] local livesFile = gameFilesContents[2] io.close( gameFiles) --Set Audio Volumes audio.setVolume( gameFilesContents[5], { channel=1 } ) audio.setVolume( gameFilesContents[6], { channel=2 } ) -- Set Sounds local selectLetter selectLetter = audio.loadSound( "select.wav" ) --Global Variables local pause = 0 local backGroup, difficultyGroup --Bring Difficulty Screen To Front local function chooseDifficulty(event) if pause == 0 then audio.play(selectLetter, {channel=2} ) if ( event.phase == "began" ) then pause = 1 difficultyGroup:toFront() coinHolder:toFront() coinImageHolder:toFront() actualCoins:toFront() end end end --Close Difficulty Screen local function closeDifficulty(event) pause = 0 if ( event.phase == "began" ) then audio.play(selectLetter, {channel=2} ) end difficultyGroup:toBack() end -- Move to the Easy Screen local function easyLevelsScreen() if pause == 1 then audio.play(selectLetter, {channel=2} ) composer.gotoScene( "easyLevelChooser" ) end end function scene:create( event ) local sceneGroup = self.view --Set Scene Groups backGroup = display.newGroup() sceneGroup:insert( backGroup ) difficultyGroup = display.newGroup() sceneGroup:insert( difficultyGroup ) -- Set Background local background = display.newImageRect(backGroup, "mainBackground.png", deviceWidth, deviceHeight ) background.x = display.contentCenterX background.y = display.contentCenterY -- Set Bottom Button Holder Image local mainBottom = display.newImageRect(backGroup, "mainBottom.png", deviceWidth\*.75, deviceWidth\*.22) mainBottom.x = display.contentCenterX ; mainBottom.y = deviceHeight\*.82 -- Set Title local titleTop = display.newImageRect(backGroup, "candy.png", deviceWidth\*.456, deviceWidth\*.19) titleTop.x = display.contentCenterX ; titleTop.y = deviceHeight\*.21 local mainMiddleImage = display.newImageRect(backGroup, "mainMiddle.png", deviceWidth\*.2, deviceWidth\*.11) mainMiddleImage.x = deviceWidth\*.6 ; mainMiddleImage.y = deviceHeight\*.35 local titleBottom = display.newImageRect(backGroup, "words.png", deviceWidth\*.456, deviceWidth\*.15) titleBottom.x = display.contentCenterX ; titleBottom.y = deviceHeight\*.47 -- Set Coins And Lives local healthHolder = display.newImageRect(backGroup, "topImageCounter.png", deviceWidth\*.15, deviceWidth\*.072) healthHolder.x = deviceWidth\*.91 ; healthHolder.y = deviceHeight\*.08 local healthImageHolder = display.newImageRect(backGroup, "health.png", deviceWidth\*.035, deviceWidth\*.035) healthImageHolder.x = deviceWidth\*.952 ; healthImageHolder.y = deviceHeight\*.07 coinHolder = display.newImageRect(backGroup, "topImageCounter.png", deviceWidth\*.15, deviceWidth\*.072) coinHolder.x = deviceWidth\*.74 ; coinHolder.y = deviceHeight\*.08 coinImageHolder = display.newImageRect(backGroup, "coin.png", deviceWidth\*.037, deviceWidth\*.037) coinImageHolder.x = deviceWidth\*.782 ; coinImageHolder.y = deviceHeight\*.066 actualCoins = display.newText(backGroup, coinsFile, deviceWidth\*.71, deviceHeight\*.074, "RifficFree-Bold.ttf", 15 ) local actualLives = display.newText(backGroup, livesFile, deviceWidth\*.88, deviceHeight\*.074, "RifficFree-Bold.ttf", 15 ) -- Set Play, Purchase and Settings Buttons playButton = display.newImageRect(backGroup, "playButton.png", deviceWidth\*.15, deviceWidth\*.15 ) playButton.x = display.contentCenterX ; playButton.y = deviceHeight\*.77 settingsButton = display.newImageRect(backGroup, "settingsButton.png", deviceWidth\*.11, deviceWidth\*.11 ) settingsButton.x = (display.contentCenterX-(deviceWidth\*.17)) ; settingsButton.y = deviceHeight\*.8 purchaseButton = display.newImageRect(backGroup, "purchaseButton.png", deviceWidth\*.11, deviceWidth\*.11 ) purchaseButton.x = display.contentCenterX+(deviceWidth\*.17) ; purchaseButton.y = deviceHeight\*.8 -- Declare Variables For Difficulty Chooser Menu exitButton = display.newImageRect(difficultyGroup, "exit.png", deviceWidth\*.08, deviceWidth\*.08 ) pauseWindow = display.newImageRect(difficultyGroup, "pauseWindow.png", deviceWidth\*.82, deviceHeight ) difficultyWord = display.newImageRect(difficultyGroup, "difficulty.png", deviceWidth\*.35, deviceWidth\*.092 ) difficultyChooserWindow1 = display.newImageRect(difficultyGroup, "difficultyChooser4.png", deviceWidth\*.18, deviceHeight\*.49 ) difficultyChooserWindow2 = display.newImageRect(difficultyGroup, "difficultyChooser3.png", deviceWidth\*.18, deviceHeight\*.49 ) difficultyChooserWindow3 = display.newImageRect(difficultyGroup, "difficultyChooser2.png", deviceWidth\*.18, deviceHeight\*.5 ) easyChooserWindow = display.newImageRect(difficultyGroup, "difficultyChooser1.png", deviceWidth\*.18, deviceHeight\*.49 ) --X, Y Coordinates of Difficulty Objects difficultyWord.x = display.contentCenterX ; difficultyWord.y = deviceHeight\*.16 difficultyChooserWindow1.x = deviceWidth\*.78 ; difficultyChooserWindow1.y = deviceHeight\*.61 difficultyChooserWindow2.x = deviceWidth\*.593 ; difficultyChooserWindow2.y = deviceHeight\*.61 difficultyChooserWindow3.x = deviceWidth\*.408 ; difficultyChooserWindow3.y = deviceHeight\*.61 easyChooserWindow.x = deviceWidth\*.222 ; easyChooserWindow.y = deviceHeight\*.61 pauseWindow.x = display.contentCenterX ; pauseWindow.y = display.contentCenterY - (deviceHeight\*.01) exitButton.x = deviceWidth\*.84 ; exitButton.y = deviceHeight\*.23 --Create Event Listeners playButton:addEventListener( "touch", chooseDifficulty ) -- Set Play Button Touch Listener exitButton:addEventListener( "touch", closeDifficulty ) -- Set Exit Screen Button Touch Listener easyChooserWindow:addEventListener( "touch", easyLevelsScreen ) end --Once Screen Loads function scene:show( event ) local sceneGroup = self.view local phase = event.phase if ( phase == "will" ) then elseif ( phase == "did" ) then closeDifficulty("notEvent") --Close Difficulty Elements When Screen Starts end end --Terminate Screen function scene:hide( event ) local sceneGroup = self.view local phase = event.phase if ( phase == "will" ) then elseif ( phase == "did" ) then audio.stop( 2 ) composer.removeScene( "menu" ) end end --Destroy Screen function scene:destroy( event ) local sceneGroup = self.view package.loaded["json"] = nil selectLetter = nil audio.dispose( selectLetter ) selectLetter = nil end -- Scene event function listeners scene:addEventListener( "create", scene ) scene:addEventListener( "show", scene ) scene:addEventListener( "hide", scene ) scene:addEventListener( "destroy", scene ) return scene