Clearing a scene correctly..

hey hey…

I know this has been addressed before and I’ve tried this any which number of ways from what I’ve read on a number of other posts on the forums… 

So I’ve got a simple little back and forth going on… character goes up an escalator, emerges in a scene… great, works a treat… goes back down and emerges in the original scene… looks great…

Do it twice and and the onCollision no longer functions… so all I can assume is that as there are two variables, they’ve fired twice and that’s the end of that… 

I’ve read that using an interim scene may help this… so I’ve included a couple of these… pretty straight forward stuff… clear the scene, load the next one…  This works well the first time around with a nice little fade… but the second time around there’s a sharp changing of scenes… like it’s not functioning correctly anymore…

What’s interesting is the console output I’m getting from the collision on the second time for both… first time, just one… second, multiple hits…

16:18:45.612  White square’s top-left position in screen coordinates: 50

16:18:46.156  hit!

16:18:49.388  White square’s top-left position in screen coordinates: 312

16:18:49.701  fish!!

16:18:53.042  White square’s top-left position in screen coordinates: 50

16:18:53.546  hit!

16:18:53.546  hit!

16:18:53.546  hit!

16:18:56.581  White square’s top-left position in screen coordinates: 312

16:18:56.947  fish!!

16:18:56.947  fish!!

16:18:56.947  fish!!

16:18:56.947  fish!!

16:18:56.947  fish!!

16:18:56.947  fish!!

Anyway, here’s the code… any thoughts would be greatly appreciated…

stationv1.lua

local composer = require( "composer" ) local manSprite = require "images.man" local physics = require("physics") physics.start() physics.setGravity( 0, 0 ) local alienSheet = graphics.newImageSheet( "images/man2sprites.png", manSprite.sheetData ) local sequences\_alienWalk = { -- consecutive frames sequence { name = "alienWalk", start = 1, count = 7, time = 800, loopCount = 0, loopDirection = "forward" } } local function characterWalk( event ) local thisSprite = event.target -- "event.target" references the sprite if ( event.phase == "ended" ) then thisSprite:setSequence( "alienWalk" ) -- switch to "fastRun" sequence thisSprite:play() -- play the new sequence end end local function onTouch(event) if ( event.phase == "began" ) then alienWalk:play() print( "White square's top-left position in screen coordinates: ", alienWalk.x ) elseif(event.phase == "ended" and event.x \> alienWalk.x) then alienWalk.xScale = 1 transition.to(alienWalk, { x=event.x, onComplete = function () alienWalk:pause() -- body end }) elseif(event.phase == "ended" and event.x \< alienWalk.x) then alienWalk.xScale = -1 transition.to(alienWalk, { x=event.x, onComplete = function () alienWalk:pause() -- body end }) end end local scene = composer.newScene() local function onCollision( event ) if ( event.phase == "began" ) then local obj1 = event.object1 local obj2 = event.object2 if ( ( obj1.myName == "escalator" and obj2.myName == "alienWalk" ) or ( obj1.myName == "alienWalk" and obj2.myName == "escalator" ) ) then transition.to(alienWalk, { time=1500, x=980, y=380, onComplete = function () composer.removeScene ( "scenes.stationv1" ) composer.gotoScene( "scenes.interim", { time=800, effect="crossFade" } ) end }) print("hit!") end end end function scene:create( event ) local sceneGroup = self.view local backGroup = display.newGroup() sceneGroup:insert( backGroup ) local trainGroup = display.newGroup() sceneGroup:insert( trainGroup ) local stationGroup = display.newGroup() sceneGroup:insert( stationGroup ) local characterGroup = display.newGroup() sceneGroup:insert( characterGroup ) local foreGroup = display.newGroup() -- Display group for the ship, asteroids, lasers, etc. sceneGroup:insert( foreGroup ) -- Code here runs when the scene is first created but has not yet appeared on screen local background = display.newImageRect( backGroup, "images/platform.png", display.contentWidth, display.contentHeight ) background.x = display.contentCenterX background.y = display.contentCenterY local escalator = display.newRect( characterGroup, 850, 640, 10, 150 ) escalator:setFillColor( 255,0,0 ) escalator.alpha = 0 escalator.isHitTestable = true escalator.id = 1 physics.addBody( escalator, { radius=10, isSensor=true } ) escalator.myName = "escalator" esco = display.newImageRect( foreGroup, "images/esco.png", 350, 380 ) esco.x = 860 esco.y = display.contentCenterY + 155 esco.alpha = 1 alienWalk = display.newSprite( characterGroup, alienSheet, sequences\_alienWalk ) alienWalk.x = 50 alienWalk.y = display.contentCenterY + 190 alienWalk.isVisible = true alienWalk.id = 61 physics.addBody( alienWalk, { radius=100, isSensor=true } ) alienWalk.xScale = 1 alienWalk.myName = "alienWalk" -- alienWalk:setLinearVelocity( 10, 4 ) alienWalk:addEventListener( "sprite", characterWalk ) end -- show() function scene:show( event ) local sceneGroup = self.view local phase = event.phase if ( phase == "will" ) then -- Code here runs when the scene is still off screen (but is about to come on screen) elseif ( phase == "did" ) then -- Code here runs when the scene is entirely on screen Runtime:addEventListener("touch", onTouch) Runtime:addEventListener( "collision", onCollision ) -- composer.removeScene( "scenes.stationv1") end end -- hide() function scene:hide( event ) local sceneGroup = self.view local phase = event.phase if ( phase == "will" ) then -- Code here runs when the scene is on screen (but is about to go off screen) elseif ( phase == "did" ) then Runtime:addEventListener("touch", onTouch) Runtime:addEventListener( "collision", onCollision ) physics.pause() composer.removeScene ("scenes.stationv1") -- Code here runs immediately after the scene goes entirely off screen end end -- destroy() function scene:destroy( event ) local sceneGroup = self.view -- Code here runs prior to the removal of scene's view end -- ----------------------------------------------------------------------------------- -- Scene event function listeners -- ----------------------------------------------------------------------------------- scene:addEventListener( "create", scene ) scene:addEventListener( "show", scene ) scene:addEventListener( "hide", scene ) scene:addEventListener( "destroy", scene ) -- ----------------------------------------------------------------------------------- return scene

interim.lua

local composer = require( "composer" ) local scene = composer.newScene() function scene:create( event ) local sceneGroup = self.view end -- show() function scene:show( event ) local sceneGroup = self.view local phase = event.phase if ( phase == "will" ) then -- Code here runs when the scene is still off screen (but is about to come on screen) elseif ( phase == "did" ) then composer.removeScene ( "scenes.stationv1" ) composer.gotoScene( "scenes.fishhill", { time=400, effect="crossFade" } ) end end -- hide() function scene:hide( event ) local sceneGroup = self.view local phase = event.phase if ( phase == "will" ) then elseif ( phase == "did" ) then composer.removeScene ( "scenes.interim" ) end end

fishhill.lua

local composer = require( "composer" ) local manSprite = require "images.man" local physics = require("physics") local function onCollision( event ) if ( event.phase == "began" ) then local obj1 = event.object1 local obj2 = event.object2 if ( ( obj1.myName == "esco2" and obj2.myName == "alienWalk" ) or ( obj1.myName == "alienWalk" and obj2.myName == "esco2" ) ) then transition.to(alienWalk, { time=1500, x=20, y=display.contentCenterY +500, onComplete = function () -- composer.removeScene( "scenes.fishhill" ) composer.gotoScene( "scenes.interim2", { time=800, effect="crossFade" } ) end }) print("fish!!") end end end local alienSheet = graphics.newImageSheet( "images/man2sprites.png", manSprite.sheetData ) local sequences\_alienWalk = { -- consecutive frames sequence { name = "alienWalk", start = 1, count = 7, time = 800, loopCount = 0, loopDirection = "forward" } } local function characterWalk( event ) local thisSprite = event.target -- "event.target" references the sprite if ( event.phase == "ended" ) then thisSprite:setSequence( "alienWalk" ) -- switch to "fastRun" sequence thisSprite:play() -- play the new sequence end end local function onTouch(event) if ( event.phase == "began" ) then alienWalk:play() print( "White square's top-left position in screen coordinates: ", alienWalk.x ) elseif(event.phase == "ended" and event.x \> alienWalk.x) then alienWalk.xScale = 1 transition.to(alienWalk, { x=event.x, onComplete = function () alienWalk:pause() -- body end }) elseif(event.phase == "ended" and event.x \< alienWalk.x) then alienWalk.xScale = -1 transition.to(alienWalk, { x=event.x, onComplete = function () alienWalk:pause() -- body end }) end end local scene = composer.newScene() function scene:create( event ) local sceneGroup = self.view local backGroup = display.newGroup() sceneGroup:insert( backGroup ) local trainGroup = display.newGroup() sceneGroup:insert( trainGroup ) local stationGroup = display.newGroup() sceneGroup:insert( stationGroup ) local characterGroup = display.newGroup() sceneGroup:insert( characterGroup ) local foreGroup = display.newGroup() -- Display group for the ship, asteroids, lasers, etc. sceneGroup:insert( foreGroup ) -- Code here runs when the scene is first created but has not yet appeared on screen local background = display.newImageRect( backGroup, "images/fishhill.png", display.contentWidth, display.contentHeight ) background.x = display.contentCenterX background.y = display.contentCenterY local esco2 = display.newRect( characterGroup, display.contentCenterX - 365, display.contentCenterY + 215, 10, 100 ) esco2:setFillColor( 255,0,0 ) esco2.alpha = 1 esco2.isHitTestable = true esco2.id = 1 physics.addBody( esco2, { radius=10, isSensor=true } ) esco2.myName = "esco2" local subway1 = display.newImageRect( stationGroup, "images/subway1.png", 250, 600) subway1.x = display.contentCenterX - 385 subway1.y = display.contentCenterY + 95 local subway2 = display.newImageRect( foreGroup, "images/subway2.png", 250, 600) subway2.x = display.contentCenterX - 385 subway2.y = display.contentCenterY + 95 subway2.alpha = 1 alienWalk = display.newSprite( characterGroup, alienSheet, sequences\_alienWalk ) alienWalk.x = display.contentCenterX - 200 alienWalk.y = display.contentCenterY + 220 alienWalk.isVisible = true alienWalk.id = 61 physics.addBody( alienWalk, { radius=50, isSensor=true } ) alienWalk.xScale = 1 alienWalk.myName = "alienWalk" -- alienWalk:setLinearVelocity( 10, 4 ) alienWalk:addEventListener( "sprite", characterWalk ) end -- show() function scene:show( event ) local sceneGroup = self.view local phase = event.phase if ( phase == "will" ) then -- Code here runs when the scene is still off screen (but is about to come on screen) elseif ( phase == "did" ) then -- Code here runs when the scene is entirely on screen physics.start() physics.setGravity( 0, 0 ) Runtime:addEventListener("touch", onTouch) Runtime:addEventListener( "collision", onCollision ) -- composer.removeScene( "scenes.stationv1") end end -- hide() function scene:hide( event ) local sceneGroup = self.view local phase = event.phase if ( phase == "will" ) then -- Code here runs when the scene is on screen (but is about to go off screen) elseif ( phase == "did" ) then -- Code here runs immediately after the scene goes entirely off screen Runtime:addEventListener("touch", onTouch) Runtime:addEventListener( "collision", onCollision ) composer.removeScene( "scenes.fishhill" ) physics.pause() end end

interim2.lua

local composer = require( "composer" ) local scene = composer.newScene() function scene:create( event ) local sceneGroup = self.view -- Code here runs when the scene is first created but has not yet appeared on screen end -- show() function scene:show( event ) local sceneGroup = self.view local phase = event.phase if ( phase == "will" ) then -- Code here runs when the scene is still off screen (but is about to come on screen) elseif ( phase == "did" ) then composer.removeScene ( "scenes.fishhill" ) composer.gotoScene( "scenes.stationv1", { time=400, effect="crossFade" } ) end end -- hide() function scene:hide( event ) local sceneGroup = self.view local phase = event.phase if ( phase == "will" ) then -- Code here runs when the scene is on screen (but is about to go off screen) elseif ( phase == "did" ) then composer.removeScene ( "scenes.interim2" ) end end

Your first problem is that main.lua should not be used as a scene. All main.lua should do is some light initialisation work before calling composer to load whatever is your first scene.

Sorry about that… sometimes you look at things so many times you don’t see it anymore…

That was just a commented out section, it wasn’t main.lua… just a hangover from when I first started the project and was mucking around with movement… I’ve now removed that from the code dump to clear up any confusion…

Like I say, very very basic at the moment… I’m trying to confirm certain aspects work before attempting to implement things further…

Actual main.lua…

----------------------------------------------------------------------------------------- -- -- main.lua -- Alphagame ----------------------------------------------------------------------------------------- -- Your code here local composer = require( "composer" ) -- Hide status bar display.setStatusBar( display.HiddenStatusBar ) composer.gotoScene( "scenes.stationv1" )

Ok, another issue is deleting a scene within itself. What you need to do is put this in scene:show(), “did” phase of each scene:

[lua]

local previous = composer.getSceneName(“previous”)

    if previous ~= “main” and previous then

      composer.removeScene(previous, false)

    end

[/lua]

What I do when moving scenes is check whether the name of the current scene is the name of the scene I’m going to. If so, I redirect to a scene called loading.lua and store the name of the scene I want to go to in my globals table, which loading then uses to decide which scene to load.

This is the show() function of my loading.lua:

[lua]

function scene:show(event)

    grp.main = self.view

    local phase = event.phase

    if phase == “will” then

    local previous = composer.getSceneName(“previous”)

        if previous ~= “main” and previous then

             print ("DELETE SCENE: "…previous)

            composer.removeScene(previous, false)

        end

    end

    if phase == “did” then

        local delayIt=  function ()

          sceneManager.gotoScene(glo.nextScene, event.params, nil, true)

        end

        timer.performWithDelay(10, delayIt)

    end

end

[/lua]

Another issue that you have concerning those prints “hit!” and “fish!” is that you don’t set any limits to the collisions AND you fire them using a function after a transition.

Take a look at this.

local function onCollision( event ) if ( event.phase == "began" ) then local obj1 = event.object1 local obj2 = event.object2 if ( ( obj1.myName == "escalator" and obj2.myName == "alienWalk" ) or ( obj1.myName == "alienWalk" and obj2.myName == "escalator" ) ) then transition.to(alienWalk, { time=1500, x=980, y=380, onComplete = function () composer.removeScene ( "scenes.stationv1" ) composer.gotoScene( "scenes.interim", { time=800, effect="crossFade" } ) end }) print("hit!") end end end

Whenever a collision that meets with your requirements occurs, then you start that transition. Unless you cancel these transitions, they will carry out until the end even if the object being transitioned were destroyed. So, each time a new transition starts, the code will try to remove the scene and go to another scene.

You could simply create a variable like  hasCollided and set it to false. Once the first collision occurs, then set it to true and prevent any further collisions from triggering.

Also, you can’t delete the scene you are in. However, since you seem to want to remove the scenes whenever you move between scenes, you could just set composer to automatically recycle scenes on change (https://docs.coronalabs.com/api/library/composer/recycleOnSceneChange.html). This way, you won’t need to do it every time manually.

Thanks for having a look for me…

I’ve attempted to both of the above changes suggested…

I also removed the ‘composer.removeScene ( “scenes.whatever” )’ from the Collision event…

The only appreciable change is that the collision now occurs only once… interestingly, when I put it back into the Collision event, I get a second collision again… 

@Spyric - With regards to the transition… I want the scene change to occur after the transition has completed… the object itself shouldn’t be destroyed… this is a character walking and moving into another scene… the transition is a ‘cheat’ to make a them just move up an escalator… I’m not wedded to the transition… an exit is an exit…  I’m just using the collision as a means of triggering movement to the next scene… 

To be honest, I don’t necessarily want to completely remove the scenes whenever I move between them, I’m just looking for a way at this point to ‘reset’ my collision so you could theoretically up and down the escalator forever (it’s for my kid… that boy could do that shit for hours) instead of just twice… clearly the scene from memory seemed like a way to make this happen… 

Another reason that I went down the path of trying to clear the scene is that say for example I attempt to go to a third scene that is completely un-related to the actions these two… then it looks like it’s still trying to perform actions from the original scene… 

Character operates a keypad for example… 

stationv1.lua is the first scene… character just moves on an x axis,  which is using ‘touch’ for movement… a ‘tap’ to open up the keypad… 

alphabet.lua is the keypad… which is a lot of ‘touch’ functions for the alphapad… the first ‘touch’ throws up an error like it’s still attempting to perform a movement in the previous scene…

21:20:38.142  ERROR: Runtime error

21:20:38.142  C:\Users\Manderley\Documents\Corona Projects\alphatrain-side\scenes\stationv1.lua:69: attempt to call method ‘pause’ (a nil value)

21:20:38.142  stack traceback:

21:20:38.142  C:\Users\Manderley\Documents\Corona Projects\alphatrain-side\scenes\stationv1.lua:69: in function <C:\Users\Manderley\Documents\Corona Projects\alphatrain-side\scenes\stationv1.lua:68>

21:20:38.142  (tail call): ?

21:20:38.142  ?: in function ‘?’

21:20:38.142  ?: in function <?:190>

So while I _should _have left that scene behind, though still in memory, it seems like the functions are still attempting to operate in the new scene… 

Using cut scenes or removing a scene so you can reenter it fresh is a short cut. It’s a way for developers to do things that save the developer time at the price of more work on the CPU/GPU. Loading scenes fresh is costly, but every good developer looks for ways to save writing excessive code.

Corona scene’s were designed to actually not be removed. Caching scenes you know your going back to is a design feature for Composer (and previously with Storyboard).

I know this is extra work, but consider that:

scene:create() is for creating objects that will be on screen when the scene begins,

scene:show()'s “will” phase is a good time to position those object that may have moved the last time the scene was on screen. This includes, perhaps your initial placement, which people usually want to do in scene:create(). Maybe start physics here but pause it right away. This keeps things from moving until you’ve had a chance to get the scene on the actual screen.

scene:show()'s “did” phase is a good time to add physics bodies to the objects and re-start physics. start your timers, transitions, etc.

When the level is over, in

scene:hide()'s “will” phase, pause physics, remove the physics bodies. stop your timers, transitions etc.

It’s extra work, but you don’t have to worry about if your scene exists or not. You don’t have to worry about removing scenes.

Honestly it’s not really that much more code, it’s about re-thinking when you do things. The typical creation process is:

object = display.newSomething()

object.x = startingX

object.y = startingY

physics.addBody(object,…)

So now in scene:create()

object.display.newSomething()

in scene:show()'s “will” phase:

object.x = startingX

object.y = startingY

in scene:show()'s “did” phase:

physics.addBody(object,…)

Thanks all for your advice… I basically started again and went back over it piece by piece and managed to get it working… 

I’ve followed Robs advice in breaking things up - which is good practice, but I’m not sure was the cause of my issue here…

Issues I think I identified in my app, 

  • Can’t use the same object names in consecutive scenes… I haven’t progressed too much further in creating more to see how much of this continues but it definitely seemed to cause issues…

  • Added timer.performWithDelay in the Collision to ensure that it has time to complete correctly…

  • As I said before, sometimes you look at things so many times you don’t see them anymore…

Previously when the scene was being hidden I was still adding event listeners!.. like an idiot… 

function scene:hide( event ) local sceneGroup = self.view local phase = event.phase if ( phase == "will" ) then -- Code here runs when the scene is on screen (but is about to go off screen) elseif ( phase == "did" ) then -- Code here runs immediately after the scene goes entirely off screen Runtime:addEventListener("touch", onTouch) Runtime:addEventListener( "collision", onCollision ) composer.removeScene( "scenes.fishhill" ) physics.pause()

Full working now for those are interested… any tidy up suggestions would be greatly appreciated…

Different lua names, same base concept…

nicollStation.lua

----------------------------------------------------------------------------------------- -- -- nicollStation.lua -- ----------------------------------------------------------------------------------------- -- Your code here local composer = require( "composer" ) local manSprite = require "images.man" local physics = require("physics") local scene = composer.newScene() local machine local escalator local alphabetScreen local charStation local esco local function gotoMachine() composer.gotoScene ( "scenes.alphabet", { time=500, effect="crossFade" } ) end local function gotonicollOutside() transition.to(charStation, { time=1500, x=980, y=380, onComplete = function () composer.gotoScene ( "scenes.nicollOutside", { time=500, effect="crossFade" } ) end }) end local charSheet = graphics.newImageSheet( "images/man2sprites.png", manSprite.sheetData ) local sequences\_charStation = { -- consecutive frames sequence { name = "walkWalk", start = 1, count = 7, time = 800, loopCount = 0, loopDirection = "forward" } } local function characterWalk( event ) local thisSprite = event.target -- "event.target" references the sprite if ( event.phase == "ended" ) then thisSprite:setSequence( "walkWalk" ) -- switch to "fastRun" sequence thisSprite:play() -- play the new sequence end end local function onTouch(event) if ( event.phase == "began" ) then charStation:play() print( "Characters top-left position in screen coordinates: ", charStation.x ) elseif(event.phase == "ended" and event.x \> charStation.x) then charStation.xScale = 1 transition.to(charStation, { x=event.x, onComplete = function () charStation:pause() -- body end }) elseif(event.phase == "ended" and event.x \< charStation.x) then print( "Characters top-left position in screen coordinates: ", charStation.x ) charStation.xScale = -1 transition.to(charStation, { x=event.x, onComplete = function () charStation:pause() -- body end }) end end local function onCollision( event ) if ( event.phase == "began" ) then local obj1 = event.object1 local obj2 = event.object2 if ( ( obj1.myName == "escalator" and obj2.myName == "charStation" ) or ( obj1.myName == "charStation" and obj2.myName == "escalator" ) ) then print("Escalator up") charStation:pause() timer.performWithDelay(20, gotonicollOutside ) end -- elseif -- ( ( obj1.myName == "alphabetScreen" and obj2.myName == "alienWalk" ) or -- ( obj1.myName == "alienWalk" and obj2.myName == "alphabetScreen" ) ) -- then -- alphabetScreen.isVisible = true -- print("Ticket machine") elseif (event.phase == "ended") then print("Station collision ended") end end function scene:create( event ) local sceneGroup = self.view local backGroup = display.newGroup() sceneGroup:insert( backGroup ) local trainGroup = display.newGroup() sceneGroup:insert( trainGroup ) local stationGroup = display.newGroup() sceneGroup:insert( stationGroup ) local characterGroup = display.newGroup() sceneGroup:insert( characterGroup ) local foreGroup = display.newGroup() -- Display group for the ship, asteroids, lasers, etc. sceneGroup:insert( foreGroup ) -- Code here runs when the scene is first created but has not yet appeared on screen local background = display.newImageRect( backGroup, "images/platform.png", display.contentWidth, display.contentHeight ) background.x = display.contentCenterX background.y = display.contentCenterY -- Station -- Platform machine = display.newImageRect (characterGroup, "images/full-machine.png", 250, 350 ) escalator = display.newRect( characterGroup, 850, 640, 10, 150 ) alphabetScreen = display.newImageRect (characterGroup, "images/small-keypad.png", 50, 100 ) charStation = display.newSprite( characterGroup, charSheet, sequences\_charStation ) -- Foreground esco = display.newImageRect( foreGroup, "images/esco.png", 350, 380 ) end -- show() function scene:show( event ) local sceneGroup = self.view local phase = event.phase if ( phase == "will" ) then -- Code here runs when the scene is still off screen (but is about to come on screen) escalator:setFillColor( 255,0,0 ) escalator.alpha = 0 escalator.isHitTestable = true escalator.id = 1 escalator.myName = "escalator" esco.x = 860 esco.y = display.contentCenterY + 155 esco.alpha = 1 machine.x = display.contentCenterY - 250 machine.y = display.contentCenterY + 120 alphabetScreen.x = display.contentCenterY - 270 alphabetScreen.y = display.contentCenterY + 75 alphabetScreen.myName = "alphabetScreen" alphabetScreen.isVisible = false alphabetScreen.isHitTestable = true charStation.x = display.contentCenterX charStation.y = display.contentCenterY + 190 charStation.isVisible = true charStation.id = 61 charStation.xScale = 1 charStation.myName = "charStation" -- alienWalk:setLinearVelocity( 10, 4 ) elseif ( phase == "did" ) then -- Code here runs when the scene is entirely on screen physics.start() physics.setGravity( 0, 0 ) physics.addBody( charStation, { radius=100, isSensor=true } ) physics.addBody( alphabetScreen, { radius=100, isSensor=true } ) physics.addBody( escalator, { radius=10, isSensor=true } ) -- Event Listeners Runtime:addEventListener("touch", onTouch) Runtime:addEventListener( "collision", onCollision ) charStation:addEventListener( "sprite", characterWalk ) alphabetScreen:addEventListener ("tap", gotoMachine) end end -- hide() function scene:hide( event ) local sceneGroup = self.view local phase = event.phase if ( phase == "will" ) then -- Code here runs when the scene is on screen (but is about to go off screen) elseif ( phase == "did" ) then physics.pause() Runtime:removeEventListener("touch", onTouch) Runtime:removeEventListener( "collision", onCollision ) charStation:removeEventListener( "sprite", characterWalk ) composer.removeScene ("scenes.nicollStation") -- Code here runs immediately after the scene goes entirely off screen end end -- destroy() function scene:destroy( event ) local sceneGroup = self.view -- Code here runs prior to the removal of scene's view end -- ----------------------------------------------------------------------------------- -- Scene event function listeners -- ----------------------------------------------------------------------------------- scene:addEventListener( "create", scene ) scene:addEventListener( "show", scene ) scene:addEventListener( "hide", scene ) scene:addEventListener( "destroy", scene ) -- ----------------------------------------------------------------------------------- return scene

nicollOutside.lua

----------------------------------------------------------------------------------------- -- -- nicollOutside.lua -- ----------------------------------------------------------------------------------------- -- Your code here local composer = require( "composer" ) local manSprite = require "images.man" local physics = require("physics") local scene = composer.newScene() local stepsNicoll local subway1 local subway2 local charNicoll local function gotoNicollStation() transition.to(charNicoll, { time=1500, x=-100, y=980, onComplete = function () composer.gotoScene ( "scenes.nicollStation", { time=500, effect="crossFade" } ) end }) end local charSheet = graphics.newImageSheet( "images/man2sprites.png", manSprite.sheetData ) local sequences\_charStation = { -- consecutive frames sequence { name = "walkWalk", start = 1, count = 7, time = 800, loopCount = 0, loopDirection = "forward" } } local function characterWalk( event ) local thisSprite = event.target -- "event.target" references the sprite if ( event.phase == "ended" ) then thisSprite:setSequence( "walkWalk" ) -- switch to "fastRun" sequence thisSprite:play() -- play the new sequence end end local function onTouch(event) if ( event.phase == "began" ) then charNicoll:play() print( "Characters top-left position in screen coordinates: ", charNicoll.x ) elseif(event.phase == "ended" and event.x \> charNicoll.x) then charNicoll.xScale = 1 transition.to(charNicoll, { x=event.x, onComplete = function () charNicoll:pause() -- body end }) elseif(event.phase == "ended" and event.x \< charNicoll.x) then charNicoll.xScale = -1 transition.to(charNicoll, { x=event.x, onComplete = function () charNicoll:pause() -- body end }) end end local function onCollision( event ) if ( event.phase == "began" ) then local obj1 = event.object1 local obj2 = event.object2 if ( ( obj1.myName == "stepsNicoll" and obj2.myName == "charNicoll" ) or ( obj1.myName == "charNicoll" and obj2.myName == "stepsNicoll" ) ) then print("Steps down to station") charNicoll:pause() timer.performWithDelay(20, gotoNicollStation ) end elseif (event.phase == "ended") then print("Station collision ended") end end function scene:create( event ) local sceneGroup = self.view local backGroup = display.newGroup() sceneGroup:insert( backGroup ) local trainGroup = display.newGroup() sceneGroup:insert( trainGroup ) local stationGroup = display.newGroup() sceneGroup:insert( stationGroup ) local characterGroup = display.newGroup() sceneGroup:insert( characterGroup ) local foreGroup = display.newGroup() -- Display group for the ship, asteroids, lasers, etc. sceneGroup:insert( foreGroup ) -- Code here runs when the scene is first created but has not yet appeared on screen local background = display.newImageRect( backGroup, "images/fishhill.png", display.contentWidth, display.contentHeight ) background.x = display.contentCenterX background.y = display.contentCenterY stepsNicoll = display.newRect( characterGroup, display.contentCenterX - 365, display.contentCenterY + 215, 10, 100 ) subway1 = display.newImageRect( stationGroup, "images/subway1.png", 250, 600) subway2 = display.newImageRect( foreGroup, "images/subway2.png", 250, 600) charNicoll = display.newSprite( characterGroup, charSheet, sequences\_charStation ) end -- show() function scene:show( event ) local sceneGroup = self.view local phase = event.phase if ( phase == "will" ) then -- Code here runs when the scene is still off screen (but is about to come on screen) stepsNicoll:setFillColor( 255,0,0 ) stepsNicoll.alpha = 1 stepsNicoll.isHitTestable = true stepsNicoll.id = 1 stepsNicoll.myName = "stepsNicoll" subway1.x = display.contentCenterX - 385 subway1.y = display.contentCenterY + 95 subway2.x = display.contentCenterX - 385 subway2.y = display.contentCenterY + 95 subway2.alpha = 1 charNicoll.x = display.contentCenterX - 200 charNicoll.y = display.contentCenterY + 220 charNicoll.isVisible = true charNicoll.id = 61 charNicoll.xScale = 1 charNicoll.myName = "charNicoll" -- charNicoll:setLinearVelocity( 10, 4 ) elseif ( phase == "did" ) then -- Code here runs when the scene is entirely on screen physics.start() physics.setGravity( 0, 0 ) physics.addBody( stepsNicoll, { radius=10, isSensor=true } ) physics.addBody( charNicoll, { radius=50, isSensor=true } ) Runtime:addEventListener("touch", onTouch) Runtime:addEventListener( "collision", onCollision ) charNicoll:addEventListener( "sprite", characterWalk ) end end -- hide() function scene:hide( event ) local sceneGroup = self.view local phase = event.phase if ( phase == "will" ) then -- Code here runs when the scene is on screen (but is about to go off screen) elseif ( phase == "did" ) then physics.pause() charNicoll:removeEventListener( "sprite", characterWalk ) Runtime:removeEventListener("touch", onTouch) Runtime:removeEventListener( "collision", onCollision ) composer.removeScene( "scenes.nicollOutside" ) end end -- destroy() function scene:destroy( event ) local sceneGroup = self.view -- Code here runs prior to the removal of scene's view end -- ----------------------------------------------------------------------------------- -- Scene event function listeners -- ----------------------------------------------------------------------------------- scene:addEventListener( "create", scene ) scene:addEventListener( "show", scene ) scene:addEventListener( "hide", scene ) scene:addEventListener( "destroy", scene ) -- ----------------------------------------------------------------------------------- return scene

This phrase is a possible clue:  “Can’t use the same object names in consecutive scenes…”  This happens when you’re using global objects. I went back and did a quick scan on your first code post and objects like “alienWalk” appear to be global. If you re-create that object in another scene, you will basically overwrite the original with the new one and that can lead to very hard to troubleshoot bugs.

Make sure you’re not using globals or specifically prefix it with _G. so you know for certain you’re using a global.

Rob