- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
在我被反对票钉在十字架上之前,让我说我已经对此进行了研究,但我仍然不明白为什么我会收到这个错误。
我有一个玩家试图防御的核心,您可以从中射出小激光来防御即将到来的 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/
我正在尝试用 Swift 编写这段 JavaScript 代码:k_combinations 到目前为止,我在 Swift 中有这个: import Foundation import Cocoa e
我是一名优秀的程序员,十分优秀!