I was following an outdated guide on youtube to make a simple side-scrolling jet game that avoids mines, and when the tutorial came to an area of using .purge (or in this case, the updated version of composer.removeScene) that’s when everything started messing up. So I can get from the mainGame.lua file, to the restart.lua file, but when I try to go back to mainGame, 1 of 2 things will happen.
-
Things will transition over smoothly and the game will play.
-
I get an error, or sometimes physics gets doubled( ie, things go faster)
21:12:44.104 ERROR: C:\Users\Didier\Documents\Corona Projects\SpeedyBird\mainGame.lua:247: physics.start() must be called before physics.stop() 21:12:47.617 ERROR: Runtime error 21:12:47.617 C:\Users\Didier\Documents\Corona Projects\SpeedyBird\mainGame.lua:31: attempt to call method ‘setLinearVelocity’ (a nil value) 21:12:47.617 stack traceback: 21:12:47.617 C:\Users\Didier\Documents\Corona Projects\SpeedyBird\mainGame.lua:31: in function ‘activateFlight2’ 21:12:47.617 C:\Users\Didier\Documents\Corona Projects\SpeedyBird\mainGame.lua:37: in function <C:\Users\Didier\Documents\Corona Projects\SpeedyBird\mainGame.lua:35> 21:12:47.617 ?: in function <?:169>
This is without the removeScene. If I place in a removeScene in restart.lua, I get errors in the first function it finds outside of scene functions (in mainGame) saying I’m trying to compare nil to a number. I don’t know what else to do. Let me know if I should include the files to make this post smaller or not.
So here’s restart.lua:
local composer = require( "composer" ) local scene = composer.newScene() -- ----------------------------------------------------------------------------------- -- Code outside of the scene event functions below will only be executed ONCE unless -- the scene is removed entirely (not recycled) via "composer.removeScene()" -- ----------------------------------------------------------------------------------- function start(event) if event.phase == "ended" then composer.gotoScene("mainGame", "fade", 500) end end -- ----------------------------------------------------------------------------------- -- Scene event functions -- ----------------------------------------------------------------------------------- -- create() function scene:create( event ) local sceneGroup = self.view -- Code here runs when the scene is first created but has not yet appeared on screen local background = display.newImage("layer-1.png") background.anchorX = 0; background.anchorY = 0 background.x = 0; background.y = 0 ------------------ Dead Bird Animation----------- --||||||||||||||| Bird |||||||||||||||||||||||||| local sheetOptions1 ={width = 561,height = 435,numFrames = 4 } local sheet\_idleBird = graphics.newImageSheet( "deadBird.png", sheetOptions1 ) -- sequences table local sequences\_idleBird = { -- consecutive frames sequence {name = "normalFly",start = 1,count = 4,time = 900,loopCount = 0, }, } deadBird = display.newSprite(sheet\_idleBird, sequences\_idleBird) deadBird.x = 220; deadBird.y = 150; deadBird:scale(0.5,0.5) sceneGroup:insert(background) sceneGroup:insert(deadBird) 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 deadBird:play() deadBird:addEventListener("touch", start) 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 deadBird:removeEventListener("touch", start) 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
and here’s my mainGame.lua:
local composer = require( "composer" ) local scene = composer.newScene() local physics = require "physics" physics.start() -- ----------------------------------------------------------------------------------- -- Code outside of the scene event functions below will only be executed ONCE unless -- the scene is removed entirely (not recycled) via "composer.removeScene()" -- ----------------------------------------------------------------------------------- function scrollEnvironment(self, event) if self.x \< -1145 then self.x = 1157 else self.x = self.x - self.speed end end function moveObstacles(self, event) if self.x \< -50 then obstacleCounter = math.random(1,4) self.x = 500 elseif (obstacleCounter == self.counter)then self.x = self.x - self.speed end end function boostPowerup(self, event) end function activateFlight2(self) self:setLinearVelocity(0,0) self:applyForce(0,-10,self.x,self.y) end function touchScreen(event) if event.phase == "began" then activateFlight2(bird) end end function onCollision(event) if event.phase == "began" then composer.gotoScene("restart", "fade", 400) end end -- ----------------------------------------------------------------------------------- -- Scene event functions -- ----------------------------------------------------------------------------------- -- create() function scene:create( event ) local sceneGroup = self.view -- Code here runs when the scene is first created but has not yet appeared on screen restartCounter = false; obstacleCounter = math.random(1,4); groundSpeed = 7; --||||||||| Background Image ||||||||||||||||||| local background = display.newImage("layer-1.png") background.anchorX = 0; background.anchorY = 0 background.x = 0; background.y = 0 background:scale(0.4,0.4) --|||||||||Cieling and flooring||||||||||||||||||| ceiling = display.newImage("testInvisTile.png") ceiling.x = 0; ceiling.y = 10 flooring = display.newImage("testInvisTile.png") flooring.anchorX = 0; flooring.anchorY = 1; flooring.x = 0; flooring.y = 320 --|||||||||||||||| Forest Display |||||||||||||| shrubs1 = display.newImage("layer-2.png") shrubs1.anchorX = 0; shrubs1.anchorY = 1; shrubs1.x = 0; shrubs1.y = 320 shrubs1:scale(0.4,0.4) shrubs1.speed = groundSpeed - 4 shrubs2 = display.newImage("layer-2.png") shrubs2.anchorX = 0; shrubs2.anchorY = 1; shrubs2.x = 1157; shrubs2.y = 320 shrubs2:scale(0.4,0.4) shrubs2.speed = groundSpeed - 4 forest1 = display.newImage("layer-3.png") forest1.anchorX = 0; forest1.anchorY = 1; forest1.x = 0; forest1.y = 320 forest1:scale(0.4,0.4) forest1.speed = groundSpeed - 2 forest2 = display.newImage("layer-3.png") forest2.anchorX = 0; forest2.anchorY = 1; forest2.x = 1157; forest2.y = 320 forest2:scale(0.4,0.4) forest2.speed = groundSpeed - 2 --||||||||||||||| Ground Display ||||||||||||||| ground1 = display.newImage("layer-5.png") ground1.anchorX = 0; ground1.anchorY = 1 ground1.x = 0; ground1.y = 300 ground1:scale(0.4, 0.4) ground1.speed = groundSpeed ground2 = display.newImage("layer-5.png") ground2.anchorX = 0; ground2.anchorY = 1 ground2.x = 1157; ground2.y = 300 ground2:scale(0.4, 0.4) ground2.speed = groundSpeed --||||||||||||||| Bird |||||||||||||||||||||||||| local sheetOptions1 ={width = 561,height = 435,numFrames = 4 } local sheet\_idleBird = graphics.newImageSheet( "testingBirdFly3.png", sheetOptions1 ) -- sequences table local sequences\_idleBird = { -- consecutive frames sequence {name = "normalFly",start = 1,count = 4,time = 900,loopCount = 0, }, -- next sequence (non-consecutive frames) {name = "fastFly",start = 1,count = 4,time = 100,loopCount = 0 }, } bird = display.newSprite(sheet\_idleBird, sequences\_idleBird) bird.x = 50; bird.y = 100; bird:scale(0.1,0.1) bird.width = 40; bird.height = 40 --|||||||||||||| Obstacles |||||||||||||||||||||||| obstacleTopSmall = display.newImage("obstacle hanging sharp wood.png") obstacleTopSmall.x = math.random(550,900); obstacleTopSmall.y = 50; obstacleTopSmall.speed = groundSpeed; obstacleTopSmall.counter = 1 obstacleTopSmall:scale(0.8,0.8) obstacleTopSmall.width = 40; obstacleTopSmall.height = 100; obstacleTopBig = display.newImage("obstacle hanging sharp wood.png") obstacleTopBig.x = math.random(550,1100); obstacleTopBig.y = 50; obstacleTopBig.speed = groundSpeed obstacleTopBig.counter = 2 obstacleTopBig:scale(0.8,1.2) obstacleTopBig.width = 40; obstacleTopBig.height = 100; obstacleBottomBig = display.newImage("obstacle tall sharp wood.png") obstacleBottomBig.anchorX = 0; obstacleBottomBig.anchorY = 1 obstacleBottomBig.x = math.random(550,900); obstacleBottomBig.y = 270; obstacleBottomBig.speed = groundSpeed obstacleBottomBig.counter = 3 obstacleBottomBig:scale(0.8,0.8) obstacleBottomBig.width = 70; obstacleBottomBig.height = 200; obstacleBottomSmall = display.newImage("obstacle short sharp wood.png") obstacleBottomSmall.anchorX = 0; obstacleBottomSmall.anchorY = 1 obstacleBottomSmall.x = math.random(550,900); obstacleBottomSmall.y = 270; obstacleBottomSmall.speed = groundSpeed obstacleBottomSmall.counter = 4 obstacleBottomSmall:scale(0.8,0.8) obstacleBottomSmall.width = 40; obstacleBottomSmall.height = 100; sceneGroup:insert(background) sceneGroup:insert(ceiling) sceneGroup:insert(flooring) sceneGroup:insert(shrubs1) sceneGroup:insert(shrubs2) sceneGroup:insert(flooring) sceneGroup:insert(forest1) sceneGroup:insert(forest2) sceneGroup:insert(ground1) sceneGroup:insert(ground2) sceneGroup:insert(bird) sceneGroup:insert(obstacleTopSmall) sceneGroup:insert(obstacleTopBig) sceneGroup:insert(obstacleBottomBig) sceneGroup:insert(obstacleBottomSmall) 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) bird.x = 50; bird.y = 100; obstacleTopSmall.x = 500; obstacleTopBig.x = 500; obstacleBottomBig.x = 500; obstacleBottomSmall.x = 500; obstacleCounter = math.random(1,4); elseif ( phase == "did" ) then -- Code here runs when the scene is entirely on screen physics.start() physics.addBody(bird, "dynamic", {density=.1, bounce=0.1, friction=.2, radius=13}) physics.addBody(obstacleTopSmall, "static", {density=.1, bounce=0.1, friction=.2}) physics.addBody(obstacleTopBig, "static", {density=.1, bounce=0.1, friction=.2}) physics.addBody(obstacleBottomBig, "static", {density=.1, bounce=0.1, friction=.2}) physics.addBody(obstacleBottomSmall, "static", {density=.1, bounce=0.1, friction=.2}) physics.addBody(ceiling, "static", {density=.1, bounce=0.1, friction=.2}) physics.addBody(flooring, "static", {density=.1, bounce=0.1, friction=.2}) bird:play() -- play the new sequence shrubs1.enterFrame = scrollEnvironment shrubs2.enterFrame = scrollEnvironment forest1.enterFrame = scrollEnvironment forest2.enterFrame = scrollEnvironment ground1.enterFrame = scrollEnvironment ground2.enterFrame = scrollEnvironment obstacleTopSmall.enterFrame = moveObstacles obstacleTopBig.enterFrame = moveObstacles obstacleBottomBig.enterFrame = moveObstacles obstacleBottomSmall.enterFrame = moveObstacles Runtime:addEventListener("touch", touchScreen) Runtime:addEventListener("collision", onCollision) Runtime:addEventListener("enterFrame", shrubs1) Runtime:addEventListener("enterFrame", shrubs2) Runtime:addEventListener("enterFrame", forest1) Runtime:addEventListener("enterFrame", forest2) Runtime:addEventListener("enterFrame", ground1) Runtime:addEventListener("enterFrame", ground2) Runtime:addEventListener("enterFrame", obstacleTopSmall) Runtime:addEventListener("enterFrame", obstacleTopBig) Runtime:addEventListener("enterFrame", obstacleBottomBig) Runtime:addEventListener("enterFrame", obstacleBottomSmall) 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:removeEventListener("touch", touchScreen) Runtime:removeEventListener("collision", onCollision) Runtime:removeEventListener("enterFrame", shrubs1) Runtime:removeEventListener("enterFrame", shrubs2) Runtime:removeEventListener("enterFrame", forest1) Runtime:removeEventListener("enterFrame", forest2) Runtime:removeEventListener("enterFrame", ground1) Runtime:removeEventListener("enterFrame", ground2) Runtime:removeEventListener("enterFrame", obstacleTopSmall) Runtime:removeEventListener("enterFrame", obstacleTopBig) Runtime:removeEventListener("enterFrame", obstacleBottomBig) Runtime:removeEventListener("enterFrame", obstacleBottomSmall) physics.stop() 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