【问题标题】:event.other is nil in onCollision after resuming the scene with storyboard library [CORONA sdk]使用情节提要库 [CORONA sdk] 恢复场景后,onCollision 中的 event.other 为零
【发布时间】:2014-07-21 05:50:42
【问题描述】:

我在使用 Corona SDK 开发与碰撞检测和故事板库有关的奇怪错误。

这是我的onCollision 听众:

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

这在第一次启动时运行良好,但在返回菜单屏幕后(使用storyboard.goToScene("menu")) 并重新玩游戏,现在这个监听器将在我的一个球击中底部边框时触发以下错误:

尝试索引字段“其他”(零值)

我确实在scene:onEnterScene(scene) 中创建了适当的侦听器,所以这与它们无关,而且这个其他侦听器永远不会产生错误:

local function onPlayerCollision( event )


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

   end

end

我现在卡住了...请帮助!

【问题讨论】:

    标签: lua coronasdk collision-detection null corona-storyboard


    【解决方案1】:

    我相信这个问题是因为当你切换场景时情节提要在内存中保存了一些变量。显示对象被破坏,但引用仍然存在。您可能正在 CreateScene 函数中初始化您的显示对象,如果您不移除场景,该函数只会被调用一次。

    在菜单的进入场景功能中破坏场景可能会解决问题。 这是由Storyboard.removeScene 函数完成的。

    在menu.lua的“EnterScene”函数中,添加一行删除场景。例如。如果您的场景名称是游戏:

    storyboard.removeScene("game")
    

    你可以了解更多destroyScene和purgeScene的区别here

    【讨论】:

    • 试过了,但没有运气!我相信问题是由于物理引擎没有正确停止引起的,但现在我不知道什么时候停止它,因为我的 changeScene 在碰撞检测事件中被调用!
    【解决方案2】:

    其实这种类型的错误主要是由于一些活跃的函数调用/定时器/transitions,在改变场景之前还没有取消。

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

    上述错误提到正在调用/获取任何对象/它的属性,但它不在当前事件或场景中。因此,请检查您是否取消了计时器、转换和运行时事件侦听器。


    在您的情况下,可能是由于在运行时取消碰撞检测功能onBottomBorderCollision 失败。如果您在 enterFrame 中调用它,那么您必须在场景更改之前取消它。你可以这样做:

    Runtime:removeEventListener("enterFrame",onBottomBorderCollision)
    

    更新:您无法在碰撞检查运行时停止物理引擎。因此,请执行以下操作:

    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
    

    【讨论】:

    • 我试过这个,但没有运气。我在模块底部调用了 Runtime:removeEventListener("enterFrame",onBottomBorderCollision) 但问题没有解决。
    • 您必须在返回菜单场景之前编写 'Runtime:removeEventListener("enterFrame",onBottomBorderCollision)'。也可以通过 'physics.stop()' 停止物理,停止​​所有的转换和计时器.... :)
    • 实际上,我在改变场景之前就解决了调用“physics.pause()”的问题。由于在我的碰撞检测器的函数 UpdateLifes() 中调用了场景变化,因此调用physics.stopgeneretase 发出警告。由于我无法在碰撞期间停止物理引擎,现在我需要检查代码中其他地方的生命值是否
    • @Psicolabile:是的,没错。当有碰撞检测时,您不能调用physics.stop()。所以首先,你必须暂停物理,然后你必须停止所有的事件监听器、定时器和转换。然后你需要稍微延迟一下停止物理,并调用场景更改。我将编辑我的答案以便正确理解。 :)
    • 非常感谢!用计时器暂停和停止物理解决了这个问题! ^_^ PS:请继续关注,因为我很快就会发布一个关于storyboard scene.view 属性的问题! ;)
    猜你喜欢
    • 1970-01-01
    • 2016-04-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多