Runtime:removeEventListener

Hi, I’m having issues when running my game and die. It goes to the menu which is what I want, but when I try to go back. It say “attempt to call method ‘setLinearVelocity’ (a nil value)”. I figured out that I need to remove timers and event listeners, so I added that to my code. I think I’m doing something wrong because it says the same thing, and on further research found out something to do with scope when I try to remove it. I don’t know what to do because I tried different ways to try to bring it into scope, but either didn’t work or got different error messages.

Here is my code: ( Sorry it’s so lengthy)

--Load the composer library which is used for creating scenes/menus local composer = require( "composer" ) local scene = composer.newScene() composer.removeHidden( true ) --composer.recycleOnSceneChange = true --Load the physics library local physics = require( "physics" ) --Load table library local table = require( "table" ) local math = require("math") --Set physics and gravity physics.start(true) physics.setGravity( 0, 100 ) --composer.removeScene( "title\_screen" ) --Seed the random number generator math.randomseed( os.time() ) --Load in audio local jumpSound = audio.loadSound( "SFX\_Jump\_04.wav" ) local jumpOptions = { channel = 2, } audio.setVolume( 0.5, { channel = 2 } ) local backgroundMusic = audio.play( "Reaper Music.wav" ) local backgroundOptions = { channel = 1, loop = -1, duration = 150000 } audio.setVolume( 0.3, { channel = 1 } ) --audio.play( backgroundMusic, backgroundOptions ) --Initialize jumpcounter local jumpcounter = 0 --Load the sprite sheet with all the platform information local sheetInfo = require("platforms") local platformSheet = graphics.newImageSheet( "platforms.png", sheetInfo:getSheet() ) --local sprite = display.newSprite( platformSheet, {frames={sheetInfo:getFrameIndex("sprite")}} ) local sheetInfo2 = require("StuffSprite") local decorSheet = graphics.newImageSheet( "StuffSprite.png", sheetInfo2:getSheet() ) --local sprite2 = display.newSprite( decorSheet, {frames={sheetInfo2:getFrameIndex("sprite")}} ) local options = { frames = { --Frame 1 (Reaper1-1) { x = 0, y = 0, width = 80, height = 80, }, --Frame 2 (Reaper1-2) { x = 80, y = 0, width = 80, height = 80, }, --Frame 3 (Reaper1-3) { x = 160, y = 0, width = 80, height = 80, }, --Frame 4 (Reaper1-4) { x = 240, y = 0, width = 80, height = 80, }, --Frame 5 (Reaper2-1) { x = 320, y = 0, width = 80, height = 80, }, --Frame 6 (Reaper2-2) { x = 400, y = 0, width = 80, height = 80, }, --Frame 7 (Reaper2-3) { x = 0, y = 80, width = 80, height = 80, }, --Frame 8 (Reaper2-4) { x = 80, y = 80, width = 80, height = 80, }, --Frame 9 (Reaper3-1) { x = 160, y = 80, width = 88, height = 82, }, --Frame 10 (Reaper3-2) { x = 88, y = 184, width = 88, height = 88, }, --Frame 11 (Reaper3-3) { x = 176, y = 184, width = 88, height = 100, }, --Frame 12 (Reaper3-4) { x = 264, y = 184, width = 80, height = 94, }, --Frame 13 (Reaper3-5) { x = 344, y = 184, width = 88, height = 118, }, --Frame 14 (Reaper3-6) { x = 0, y = 302, width = 88, height = 118, }, --Frame 15 (Reaper3-7) { x = 88, y = 302, width = 88, height = 118, }, --Frame 16 (Reaper3-8) { x = 176, y = 302, width = 88, height = 118, }, --Frame 17 (Reaper3-9) { x = 264, y = 302, width = 88, height = 118, }, --Frame 18 (Reaper3-10) { x = 248, y = 80, width = 88, height = 104, }, --Frame 19 (Reaper3-11) { x = 336, y = 80, width = 100, height = 104, }, --Frame 20 (Reaper3-12) { x = 0, y = 184, width = 88, height = 85, } }, sheetContentWidth = 512, sheetContentHeight = 512 } local player = graphics.newImageSheet( "reapersprite.png", options ) local sequence\_runningReaper = { { name = "running", frames = { 1, 2, 3, 4 }, time = 1000, loopCount = 0, loopDirection = "forward" }, { name = "jump", frames = { 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20 }, time = 700, loopCount = 1, loopDirection = "forward" } } --function load () --end function scene:create( event ) local sceneGroup = self.view --Load the display physics.setDrawMode( "hybrid" ) local background = display.newImageRect( "1Background.png", 1500, 900 ) background.x = display.contentCenterX background.y = display.contentCenterY sceneGroup:insert( background ) --Shapes for all the platform parts and the reverse of each platform section local B3shape = { 150,-96, 150,-59, -150,29, -150,-8 } local reverseB3shape = { 150,-8, 150,29, -150,-59, -150,-96 } local A1shape = { 50,-71, 50,-23, -43,-71 } local score = 0 scoreText2 = display.newText( "Score: ", 11, 50, native.systemFontBold, 80 ) sceneGroup:insert( scoreText2 ) scoreText = display.newText( score, 500, 50, native.systemFontBold, 80 ) sceneGroup:insert( scoreText ) local platformStart = display.newImageRect( platformSheet, 10, 552, 255 ) platformStart.x = display.contentWidth -900 platformStart.y = display.contentHeight -200 sceneGroup:insert( platformStart ) local treeStart = display.newImageRect( decorSheet, 9, 200, 200 ) treeStart.x = platformStart.x - 100 treeStart.y = platformStart.y - 170 sceneGroup:insert( treeStart ) local gravestoneStart = display.newImageRect( decorSheet, 3, 50, 100 ) gravestoneStart.x = platformStart.x + 100 gravestoneStart.y = display.contentHeight -365 sceneGroup:insert( gravestoneStart ) local soulStart = display.newImageRect( decorSheet, 4, 30, 40 ) soulStart.x = platformStart.x + 30 soulStart.y = platformStart.y - 135 sceneGroup:insert( soulStart ) local platform1 = display.newImageRect( platformSheet, 1, 100, 100 ) platform1.x = display.contentWidth -500 platform1.y = display.contentHeight -399 sceneGroup:insert( platform1 ) local platform2 = display.newImageRect( platformSheet, 11, 300, 150 ) platform2.x = display.contentWidth -320 platform2.y = display.contentHeight -393 sceneGroup:insert( platform2 ) local platform3 = display.newImageRect( platformSheet, 1, 100, 100 ) platform3.x = display.contentWidth -140 platform3.y = display.contentHeight -399 platform3:scale( -1, 1 ) sceneGroup:insert( platform3 ) local platform4 = display.newImageRect( platformSheet, 7, 300, 150 ) platform4.x = display.contentWidth +200 platform4.y = display.contentHeight -322 sceneGroup:insert( platform4 ) local platform5 = display.newImageRect( platformSheet, 8, 300, 200 ) platform5.x = display.contentWidth +482 platform5.y = display.contentHeight -391 sceneGroup:insert( platform5 ) local platform6 = display.newImageRect( platformSheet, 6, 100, 100 ) platform6.x = display.contentWidth +680 platform6.y = display.contentHeight -440 sceneGroup:insert( platform6 ) --local platform7 = display.newImageRect( platformSheet, , [baseDir,], width, height ) local reaper = display.newSprite( player, sequence\_runningReaper ) reaper:setSequence("running") reaper:play( ) reaper.x = platformStart.x reaper.y = platformStart.y - 165 sceneGroup:insert( reaper ) --local arrow = display.newImageRect( "arrow-landing.png", 100, 100 ) --arrow.x = display.contentCenterX --arrow.y = display.contentCenterY speed = 4 value = 100 --These add the physics bodies to the platfroms and reaper physics.addBody( platformStart, "static", { bounce = 0, friction = 0.2} ) physics.addBody( reaper, "dynamic", { bounce = 0, friction = 0.2} ) physics.addBody( platform1, "static", {bounce = 0, friction = 0.2, shape = A1shape} ) physics.addBody( platform2, "static", { bounce = 0, friction = 0.2} ) physics.addBody( platform3, "static", { bounce = 0, friction = 0.2, shape = A1shape} ) physics.addBody( platform4, "static", {bounce = 0, friction = 0.2} ) physics.addBody( platform5, "static", {bounce = 0, friction = 1.0, shape = B3shape} ) physics.addBody( platform6, "static", {bounce = 0, friction = 0.2} ) reaper.isFixedRotation = true --Start with Math calculations local function update( event ) --update background updateBackgrounds() end function updateBackgrounds() score = score + 1 scoreText.text = score --This line of code controls platform movement --Change the number inside parenthesis to change speed higher number mean faster --The minus sign makes the object move to the left platformStart.x = platformStart.x - (speed) soulStart.x = soulStart.x - (speed) treeStart.x = treeStart.x - (speed) gravestoneStart.x = gravestoneStart.x - (speed) platform1.x = platform1.x - (speed) platform2.x = platform2.x - (speed) platform3.x = platform3.x - (speed) platform4.x = platform4.x - (speed) platform5.x = platform5.x - (speed) platform6.x = platform6.x - (speed) --"Moves" the platforms back to the right so they can be run again if ( platformStart.x \< -500 ) then soulStart.alpha = 1 platformStart.x = 1400 end if (gravestoneStart.x \< -500 ) then gravestoneStart.x = platformStart.x + 100 end if ( soulStart.x \< -500 ) then soulStart.x = platformStart.x + 30 end if ( treeStart.x \< -500 ) then treeStart.x = platformStart.x - 100 end if ( platform1.x \< -500 ) then --soul.alpha = 1 platform1.x = platformStart.x + 400 end if ( platform2.x \< -500 ) then --soul.alpha = 1 platform2.x = platform1.x + 200 end if ( platform3.x \< -500 ) then --soul.alpha = 1 platform3.x = platform2.x + 140 end if ( platform4.x \< -500 ) then --soul.alpha = 1 platform4.x = platform3.x + 340 end if ( platform5.x \< -500 ) then --soul.alpha = 1 platform5.x = platform4.x + 282 end if ( platform6.x \< -500 ) then platform6.x = platform5.x + 202 speed = speed + 0.5 value = value \* 4 end if ( reaper.x \>= soulStart.x-1 and reaper.x \<= soulStart.x+1 and reaper.y \>= soulStart.y-60 and reaper.y \<= soulStart.y-30 ) then score = score + value soulStart.alpha = 0 end local function collisionfunction ( self, event ) jumpcounter = 0 reaper:setSequence( "running" ) reaper:play( ) end reaper.collision = collisionfunction if ( reaper.x \< -300 or reaper.y \> 810 ) then if ( score \> highscore ) then highscore = score end Runtime:removeEventListener( "touch", ascend ) dead() end local function ascend () if jumpcounter \< 2 then --audio.play( jumpSound, jumpOptions ) reaper:setLinearVelocity( 0, -1000 ) reaper:setSequence( "jump" ) reaper:play( ) jumpcounter = jumpcounter + 1 end end --Listens for the user to tap to make the reaper jump Runtime:addEventListener( "touch", ascend ) reaper:addEventListener( "collision" ) end --This calls the update function or run the function continuously local myTimer = timer.performWithDelay( 16.667, update, -1 ) function dead ( ) --physics.pause( ) timer.cancel( myTimer ) Runtime:removeEventListener( "touch", ascend ) --reaper:removeEventListener( "collision" ) --reaper.x = platformStart.x --reaper.y = platformStart.y - 165 --speed = 2 --value = 100 --score = 0 --physics.stop( ) --composer.removeScene( "game" ) composer.gotoScene( "title\_screen" ) end end --platform shape function scene:show( event ) local sceneGroup = self.view local phase = event.phase if ( phase == "will" ) then elseif ( phase == "did" ) then end end function scene:hide( event ) local sceneGroup = self.view local phase = event.phase if ( phase == "will" ) then elseif ( phase == "did" ) then end end function scene:destroy( event ) local sceneGroup = self.view end scene:addEventListener( "create", scene ) scene:addEventListener( "show", scene ) scene:addEventListener( "hide", scene ) scene:addEventListener( "destroy", scene ) return scene

Try setting your code up like this:

 function missile.enterFrame( self ) -- is object valid? if( not self.removeSelf or type(self.removeSelf) ~= "function") then -- no! abort... return end end Runtime:addEventListener( "enterFrame", missile ) function missile.touch( self ) end Runtime:addEventListener( "touch", missile ) ... etc -- remove all runtime event listeners missile.finalize = function( self ) Runtime:removeEventListener( "enterFrame", self ) Runtime:removeEventListener( "touch", self ) end missile:addEventListener("finalize")

Here is a picture of the error. And here is the code for the game.lua

--Load the composer library which is used for creating scenes/menus local composer = require( "composer" ) local scene = composer.newScene() composer.removeHidden( true ) --composer.recycleOnSceneChange = true --Load the physics library local physics = require( "physics" ) --Load table library local table = require( "table" ) local math = require("math") --Set physics and gravity physics.start(true) physics.setGravity( 0, 100 ) --composer.removeScene( "title\_screen" ) --Seed the random number generator math.randomseed( os.time() ) --Load in audio local jumpSound = audio.loadSound( "SFX\_Jump\_04.wav" ) local jumpOptions = { channel = 2, } audio.setVolume( 0.5, { channel = 2 } ) local backgroundMusic = audio.play( "Reaper Music.wav" ) local backgroundOptions = { channel = 1, loop = -1, duration = 150000 } audio.setVolume( 0.3, { channel = 1 } ) --audio.play( backgroundMusic, backgroundOptions ) --Initialize jumpcounter local jumpcounter = 0 --Load the sprite sheet with all the platform information local sheetInfo = require("platforms") local platformSheet = graphics.newImageSheet( "platforms.png", sheetInfo:getSheet() ) --local sprite = display.newSprite( platformSheet, {frames={sheetInfo:getFrameIndex("sprite")}} ) local sheetInfo2 = require("StuffSprite") local decorSheet = graphics.newImageSheet( "StuffSprite.png", sheetInfo2:getSheet() ) --local sprite2 = display.newSprite( decorSheet, {frames={sheetInfo2:getFrameIndex("sprite")}} ) local options = { frames = { --Frame 1 (Reaper1-1) { x = 0, y = 0, width = 80, height = 80, }, --Frame 2 (Reaper1-2) { x = 80, y = 0, width = 80, height = 80, }, --Frame 3 (Reaper1-3) { x = 160, y = 0, width = 80, height = 80, }, --Frame 4 (Reaper1-4) { x = 240, y = 0, width = 80, height = 80, }, --Frame 5 (Reaper2-1) { x = 320, y = 0, width = 80, height = 80, }, --Frame 6 (Reaper2-2) { x = 400, y = 0, width = 80, height = 80, }, --Frame 7 (Reaper2-3) { x = 0, y = 80, width = 80, height = 80, }, --Frame 8 (Reaper2-4) { x = 80, y = 80, width = 80, height = 80, }, --Frame 9 (Reaper3-1) { x = 160, y = 80, width = 88, height = 82, }, --Frame 10 (Reaper3-2) { x = 88, y = 184, width = 88, height = 88, }, --Frame 11 (Reaper3-3) { x = 176, y = 184, width = 88, height = 100, }, --Frame 12 (Reaper3-4) { x = 264, y = 184, width = 80, height = 94, }, --Frame 13 (Reaper3-5) { x = 344, y = 184, width = 88, height = 118, }, --Frame 14 (Reaper3-6) { x = 0, y = 302, width = 88, height = 118, }, --Frame 15 (Reaper3-7) { x = 88, y = 302, width = 88, height = 118, }, --Frame 16 (Reaper3-8) { x = 176, y = 302, width = 88, height = 118, }, --Frame 17 (Reaper3-9) { x = 264, y = 302, width = 88, height = 118, }, --Frame 18 (Reaper3-10) { x = 248, y = 80, width = 88, height = 104, }, --Frame 19 (Reaper3-11) { x = 336, y = 80, width = 100, height = 104, }, --Frame 20 (Reaper3-12) { x = 0, y = 184, width = 88, height = 85, } }, sheetContentWidth = 512, sheetContentHeight = 512 } local player = graphics.newImageSheet( "reapersprite.png", options ) local sequence\_runningReaper = { { name = "running", frames = { 1, 2, 3, 4 }, time = 1000, loopCount = 0, loopDirection = "forward" }, { name = "jump", frames = { 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20 }, time = 700, loopCount = 1, loopDirection = "forward" } } --function load () --end function scene:create( event ) local sceneGroup = self.view --Load the display physics.setDrawMode( "hybrid" ) local background = display.newImageRect( "1Background.png", 1500, 900 ) background.x = display.contentCenterX background.y = display.contentCenterY sceneGroup:insert( background ) --Shapes for all the platform parts and the reverse of each platform section local B3shape = { 150,-96, 150,-59, -150,29, -150,-8 } local reverseB3shape = { 150,-8, 150,29, -150,-59, -150,-96 } local A1shape = { 50,-71, 50,-23, -43,-71 } local score = 0 scoreText2 = display.newText( "Score: ", 11, 50, native.systemFontBold, 80 ) sceneGroup:insert( scoreText2 ) scoreText = display.newText( score, 500, 50, native.systemFontBold, 80 ) sceneGroup:insert( scoreText ) local platformStart = display.newImageRect( platformSheet, 10, 552, 255 ) platformStart.x = display.contentWidth -900 platformStart.y = display.contentHeight -200 sceneGroup:insert( platformStart ) local treeStart = display.newImageRect( decorSheet, 9, 200, 200 ) treeStart.x = platformStart.x - 100 treeStart.y = platformStart.y - 170 sceneGroup:insert( treeStart ) local gravestoneStart = display.newImageRect( decorSheet, 3, 50, 100 ) gravestoneStart.x = platformStart.x + 100 gravestoneStart.y = display.contentHeight -365 sceneGroup:insert( gravestoneStart ) local soulStart = display.newImageRect( decorSheet, 4, 30, 40 ) soulStart.x = platformStart.x + 30 soulStart.y = platformStart.y - 135 sceneGroup:insert( soulStart ) local platform1 = display.newImageRect( platformSheet, 1, 100, 100 ) platform1.x = display.contentWidth -500 platform1.y = display.contentHeight -399 sceneGroup:insert( platform1 ) local platform2 = display.newImageRect( platformSheet, 11, 300, 150 ) platform2.x = display.contentWidth -320 platform2.y = display.contentHeight -393 sceneGroup:insert( platform2 ) local platform3 = display.newImageRect( platformSheet, 1, 100, 100 ) platform3.x = display.contentWidth -140 platform3.y = display.contentHeight -399 platform3:scale( -1, 1 ) sceneGroup:insert( platform3 ) local platform4 = display.newImageRect( platformSheet, 7, 300, 150 ) platform4.x = display.contentWidth +200 platform4.y = display.contentHeight -322 sceneGroup:insert( platform4 ) local platform5 = display.newImageRect( platformSheet, 8, 300, 200 ) platform5.x = display.contentWidth +482 platform5.y = display.contentHeight -391 sceneGroup:insert( platform5 ) local platform6 = display.newImageRect( platformSheet, 6, 100, 100 ) platform6.x = display.contentWidth +680 platform6.y = display.contentHeight -440 sceneGroup:insert( platform6 ) local platform7 = display.newImageRect( platformSheet, 4, 300, 162 ) platform7.x = display.contentWidth +1000 platform7.y = display.contentHeight -100 sceneGroup:insert( platform7 ) local platform8 = display.newImageRect( platformSheet, 11, 300, 178 ) platform8.x = display.contentWidth +1300 platform8.y = display.contentHeight -95 sceneGroup:insert( platform8 ) local reaper = display.newSprite( player, sequence\_runningReaper ) reaper:setSequence("running") reaper:play( ) reaper.x = platformStart.x reaper.y = platformStart.y - 165 sceneGroup:insert( reaper ) --local arrow = display.newImageRect( "arrow-landing.png", 100, 100 ) --arrow.x = display.contentCenterX --arrow.y = display.contentCenterY speed = 4 value = 100 --These add the physics bodies to the platfroms and reaper physics.addBody( platformStart, "static", { bounce = 0, friction = 0.2} ) physics.addBody( reaper, "dynamic", { bounce = 0, friction = 0.2} ) physics.addBody( platform1, "static", {bounce = 0, friction = 0.2, shape = A1shape} ) physics.addBody( platform2, "static", { bounce = 0, friction = 0.2} ) physics.addBody( platform3, "static", { bounce = 0, friction = 0.2, shape = A1shape} ) physics.addBody( platform4, "static", {bounce = 0, friction = 0.2} ) physics.addBody( platform5, "static", {bounce = 0, friction = 1.0, shape = B3shape} ) physics.addBody( platform6, "static", {bounce = 0, friction = 0.2} ) physics.addBody( platform7, "static", {bounce = 0, friction = 0.2} ) physics.addBody( platform8, "static", {bounce = 0, friction = 0.2} ) reaper.isFixedRotation = true --Start with Math calculations local function update( event ) --update background updateBackgrounds() end function updateBackgrounds() score = score + 1 scoreText.text = score --This line of code controls platform movement --Change the number inside parenthesis to change speed higher number mean faster --The minus sign makes the object move to the left platformStart.x = platformStart.x - (speed) soulStart.x = soulStart.x - (speed) treeStart.x = treeStart.x - (speed) gravestoneStart.x = gravestoneStart.x - (speed) platform1.x = platform1.x - (speed) platform2.x = platform2.x - (speed) platform3.x = platform3.x - (speed) platform4.x = platform4.x - (speed) platform5.x = platform5.x - (speed) platform6.x = platform6.x - (speed) platform7.x = platform7.x - (speed) platform8.x = platform8.x - (speed) --"Moves" the platforms back to the right so they can be run again if ( platformStart.x \< -500 ) then soulStart.alpha = 1 platformStart.x = platform8.x + 550 end if (gravestoneStart.x \< -500 ) then gravestoneStart.x = platformStart.x + 100 end if ( soulStart.x \< -500 ) then soulStart.x = platformStart.x + 30 end if ( treeStart.x \< -500 ) then treeStart.x = platformStart.x - 100 end if ( platform1.x \< -500 ) then --soul.alpha = 1 platform1.x = platformStart.x + 400 end if ( platform2.x \< -500 ) then --soul.alpha = 1 platform2.x = platform1.x + 200 end if ( platform3.x \< -500 ) then --soul.alpha = 1 platform3.x = platform2.x + 140 end if ( platform4.x \< -500 ) then --soul.alpha = 1 platform4.x = platform3.x + 340 end if ( platform5.x \< -500 ) then --soul.alpha = 1 platform5.x = platform4.x + 282 end if ( platform6.x \< -500 ) then platform6.x = platform5.x + 202 end if ( platform7.x \< -500 ) then platform7.x = platform6.x + 480 end if ( platform8.x \< -500 ) then platform8.x = platform8.x + 300 speed = speed + 0.5 value = value \* 4 end if ( reaper.x \>= soulStart.x-1 and reaper.x \<= soulStart.x+1 and reaper.y \>= soulStart.y-60 and reaper.y \<= soulStart.y-30 ) then score = score + value soulStart.alpha = 0 end local function collisionfunction ( self, event ) jumpcounter = 0 reaper:setSequence( "running" ) reaper:play( ) end reaper.collision = collisionfunction if ( reaper.x \< -300 or reaper.y \> 810 ) then if ( score \> highscore ) then highscore = score end Runtime:removeEventListener( "touch", ascend ) dead() end function ascend ( event ) if jumpcounter \< 2 then --audio.play( jumpSound, jumpOptions ) --HERE IS WERE IT'S BREAKING reaper:setLinearVelocity( 0, -1000 ) reaper:setSequence( "jump" ) reaper:play( ) jumpcounter = jumpcounter + 1 end end --Listens for the user to tap to make the reaper jump Runtime:addEventListener( "touch", ascend ) reaper:addEventListener( "collision" ) end --This calls the update function or run the function continuously local myTimer = timer.performWithDelay( 16.667, update, -1 ) function dead ( ) --physics.pause( ) timer.cancel( myTimer ) Runtime:removeEventListener( "touch", ascend ) --reaper:removeEventListener( "collision" ) --reaper.x = platformStart.x --reaper.y = platformStart.y - 165 --speed = 2 --value = 100 --score = 0 --physics.stop( ) --composer.removeScene( "game" ) composer.gotoScene( "title\_screen" ) end end --platform shape function scene:show( event ) local sceneGroup = self.view local phase = event.phase if ( phase == "will" ) then elseif ( phase == "did" ) then end end function scene:hide( event ) local sceneGroup = self.view local phase = event.phase if ( phase == "will" ) then elseif ( phase == "did" ) then end end function scene:destroy( event ) local sceneGroup = self.view end scene:addEventListener( "create", scene ) scene:addEventListener( "show", scene ) scene:addEventListener( "hide", scene ) scene:addEventListener( "destroy", scene ) return scene

No, take a closer look at what I’m doing.  I’m attaching the listeners directly to the objects as fields with the same name as the event. 

Then, in the finalize event I’m removing the runtime event listeners.

Note: Sorry, but I’m not reading those code posts… They’re too long (past my threshold).

Try creating a blank project (just main.lua and the following code) with this code to see how this works:

local function doTest() local obj = display.newCircle( 10, 100, 10 ) function obj.enterFrame( self ) if( not self.removeSelf or type(self.removeSelf) ~= "function" ) then return end self.x = self.x + 1 end Runtime:addEventListener( "enterFrame", obj ) -- -- Add finalize listener to clean up when object is deleted -- function obj.finalize( self ) Runtime:addEventListener( "enterFrame", self ) end obj:addEventListener("finalize") -- -- delete object in 5 seconds -- timer.performWithDelay( 5000, function() display.remove(obj) end ) -- start test again in 6 seconds timer.performWithDelay( 5000, doTest) end doTest()

How would I implement this into my code?

Sorry, but that would be  total re-write… I simply can’t do that for you.

Here are my suggestions:

  1. Don’t use composer.* till you have some experience with basic Corona features and fundamental Lua principles (scope, visibility, garbage collection, tables, modules, …)

  2. Make a standalone game module that can create() and destroy() the game.  

  3. Ensure the create function in the module above takes a group as an argument and place all objects you create in that group.

  4. To simplify handling of objects that need to be in scope of multiple functions in your module, forward declare the variables that refer to the objecst (and if needed function names that may be used in multiple module functions/methods).

  5. Be sure to assign nil to variables that referenced objects after you delete those objects.

  6. Avoid Runtime: touch listeners.  I find it much better to use local touch listeners and assign a touch listener to the background image or the object you need to catch the touch.

  7. The same goes for global collision listeners, etc.  When its an option use local listeners.

Hey, I offer a service for folks who are really stuck called ‘hitman’.  If you’re interested I could do a hit to refactor your project.

However, I think you’d be best suited starting over and focusing on fundamentals and basic learning first. 

Jumping right into making a game is sexy and fun sounding, but 99% of the time leads to total confusion. 

Better to make super tiny mechanical and functional experiments first, then when you have your feet under you, combine your accrued knowledge into a bigger project, eventually getting to the point where you make a game.

There are a couple of issues you still have.

First, you’re still doing things inside your updateBackgrounds() function that should only happen once.  These two lines are being executed 60 times per second too:

 Runtime:addEventListener( "touch", ascend ) reaper:addEventListener( "collision" )

Then your “ascend” function doesn’t handle touches properly. It will get called multiple times. It will be called once when the touch begins, one when it ends and multiple times if your finger moves during the event.  The code in the touch handler will execute multiple times. Still, I don’t see where reaper is getting destroyed, which would be a reason why you’re getting the error you’re getting.

So study your code and see how reaper can get destroyed and see if your ascend function is getting called after reaper has been removed (or called before you add the physics body.

Rob

Try setting your code up like this:

 function missile.enterFrame( self ) -- is object valid? if( not self.removeSelf or type(self.removeSelf) ~= "function") then -- no! abort... return end end Runtime:addEventListener( "enterFrame", missile ) function missile.touch( self ) end Runtime:addEventListener( "touch", missile ) ... etc -- remove all runtime event listeners missile.finalize = function( self ) Runtime:removeEventListener( "enterFrame", self ) Runtime:removeEventListener( "touch", self ) end missile:addEventListener("finalize")

Here is a picture of the error. And here is the code for the game.lua

--Load the composer library which is used for creating scenes/menus local composer = require( "composer" ) local scene = composer.newScene() composer.removeHidden( true ) --composer.recycleOnSceneChange = true --Load the physics library local physics = require( "physics" ) --Load table library local table = require( "table" ) local math = require("math") --Set physics and gravity physics.start(true) physics.setGravity( 0, 100 ) --composer.removeScene( "title\_screen" ) --Seed the random number generator math.randomseed( os.time() ) --Load in audio local jumpSound = audio.loadSound( "SFX\_Jump\_04.wav" ) local jumpOptions = { channel = 2, } audio.setVolume( 0.5, { channel = 2 } ) local backgroundMusic = audio.play( "Reaper Music.wav" ) local backgroundOptions = { channel = 1, loop = -1, duration = 150000 } audio.setVolume( 0.3, { channel = 1 } ) --audio.play( backgroundMusic, backgroundOptions ) --Initialize jumpcounter local jumpcounter = 0 --Load the sprite sheet with all the platform information local sheetInfo = require("platforms") local platformSheet = graphics.newImageSheet( "platforms.png", sheetInfo:getSheet() ) --local sprite = display.newSprite( platformSheet, {frames={sheetInfo:getFrameIndex("sprite")}} ) local sheetInfo2 = require("StuffSprite") local decorSheet = graphics.newImageSheet( "StuffSprite.png", sheetInfo2:getSheet() ) --local sprite2 = display.newSprite( decorSheet, {frames={sheetInfo2:getFrameIndex("sprite")}} ) local options = { frames = { --Frame 1 (Reaper1-1) { x = 0, y = 0, width = 80, height = 80, }, --Frame 2 (Reaper1-2) { x = 80, y = 0, width = 80, height = 80, }, --Frame 3 (Reaper1-3) { x = 160, y = 0, width = 80, height = 80, }, --Frame 4 (Reaper1-4) { x = 240, y = 0, width = 80, height = 80, }, --Frame 5 (Reaper2-1) { x = 320, y = 0, width = 80, height = 80, }, --Frame 6 (Reaper2-2) { x = 400, y = 0, width = 80, height = 80, }, --Frame 7 (Reaper2-3) { x = 0, y = 80, width = 80, height = 80, }, --Frame 8 (Reaper2-4) { x = 80, y = 80, width = 80, height = 80, }, --Frame 9 (Reaper3-1) { x = 160, y = 80, width = 88, height = 82, }, --Frame 10 (Reaper3-2) { x = 88, y = 184, width = 88, height = 88, }, --Frame 11 (Reaper3-3) { x = 176, y = 184, width = 88, height = 100, }, --Frame 12 (Reaper3-4) { x = 264, y = 184, width = 80, height = 94, }, --Frame 13 (Reaper3-5) { x = 344, y = 184, width = 88, height = 118, }, --Frame 14 (Reaper3-6) { x = 0, y = 302, width = 88, height = 118, }, --Frame 15 (Reaper3-7) { x = 88, y = 302, width = 88, height = 118, }, --Frame 16 (Reaper3-8) { x = 176, y = 302, width = 88, height = 118, }, --Frame 17 (Reaper3-9) { x = 264, y = 302, width = 88, height = 118, }, --Frame 18 (Reaper3-10) { x = 248, y = 80, width = 88, height = 104, }, --Frame 19 (Reaper3-11) { x = 336, y = 80, width = 100, height = 104, }, --Frame 20 (Reaper3-12) { x = 0, y = 184, width = 88, height = 85, } }, sheetContentWidth = 512, sheetContentHeight = 512 } local player = graphics.newImageSheet( "reapersprite.png", options ) local sequence\_runningReaper = { { name = "running", frames = { 1, 2, 3, 4 }, time = 1000, loopCount = 0, loopDirection = "forward" }, { name = "jump", frames = { 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20 }, time = 700, loopCount = 1, loopDirection = "forward" } } --function load () --end function scene:create( event ) local sceneGroup = self.view --Load the display physics.setDrawMode( "hybrid" ) local background = display.newImageRect( "1Background.png", 1500, 900 ) background.x = display.contentCenterX background.y = display.contentCenterY sceneGroup:insert( background ) --Shapes for all the platform parts and the reverse of each platform section local B3shape = { 150,-96, 150,-59, -150,29, -150,-8 } local reverseB3shape = { 150,-8, 150,29, -150,-59, -150,-96 } local A1shape = { 50,-71, 50,-23, -43,-71 } local score = 0 scoreText2 = display.newText( "Score: ", 11, 50, native.systemFontBold, 80 ) sceneGroup:insert( scoreText2 ) scoreText = display.newText( score, 500, 50, native.systemFontBold, 80 ) sceneGroup:insert( scoreText ) local platformStart = display.newImageRect( platformSheet, 10, 552, 255 ) platformStart.x = display.contentWidth -900 platformStart.y = display.contentHeight -200 sceneGroup:insert( platformStart ) local treeStart = display.newImageRect( decorSheet, 9, 200, 200 ) treeStart.x = platformStart.x - 100 treeStart.y = platformStart.y - 170 sceneGroup:insert( treeStart ) local gravestoneStart = display.newImageRect( decorSheet, 3, 50, 100 ) gravestoneStart.x = platformStart.x + 100 gravestoneStart.y = display.contentHeight -365 sceneGroup:insert( gravestoneStart ) local soulStart = display.newImageRect( decorSheet, 4, 30, 40 ) soulStart.x = platformStart.x + 30 soulStart.y = platformStart.y - 135 sceneGroup:insert( soulStart ) local platform1 = display.newImageRect( platformSheet, 1, 100, 100 ) platform1.x = display.contentWidth -500 platform1.y = display.contentHeight -399 sceneGroup:insert( platform1 ) local platform2 = display.newImageRect( platformSheet, 11, 300, 150 ) platform2.x = display.contentWidth -320 platform2.y = display.contentHeight -393 sceneGroup:insert( platform2 ) local platform3 = display.newImageRect( platformSheet, 1, 100, 100 ) platform3.x = display.contentWidth -140 platform3.y = display.contentHeight -399 platform3:scale( -1, 1 ) sceneGroup:insert( platform3 ) local platform4 = display.newImageRect( platformSheet, 7, 300, 150 ) platform4.x = display.contentWidth +200 platform4.y = display.contentHeight -322 sceneGroup:insert( platform4 ) local platform5 = display.newImageRect( platformSheet, 8, 300, 200 ) platform5.x = display.contentWidth +482 platform5.y = display.contentHeight -391 sceneGroup:insert( platform5 ) local platform6 = display.newImageRect( platformSheet, 6, 100, 100 ) platform6.x = display.contentWidth +680 platform6.y = display.contentHeight -440 sceneGroup:insert( platform6 ) local platform7 = display.newImageRect( platformSheet, 4, 300, 162 ) platform7.x = display.contentWidth +1000 platform7.y = display.contentHeight -100 sceneGroup:insert( platform7 ) local platform8 = display.newImageRect( platformSheet, 11, 300, 178 ) platform8.x = display.contentWidth +1300 platform8.y = display.contentHeight -95 sceneGroup:insert( platform8 ) local reaper = display.newSprite( player, sequence\_runningReaper ) reaper:setSequence("running") reaper:play( ) reaper.x = platformStart.x reaper.y = platformStart.y - 165 sceneGroup:insert( reaper ) --local arrow = display.newImageRect( "arrow-landing.png", 100, 100 ) --arrow.x = display.contentCenterX --arrow.y = display.contentCenterY speed = 4 value = 100 --These add the physics bodies to the platfroms and reaper physics.addBody( platformStart, "static", { bounce = 0, friction = 0.2} ) physics.addBody( reaper, "dynamic", { bounce = 0, friction = 0.2} ) physics.addBody( platform1, "static", {bounce = 0, friction = 0.2, shape = A1shape} ) physics.addBody( platform2, "static", { bounce = 0, friction = 0.2} ) physics.addBody( platform3, "static", { bounce = 0, friction = 0.2, shape = A1shape} ) physics.addBody( platform4, "static", {bounce = 0, friction = 0.2} ) physics.addBody( platform5, "static", {bounce = 0, friction = 1.0, shape = B3shape} ) physics.addBody( platform6, "static", {bounce = 0, friction = 0.2} ) physics.addBody( platform7, "static", {bounce = 0, friction = 0.2} ) physics.addBody( platform8, "static", {bounce = 0, friction = 0.2} ) reaper.isFixedRotation = true --Start with Math calculations local function update( event ) --update background updateBackgrounds() end function updateBackgrounds() score = score + 1 scoreText.text = score --This line of code controls platform movement --Change the number inside parenthesis to change speed higher number mean faster --The minus sign makes the object move to the left platformStart.x = platformStart.x - (speed) soulStart.x = soulStart.x - (speed) treeStart.x = treeStart.x - (speed) gravestoneStart.x = gravestoneStart.x - (speed) platform1.x = platform1.x - (speed) platform2.x = platform2.x - (speed) platform3.x = platform3.x - (speed) platform4.x = platform4.x - (speed) platform5.x = platform5.x - (speed) platform6.x = platform6.x - (speed) platform7.x = platform7.x - (speed) platform8.x = platform8.x - (speed) --"Moves" the platforms back to the right so they can be run again if ( platformStart.x \< -500 ) then soulStart.alpha = 1 platformStart.x = platform8.x + 550 end if (gravestoneStart.x \< -500 ) then gravestoneStart.x = platformStart.x + 100 end if ( soulStart.x \< -500 ) then soulStart.x = platformStart.x + 30 end if ( treeStart.x \< -500 ) then treeStart.x = platformStart.x - 100 end if ( platform1.x \< -500 ) then --soul.alpha = 1 platform1.x = platformStart.x + 400 end if ( platform2.x \< -500 ) then --soul.alpha = 1 platform2.x = platform1.x + 200 end if ( platform3.x \< -500 ) then --soul.alpha = 1 platform3.x = platform2.x + 140 end if ( platform4.x \< -500 ) then --soul.alpha = 1 platform4.x = platform3.x + 340 end if ( platform5.x \< -500 ) then --soul.alpha = 1 platform5.x = platform4.x + 282 end if ( platform6.x \< -500 ) then platform6.x = platform5.x + 202 end if ( platform7.x \< -500 ) then platform7.x = platform6.x + 480 end if ( platform8.x \< -500 ) then platform8.x = platform8.x + 300 speed = speed + 0.5 value = value \* 4 end if ( reaper.x \>= soulStart.x-1 and reaper.x \<= soulStart.x+1 and reaper.y \>= soulStart.y-60 and reaper.y \<= soulStart.y-30 ) then score = score + value soulStart.alpha = 0 end local function collisionfunction ( self, event ) jumpcounter = 0 reaper:setSequence( "running" ) reaper:play( ) end reaper.collision = collisionfunction if ( reaper.x \< -300 or reaper.y \> 810 ) then if ( score \> highscore ) then highscore = score end Runtime:removeEventListener( "touch", ascend ) dead() end function ascend ( event ) if jumpcounter \< 2 then --audio.play( jumpSound, jumpOptions ) --HERE IS WERE IT'S BREAKING reaper:setLinearVelocity( 0, -1000 ) reaper:setSequence( "jump" ) reaper:play( ) jumpcounter = jumpcounter + 1 end end --Listens for the user to tap to make the reaper jump Runtime:addEventListener( "touch", ascend ) reaper:addEventListener( "collision" ) end --This calls the update function or run the function continuously local myTimer = timer.performWithDelay( 16.667, update, -1 ) function dead ( ) --physics.pause( ) timer.cancel( myTimer ) Runtime:removeEventListener( "touch", ascend ) --reaper:removeEventListener( "collision" ) --reaper.x = platformStart.x --reaper.y = platformStart.y - 165 --speed = 2 --value = 100 --score = 0 --physics.stop( ) --composer.removeScene( "game" ) composer.gotoScene( "title\_screen" ) end end --platform shape function scene:show( event ) local sceneGroup = self.view local phase = event.phase if ( phase == "will" ) then elseif ( phase == "did" ) then end end function scene:hide( event ) local sceneGroup = self.view local phase = event.phase if ( phase == "will" ) then elseif ( phase == "did" ) then end end function scene:destroy( event ) local sceneGroup = self.view end scene:addEventListener( "create", scene ) scene:addEventListener( "show", scene ) scene:addEventListener( "hide", scene ) scene:addEventListener( "destroy", scene ) return scene

No, take a closer look at what I’m doing.  I’m attaching the listeners directly to the objects as fields with the same name as the event. 

Then, in the finalize event I’m removing the runtime event listeners.

Note: Sorry, but I’m not reading those code posts… They’re too long (past my threshold).

Try creating a blank project (just main.lua and the following code) with this code to see how this works:

local function doTest() local obj = display.newCircle( 10, 100, 10 ) function obj.enterFrame( self ) if( not self.removeSelf or type(self.removeSelf) ~= "function" ) then return end self.x = self.x + 1 end Runtime:addEventListener( "enterFrame", obj ) -- -- Add finalize listener to clean up when object is deleted -- function obj.finalize( self ) Runtime:addEventListener( "enterFrame", self ) end obj:addEventListener("finalize") -- -- delete object in 5 seconds -- timer.performWithDelay( 5000, function() display.remove(obj) end ) -- start test again in 6 seconds timer.performWithDelay( 5000, doTest) end doTest()

How would I implement this into my code?

Sorry, but that would be  total re-write… I simply can’t do that for you.

Here are my suggestions:

  1. Don’t use composer.* till you have some experience with basic Corona features and fundamental Lua principles (scope, visibility, garbage collection, tables, modules, …)

  2. Make a standalone game module that can create() and destroy() the game.  

  3. Ensure the create function in the module above takes a group as an argument and place all objects you create in that group.

  4. To simplify handling of objects that need to be in scope of multiple functions in your module, forward declare the variables that refer to the objecst (and if needed function names that may be used in multiple module functions/methods).

  5. Be sure to assign nil to variables that referenced objects after you delete those objects.

  6. Avoid Runtime: touch listeners.  I find it much better to use local touch listeners and assign a touch listener to the background image or the object you need to catch the touch.

  7. The same goes for global collision listeners, etc.  When its an option use local listeners.

Hey, I offer a service for folks who are really stuck called ‘hitman’.  If you’re interested I could do a hit to refactor your project.

However, I think you’d be best suited starting over and focusing on fundamentals and basic learning first. 

Jumping right into making a game is sexy and fun sounding, but 99% of the time leads to total confusion. 

Better to make super tiny mechanical and functional experiments first, then when you have your feet under you, combine your accrued knowledge into a bigger project, eventually getting to the point where you make a game.

There are a couple of issues you still have.

First, you’re still doing things inside your updateBackgrounds() function that should only happen once.  These two lines are being executed 60 times per second too:

 Runtime:addEventListener( "touch", ascend ) reaper:addEventListener( "collision" )

Then your “ascend” function doesn’t handle touches properly. It will get called multiple times. It will be called once when the touch begins, one when it ends and multiple times if your finger moves during the event.  The code in the touch handler will execute multiple times. Still, I don’t see where reaper is getting destroyed, which would be a reason why you’re getting the error you’re getting.

So study your code and see how reaper can get destroyed and see if your ascend function is getting called after reaper has been removed (or called before you add the physics body.

Rob