gpt4 book ai didi

swift - 可选展开 SKPhysics 错误

转载 作者:搜寻专家 更新时间:2023-11-01 07:14:39 25 4
gpt4 key购买 nike

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

我有一个玩家试图防御的核心,您可以从中射出小激光来防御即将到来的 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/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com