swift - 可选展开 SKPhysics 错误

标签 swift sprite-kit collision-detection physics option-type

在我被反对票钉在十字架上之前,让我说我已经对此进行了研究,但我仍然不明白为什么我会收到这个错误。

我有一个玩家试图防御的核心,您可以从中射出小激光来防御即将到来的 meteor 。好吧,我已经设置好了一切并正常工作(无论如何大部分时间),但是每隔一段时间当激光击中 meteor 并且我的碰撞处理函数试图移除射击节点和 meteor 节点时,它会抛出这个错误:

fatal error: unexpectedly found nil while unwrapping an Optional value

同样,我对此进行了大量挖掘,但似乎无法弄清楚。

这是我的开始:

func didBegin(_ contact: SKPhysicsContact) {
    if (contact.bodyA.node?.name == "shot") { // shot A
        collisionBetween(first: (contact.bodyA.node)!, second: (contact.bodyB.node)!)
    } else if (contact.bodyB.node?.name == "shot") { // shot B
        collisionBetween(first: (contact.bodyB.node)!, second: (contact.bodyA.node)!)
    }
    if (contact.bodyA.node?.name == "core") { // core A
        collisionBetween(first: (contact.bodyA.node)!, second: (contact.bodyB.node)!)
    } else if (contact.bodyB.node?.name == "core") { // core B
        collisionBetween(first: (contact.bodyB.node)!, second: (contact.bodyB.node)!)
    }

}

这是我的 collisionBetween 函数:

func collisionBetween(first: SKNode, second: SKNode) {

    if first.name == "shot" && second.name == "sMeteor" {
        first.removeFromParent()    // these two only throw the error
        second.removeFromParent()   // every once and a while
    } else if first.name == "sMeteor" && second.name == "shot" {
        first.removeFromParent()    // these two throw the error also
        second.removeFromParent()   // but only on occasion
    } else if first.name == "mMeteor" && second.name == "shot" {
        second.removeFromParent()
    } else if first.name == "shot" && second.name == "mMeteor" {
        first.removeFromParent()
    }
    if first.name == "core" && second.name == "sMeteor" {
        second.removeFromParent() //always throws the error
    } else if first.name == "sMeteor" && second.name == "core" {
        first.removeFromParent() //always throws the error
    }

}

一段时间以来,我一直在努力解决这个错误,我觉得我对可选值有了基本的了解。仅当我尝试从父 self 中删除节点时才会抛出这些错误,并且我尝试了许多不同的方法来解决此问题,但终究无法解决。感谢任何帮助,谢谢!

最佳答案

我强烈怀疑这是由 SpriteKit 为同一个联系人生成多个联系人事件引起的。 (即它使用相同的 bodyA 和 bodyB 调用 didBegin())2 次或更多次)

第一次调用,一切正常;第二次,东西已被删除,一些节点和/或主体为零。

检查此答案是否有帮助:Sprite-Kit registering multiple collisions for single contact

如果您在 didBegin() 中放置一些打印语句,例如

func didBegin(_ contact: SKPhysicsContact) {
    print("Contact between \(contact.bodyA.node?.name) & \(contact.bodyB.node?.name)")
    if (contact.bodyA.node?.name == "shot") { // shot A

您可能已经在日志中看到:

Contact between shot and sMeteor
Contact between shot and sMeteor
Contact between shot and sMeteor

仅发生 1 次接触时。

此外,您的 didBegin()collisionBetween() 函数看起来过于复杂(加上 collisionBetween 实际上应该称为 contactBetween( ))。

我发现编写 didBegin() 的更简洁的方法是:

 func didBegin(contact: SKPhysicsContact) {
            let contactMask = contact.bodyA.categoryBitMask | contact.bodyB.categoryBitMask

            switch contactMask {

            case categoryBitMask.shot | categoryBitMask.sMeteor:
               print("Collision between shot and sMeteor")
               contact.bodyA.removeFromParent()
               contact.bodyB.removeFromParent()

            case categoryBitMask.shot | categoryBitMask.mMeteor:
               print("Collision between shot and mMeteor")
               let shot = contact.bodyA.categoryBitMask == categoryBitMask.shot ? contact.bodyA.node! : contact.bodyB.node!
               shot.removeFromParent()

            case categoryBitMask.core | categoryBitMask.sMeteor:
               print("Collision between core and sMeteor")
               let meteor = contact.bodyA.categoryBitMask == categoryBitMask.sMeteor ? contact.bodyA.node! : contact.bodyB.node!
               meteor.removeFromParent()

            default :
               //Some other contact has occurred
               print("Some other contact")
        }  
    }

只有当您的节点一次只属于一个类别时,这才真正安全,这由您决定。

如果“核心”和“mMeteor”接触会发生什么?

关于swift - 可选展开 SKPhysics 错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42848719/

相关文章:

ios - SKScene.backgroundColor不起作用。始终为默认颜色

java - 如何修复碰撞响应中的圆形和矩形重叠?

c++ - 设置碰撞检测然后处理 2D 游戏中的碰撞

ios - .ondelete 带有部分的 SwiftUI 列表

ios - 无法将文件保存在 Swift 2 文档目录内的文件夹中

Swift 4.0 解码器错误与闭包属性

ios - Parse 和 Facebook 问题 - 无法识别应用程序

ios - 无尽的背景 Sprite 套件

compiler-errors - pygame炮弹碰撞检测

ios - SKShapeNode - 动画颜色变化