luacoronasdkcollision-detectionnullcorona-storyboard

event.other is nil in onCollision after resuming the scene with storyboard library [CORONA sdk]


I'm having a strange error developing with Corona SDK relating to collision-detection and the storyboard lib.

Here is my onCollision listener:

local function onBottomBorderCollision( event )    
    if (event.other.isBall) then
        local index = table.indexOf( ballArray, other )
        table.remove( ballArray, index )
        event.other:removeSelf( )
        event.other = nil
        updateLife(false)
        updateScore(false)
    end
end

This works fine at first launch, but after getting back to the menu screen (using storyboard.goToScene("menu")) and replaying the game, now this listener will trigger the following error every time one of my ball hits the bottom border:

attempt to index field "other"(a nil value)

I do create the proper listeners in scene:onEnterScene(scene) so it's not something to do with them, moreover this other listener never generate the error:

local function onPlayerCollision( event )


    if(event.other.isBall) then
       xVel, yVel = event.other:getLinearVelocity( )
       event.other:setLinearVelocity( event.other.XLinearVelocity, yVel )

   end

end

I am stuck right now... please help!


Solution

  • Actually, this type of error is caused mainly due to to some active function call/timers/transitions, which is not yet cancelled before changing the scene.

    attempt to index field "other"(a nil value)
    

    The above error mentions that any object/ it's property is being called/fetched, but it is not in the current occurrence or the scene. So, check whether you are cancelling your timers, transitions and runtime event listeners.


    In your case, it may be due to the failure in cancellation of collision detection function onBottomBorderCollision in runtime. If you are calling it in enterFrame, then you have to cancel it before scene change. YOu can do it as below:

    Runtime:removeEventListener("enterFrame",onBottomBorderCollision)
    

    Update: You can't stop the physics engine while collision check is running. So do as follows:

    function actualSceneChange()
         physics.stop() -- stop physics here
         -- call scene chage
         director:changeScene("menuPageName") -- call your scene change method
    end
    
    function initiatingSceneChange()
        physics.pause() -- pause physics here
        -- stop unwanted event listeners
        Runtime:removeEventListener("enterFrame",onBottomBorderCollision) 
    
        if(timer_1)then timer.cancel(timer_1) end    -- stop all your timers like this.
        if(trans_1)then transition.cancel(trans) end -- stop all your transitions like this.
    
        timer.performWithDelay(1000,actualSceneChange,1)
    end