'didRemoveListener' Error when I try to go to one scene from another on a collision event

So I am trying to go from one scene to another when my game’s goal collides with the ball. This is my code for the level:

local storyboard = require( “storyboard” )
local scene = storyboard.newScene()
local loadsave = require(“loadsave”)
local physics = require(“physics”)
physics.start()
physics.setGravity( 0, 0 )

local bg
local ball
local goal
local topwall
local bottomwall
local rightwall
local leftwall
local menub
local bounces
local bouncestext
local taps
local restartb
local tuttext

local function loader()
    gamestuff = loadsave.loadTable(“gamestuff.json”)
end

local function save()
    loadsave.saveTable(gamestuff, “gamestuff.json”)
end

local function gotomenu(event)
    if(event.phase == “ended”) then
        storyboard.gotoScene(“menu”)
    end
end

local function hit(event)
    if(event.phase == “ended” and bounces > 0 and event.object1 ~= “goal” and event.object2 ~= “goal”) then
        bounces = bounces -1
        bouncestext.text = "Bounces: "…bounces
    end
end

local function win(event)
    if(event.phase == “ended” and bounces > 0) then
        if(gamestuff.level < gamestuff.lastlevel or gamestuff.level == gamestuff.lastlevel) then
            gamestuff.level = gamestuff.level + 1
            save()
        end
        storyboard.gotoScene(“levelend”) –THIS IS WHERE THE ERROR COMES FROM
    end
end

local function restart(event)
    if(event.phase == “ended”) then
        --storyboard.gotoScene(“restart”)
    end
end

local function shoot(event)
    if(event.phase == “began” and taps > 0) then
        local speed = 400
        local deltaX = event.x - ball.x
        local deltaY = event.y - ball.y
        local normDeltaX = deltaX / math.sqrt(math.pow(deltaX,2) + math.pow(deltaY,2))
        local normDeltaY = deltaY / math.sqrt(math.pow(deltaX,2) + math.pow(deltaY,2))

        ball:setLinearVelocity( normDeltaX  * speed, normDeltaY  * speed )
        print(event.x)
        print(event.y)
        taps = taps -1
    end
end

function scene:createScene(event)
    local group = self.view
    bounces = 4
    taps = 1
    bg = display.newImage(“img/bg.png”)
    bg.x = display.contentWidth/2
    bg.y = display.contentHeight/2
    
    ball = display.newImage(“img/ball.png”)
    ball.x = display.contentWidth/2
    ball.y = display.contentHeight/2
    physics.addBody(ball, “dynamic”, {friction=0, bounce = 1, radius=20})
    
    topwall = display.newImage(“img/topwall.png”)
    topwall.x = display.contentWidth/2
    topwall.y = topwall.contentHeight
    physics.addBody(topwall, “static”, {friction=0, bounce = 1})
    
    bottomwall = display.newImage(“img/topwall.png”)
    bottomwall.x = display.contentWidth/2
    bottomwall.y = display.contentHeight - bottomwall.contentHeight
    physics.addBody(bottomwall, “static”, {friction=0, bounce = 1})
    
    leftwall = display.newImage(“img/sidewall.png”)
    leftwall.x = leftwall.contentWidth
    leftwall.y = display.contentHeight/2
    physics.addBody(leftwall, “static”, {friction=0, bounce = 1})
    
    rightwall = display.newImage(“img/sidewall.png”)
    rightwall.x = display.contentWidth - rightwall.contentWidth
    rightwall.y = display.contentHeight/2
    physics.addBody(rightwall, “static”, {friction=0, bounce = 1})
    
    goal = display.newImage(“img/goal.png”)
    goal.x = display.contentWidth/6
    goal.y = display.contentWidth/6
    physics.addBody(goal, “static”, {friction=0, bounce = 1})
    
    bouncestext = display.newText("Bounces: "…bounces, 0, 0, native.systemFont, 30)
    bouncestext.x = display.contentWidth/2
    bouncestext.y = bottomwall.y - bottomwall.contentHeight - bouncestext.contentHeight/2
    bouncestext:setFillColor(1,1,1)
    
    menub = display.newImage(“img/menubutton.png”)
    menub.x = bouncestext.x - bouncestext.contentWidth/2 - menub.contentWidth/1.5
    menub.y = bouncestext.y
    
    restartb = display.newImage(“img/restart.png”)
    restartb.x = bouncestext.x + bouncestext.contentWidth/2 + menub.contentWidth/1.5
    restartb.y = menub.y
    
    tuttext = display.newText(“Tap in the direction of the star to finish the level”, 0,0, display.contentWidth/4, display.contentHeight/2, native.systemFont, 25)
    tuttext.x = display.contentWidth - tuttext.contentWidth
    tuttext.y = topwall.y - tuttext.contentHeight
    
    group:insert(bg)
    group:insert(ball)
    group:insert(goal)
    group:insert(topwall)
    group:insert(bottomwall)
    group:insert(rightwall)
    group:insert(leftwall)
    group:insert(bouncestext)
    group:insert(menub)
    group:insert(restartb)
    group:insert(tuttext)
    
    
end

function scene:enterScene(event)
    loader()
    gamestuff.lastlevel = 1
    bounces = 4
    taps = 1
    if(gamestuff.level < gamestuff.lastlevel) then
        gamestuff.level = gamestuff.lastlevel
        save()
    end
    Runtime:addEventListener(“touch”, shoot)
    menub:addEventListener(“touch”, gotomenu)
    restartb:addEventListener(“touch”, restart)
    goal:addEventListener(“collision”, win)
    ball:addEventListener(“collision”, hit)
    
end

function scene:exitScene(event)
    Runtime:removeEventListener(“touch”, shoot)
    menub:removeEventListener(“touch”, gotomenu)
    restartb:removeEventListener(“touch”, restart)
    goal:removeEventListener(“collision”, win)
    ball:removeEventListener(“collision”, hit)
end

function scene:didExitScene(event)
    storyboard.removeScene(“level1”) --If I put this line in exitScene, then I get a proxy error about “insert”
end

function scene:destroyScene(event)
    local group = self.view
    bg:removeSelf()
    ball:removeSelf()
    goal:removeSelf()
    topwall:removeSelf()
    bottomwall:removeSelf()
    rightwall:removeSelf()
    leftwall:removeSelf()
    menub:removeSelf()
    bounces = nil
    bouncestext:removeSelf()
    taps = nil
    restartb:removeSelf()
    tuttext:removeSelf()
    gamestuff = nil
    
    bg = nil
    ball = nil
    goal = nil
    topwall = nil
    bottomwall = nil
    rightwall = nil
    leftwall = nil
    menub = nil
    bouncestext = nil
    restartb = nil
    tuttext = nil
    
end

scene:addEventListener(“createScene”, scene)
scene:addEventListener(“enterScene”, scene)
scene:addEventListener(“exitScene”, scene)
scene:addEventListener(“didExitScene”, scene)
scene:addEventListener(“destroyScene”, scene)

return scene

Here is the code for the “levelend” scene:

local storyboard = require( “storyboard” )
local scene = storyboard.newScene()
local loadsave = require(“loadsave”)

local gamestuff = {}
local leveltries = {}
local bg
local title1
local title2
local retryb
local nextb
local menub
local triestext

local options =
{
    effect = “slideLeft”,
    time = 400
}

local function loader()
    gamestuff = loadsave.loadTable(“gamestuff.json”)
    leveltries = loadsave.loadTable(“leveltries.json”)
    
    loadsave.saveTable(gamestuff, “gamestuff.json”)
    loadsave.saveTable(leveltries, “leveltries.json”)
end

local function retry(event)
    if(event.phase == “ended”) then
        storyboard.gotoScene(“level”…tostring(gamestuff.lastlevel), options)
    end
end

local function gotomenu(event)
    if(event.phase == “ended”) then
        storyboard.gotoScene(“menu”, options)
    end
end

local function nextlevel(event)
    if(event.phase == “ended”) then
        if(gamestuff.won == true) then
            storyboard.gotoScene(“level”…tostring(gamestuff.lastlevel + 1), options)
        end
    end
end

function scene:createScene(event)
    local group = self.view
    
    bg = display.newImage(“img/bg.png”)
    bg.x = display.contentWidth/2
    bg.y = display.contentHeight/2
    
    title1 = display.newImage(“img/goodjob.png”)
    title1.x = display.contentWidth/2
    title1.y =  title1.contentHeight *0.8
    
    title2 = display.newImage(“img/tryagain.png”)
    title2.x = title1.x
    title2.y = title1.y
    
    triestext = display.newText("Tries:  ", 0,0, native.systemFont, 45)
    triestext.x = display.contentWidth/2
    triestext.y = display.contentHeight/2
    
    menub = display.newImage(“img/menubutton.png”)
    menub.x = menub.contentWidth*1.5
    menub.y = display.contentHeight - menub.contentHeight
    
    retryb = display.newImage(“img/retry.png”)
    retryb.x = display.contentWidth/2
    retryb.y = menub.y - retryb.contentHeight/3
    
    nextb = display.newImage(“img/nextbutton.png”)
    nextb.x = display.contentWidth - nextb.contentWidth*1.5
    nextb.y = menub.y
    
    group:insert(bg)
    group:insert(title1)
    group:insert(title2)
    group:insert(menub)
    group:insert(retryb)
    group:insert(nextb)
    group:insert(triestext)
    
    

end

function scene:enterScene(event)
    loader()
    leveltries[gamestuff.lastlevel] = leveltries[gamestuff.lastlevel] + 1
    triestext.text = "Tries:  "…tostring(leveltries[gamestuff.lastlevel])
    if(gamestuff.won == true) then
        title1.isVisible = true
        title2.isVisible = false
        nextb.alpha = 1
    else
        title2.isVisible = true
        title1.isVisible = false
        nextb.alpha = 0.5
    end
    retryb:addEventListener(“touch”, retry)
    nextb:addEventListener(“touch”, nextlevel)
    menub:addEventListener(“touch”, gotomenu)
    
end

function scene:exitScene(event)
    retryb:removeEventListener(“touch”, retry)
    nextb:removeEventListener(“touch”, nextlevel)
    menub:removeEventListener(“touch”, gotomenu)
    
end

function scene:didExitScene(event)
    storyboard.removeScene(“levelend”)
    
end

function scene:destroyScene(event)
    bg:removeSelf()
    title1:removeSelf()
    title2:removeSelf()
    menub:removeSelf()
    retryb:removeSelf()
    nextb:removeSelf()
    triestext:removeSelf()
    
    bg = nil
    title1 = nil
    title2 = nil
    menub = nil
    retryb = nil
    nextb = nil
    triestext = nil
    gamestuff = nil
    leveltries = nil

end

scene:addEventListener( “createScene”, scene )

scene:addEventListener( “enterScene”, scene )

scene:addEventListener( “exitScene”, scene )
 
scene:addEventListener( “didExitScene”, scene )

scene:addEventListener( “destroyScene”, scene )
 
 
 return scene

Could this be because both scene have local variables and event listeners that are named the same?

Not as long as they are all either locals, or methods of locals (e.g. scene:enterScene is not declared explicitly local but it is because scene is declared local)

I’ve never used Storyboard, but I notice you are calling removeScene(“level1”) in the scene itself - you call your win() function which then does the gotoScene(“level end”) - this will trigger the various events, and in didExit() when it is being called the scene may still be in use, so you purge something (with removeScene()) that is still active, so it gets confused.

Is there a particular reason you don’t want Corona to manage the Scene purges ? If so have you considered the purgeOnSceneChange member ?

Can you be a bit more precise in the error you’re getting?  Can you post the whole stack trace?  Also what version of Corona SDK are you running?
 

Rob

Might be worth putting this in a sticky if it isn’t already. It’s a bit difficult to decode from “it doesn’t work” :slight_smile:

I think there is something already posted.  I’m pretty sure it’s mentioned in the basic debugging tutorial.

Not as long as they are all either locals, or methods of locals (e.g. scene:enterScene is not declared explicitly local but it is because scene is declared local)

I’ve never used Storyboard, but I notice you are calling removeScene(“level1”) in the scene itself - you call your win() function which then does the gotoScene(“level end”) - this will trigger the various events, and in didExit() when it is being called the scene may still be in use, so you purge something (with removeScene()) that is still active, so it gets confused.

Is there a particular reason you don’t want Corona to manage the Scene purges ? If so have you considered the purgeOnSceneChange member ?

Can you be a bit more precise in the error you’re getting?  Can you post the whole stack trace?  Also what version of Corona SDK are you running?
 

Rob

Might be worth putting this in a sticky if it isn’t already. It’s a bit difficult to decode from “it doesn’t work” :slight_smile:

I think there is something already posted.  I’m pretty sure it’s mentioned in the basic debugging tutorial.