So I have two scenes. They contain exactly the same code ( for testing purposes only). When i run the first scene it works as expected but when I move from “level1” to “level2” I get an error in “level2”. “Attempt to call method ‘setLinearVelocity’ (a nil value)” even though they contain the same code. The code below does not contain any images so you can copy and paste it and it should work fine. I think i might be doing something wrong in the “show” and “hide” scene event. Please help me.
local physics = require "physics" local composer = require( "composer" ) local scene = composer.newScene() local player local ground local onAir local obstacle local obstacle2 local obstacle3 local playerStartX local playerStartY local playerNextX local playerNextY local star local starEnd -- "scene:create()" function scene:create( event ) local sceneGroup = self.view physics.start() physics.setGravity( 0, 100 ) onAir = false playerStartX = 20 playerStartY = display.contentHeight\*0.5-20 playerNextX = 20 playerNextY = display.contentHeight - 18 player = display.newRect( playerStartX, playerStartY, 20,20 ) player.speed = 3 player.name = "player" player:setFillColor( 1 ) player.isFixedRotation = true --To stop it rotating when jumping etc player.isSleepingAllowed = false --To force it to update and fall off playforms correctly. sceneGroup:insert( player ) ground = display.newRect( 0, display.contentHeight\*0.5-5, display.contentWidth, 5 ) ground.anchorX = 0 ground.anchorY = 0 ground.name = "ground" ground.strokeWidth = 3 ground:setFillColor( 0.5 ) ground:setStrokeColor( 1, 0, 0 ) sceneGroup:insert( ground ) ground2 = display.newRect( 0, display.contentHeight-5, display.contentWidth, 5 ) ground2.anchorX = 0 ground2.anchorY = 0 ground2.name = "ground" ground2.strokeWidth = 3 ground2:setFillColor( 0.5 ) ground2:setStrokeColor( 1, 0, 0 ) sceneGroup:insert( ground2 ) obstacle = display.newRect( display.contentWidth\*0.5, display.contentHeight\*0.5-46, 20, 40 ) obstacle.anchorX = 0 obstacle.anchorY = 0 obstacle.name = "obstacle" obstacle.strokeWidth = 3 obstacle:setFillColor( 0.5 ) obstacle:setStrokeColor( 1, 0, 0 ) sceneGroup:insert( obstacle ) obstacle2 = display.newRect( display.contentWidth\*0.5 - 100, display.contentHeight-46, 20, 40 ) obstacle2.anchorX = 0 obstacle2.anchorY = 0 obstacle2.name = "obstacle" obstacle2.strokeWidth = 3 obstacle2:setFillColor( 0.5 ) obstacle2:setStrokeColor( 1, 0, 0 ) sceneGroup:insert( obstacle2 ) obstacle3 = display.newRect( display.contentWidth\*0.5 + 60, display.contentHeight-46, 20, 40 ) obstacle3.anchorX = 0 obstacle3.anchorY = 0 obstacle3.name = "obstacle" obstacle3.strokeWidth = 3 obstacle3:setFillColor( 0.5 ) obstacle3:setStrokeColor( 1, 0, 0 ) sceneGroup:insert( obstacle3 ) star = display.newRect( display.contentWidth - 10,display.contentHeight\*0.5 - 20, 20, 20 ) star.name = "star" sceneGroup:insert( star ) starEnd = display.newRect( display.contentWidth - 10,display.contentHeight - 20, 20, 20 ) starEnd.name = "starEnd" sceneGroup:insert( starEnd ) physics.addBody( player, "dynamic", { density=1, friction=0.3} ) physics.addBody( ground, "static", { friction=0.5, bounce=0 } ) physics.addBody( ground2, "static", { friction=0.5, bounce=0 } ) physics.addBody( obstacle, "static", { friction=0.5, bounce=0 } ) physics.addBody( obstacle2, "static", { friction=0.5, bounce=0 } ) physics.addBody( obstacle3, "static", { friction=0.5, bounce=0 } ) physics.addBody( star, "static" ) physics.addBody( starEnd, "static" ) end-- end of the scene --make the player jump when touching the screen function screenTouch( event ) if event.phase == "began" then if onAir == false then player:setLinearVelocity(0,-880) onAir = true end end end function walls( event ) if player.x \< 10 then player.x = 10 elseif player.x \> display.contentWidth-10 then player.x = display.contentWidth-10 end if player.y \< 10 then player.y = 10 elseif player.y \> display.contentHeight then player.y = display.contentHeight end end function onCollision(event) if event.phase == "began" then local name1 = event.object1.name local name2 = event.object2.name if name1 == "player" or name2 == "player" then --Hit the floor, reset vars if name1 == "ground" or name2 == "ground" then onAir = false elseif name1 == "obstacle" or name2 == "obstacle" then timer.performWithDelay(1, moveBackToCheckPoint) elseif name1 == "star" or name2 == "star" then --remove the star if name1 == "star" then --remove the star display.remove(event.object1); event.object1 = nil; else display.remove(event.object2); event.object2 = nil; end timer.performWithDelay(1, goToNextPosition) elseif name1 == "starEnd" or name2 == "starEnd" then goToNextLevel() end end end end function moveBall( event ) player.x = player.x + player.speed end function moveBackToCheckPoint( event ) player.x = playerStartX player.y = playerStartY end function goToNextPosition(event) playerStartX = playerNextX playerStartY = playerNextY player.x = playerNextX player.y = playerNextY end function goToNextLevel( event ) composer.removeScene( "level1") composer.gotoScene( "level2" ) end -- "scene:show()" function scene:show( event ) local sceneGroup = self.view local phase = event.phase if ( phase == "will" ) then elseif ( phase == "did" ) then Runtime:addEventListener( "touch", screenTouch ) Runtime:addEventListener("collision",onCollision) Runtime:addEventListener("enterFrame", moveBall) Runtime:addEventListener("enterFrame", walls) -- Called when the scene is now on screen. -- Insert code here to make the scene come alive. -- Example: start timers, begin animation, play audio, etc. end end -- "scene:hide()" function scene:hide( event ) local sceneGroup = self.view local phase = event.phase if ( phase == "will" ) then -- Called when the scene is on screen (but is about to go off screen). -- Insert code here to "pause" the scene. -- Example: stop timers, stop animation, stop audio, etc. elseif ( phase == "did" ) then -- pauseBtn:removeEventListener( "tap", pauseGame ) -- Called immediately after scene goes off screen. end end -- "scene:destroy()" function scene:destroy( event ) local sceneGroup = self.view Runtime:removeEventListener( "touch", screenTouch ) Runtime:removeEventListener("collision",onCollision) Runtime:removeEventListener("enterFrame", moveBall) Runtime:removeEventListener("enterFrame", walls) -- Called prior to the removal of scene's view ("sceneGroup"). -- Insert code here to clean up the scene. -- Example: remove display objects, save state, etc. end -- Listener setup scene:addEventListener( "create", scene ) scene:addEventListener( "show", scene ) scene:addEventListener( "hide", scene ) scene:addEventListener( "destroy", scene ) return scene