好的 - 我确定这是重复的,Whirlwind或KnightOfDragons发布了一个解决方案,但我找不到它。Sprite-Kit为单个联系人注册多个冲突
我正在使用Sprite-Kit在Swift中编写Space Invader的克隆。我遇到的问题是,当入侵者的炸弹击中我的船时,代码有时会发生2或3次碰撞,立即结束游戏。下面是处理炸弹/船舶碰撞“didBeginContact”的部分:
case category.bomb.rawValue | category.ship.rawValue:
print("Bomb hit ship!")
let bomb = contact.bodyA.categoryBitMask == category.bomb.rawValue ? contact.bodyA.node : contact.bodyB.node
bomb?.physicsBody?.contactTestBitMask = 0 // Seems to prevent multiple contacts with same bomb
ship.physicsBody!.contactTestBitMask = 0 // We'll reset this after the death animation
bomb?.removeAllActions()
ship.removeAllActions()
bomb?.removeFromParent()
ships -= 1
if ships == 0 { endScene(won: false, withMessage: "A bomb got you!") }
,当我跑这场比赛我看:
Bomb hit ship!
2 ships left.
后1重弹击(这是正确的)
Bomb hit ship!
1 ships left.
Bomb hit ship!
0 ships left.
第二次炸弹袭击后(这是错误的)。
我从来没有联系方式没有被注册,有时(50%?)它完美的作品。其他时候我已经看到自己有四艘船!我相信这是明显的/基本的,但我却错了。
我对将炸弹和船舶设置为contactTestBitMask为0的意见显然是错误的。我知道这不应该是必要的,因为当接触发生时我移除了炸弹,所以它不应该再次发生。
如何保证联系人只处理一次?
================================
更新:我添加2个print
报表提供更多调试信息:
print("bodyA is \(contact.bodyA.node!.name)")
print("bodyB is \(contact.bodyB.node!.name)")
这是let bomb = contact.bodyA.category
...语句之后,现在我得到:
Bomb hit ship!
bodyA is Optional("bomb")
bodyB is Optional("playerShip")
1 ships left.
后1弹击中,并且:
Bomb hit ship!
fatal error: unexpectedly found nil while unwrapping an Optional value
第二次炸弹袭击后。所以在第二次碰撞后,bodyA是零,所以我不明白为什么Sprite-Kit实际上发生了碰撞?
任何想法?
Sprite-Kit已经排队等待船与炸弹之间的多重碰撞(它不应该但是嘿,谁知道),然后SK每次碰撞时都会调用dBC,因为我把炸弹第一次,第二次和以后都是零。所以我需要在炸弹下落时将其标记为激活状态,检查炸弹是否在我检测到碰撞时激活,并将其设置为不激活而不是在dBC中删除它? –
从我所看到的情况来看,didBeginContact在两个物体之间有多个接触点时被多次触发。当您从纹理创建物体或者即使物体是圆形时,也可能发生这种情况。我目前无法真正找到自己的答案(我正在使用手机),但是这个解释了您遇到的崩溃:http://stackoverflow.com/a/37003007解决问题的方法很少。一种方法是检查node.parent是否为零,如果为true,则从didBeginContact返回。另一种方法是在子弹节点上标记。也许还有其他一些方法,我不记得更多。 – Whirlwind
是@Whirlwind说过的,请记住,您确实不想在didcontactbegin阶段从父项中移除,因为可能有些情况下您需要节点仍然在场景中进行第二次联系(一个子项击中2个重叠敌人,也许你想要一个幽灵,谁知道)我个人喜欢保留categoryBitMask位31处理活着或死亡,并在物理检查期间,跳过这些节点 – Knight0fDragon