【问题标题】:Swift detecting collisions and setting enums快速检测碰撞和设置枚举
【发布时间】:2017-08-13 22:55:56
【问题描述】:

我试图弄清楚设置枚举时检测碰撞的工作原理。我有几个不同的节点,我可以检测到碰撞并设置了工作,但是我刚刚完成了它并且不知道如何正确设置它。

enum ColliderType: UInt32{

    case ship = 1
    case object = 2
    case fuel = 4
    case alien = 8
    case torp = 16

}

然后我将每个节点设置为这样:

mete.physicsBody!.contactTestBitMask = ColliderType.object.rawValue
mete.physicsBody!.categoryBitMask = ColliderType.object.rawValue
mete.physicsBody!.collisionBitMask = ColliderType.object.rawValue

alien.physicsBody!.contactTestBitMask = ColliderType.torp.rawValue
alien.physicsBody!.categoryBitMask = ColliderType.alien.rawValue
alien.physicsBody!.collisionBitMask = ColliderType.alien.rawValue

fuel.physicsBody!.contactTestBitMask = ColliderType.ship.rawValue
fuel.physicsBody!.categoryBitMask = ColliderType.fuel.rawValue
fuel.physicsBody!.collisionBitMask = ColliderType.fuel.rawValue


ship.physicsBody!.contactTestBitMask = ColliderType.object.rawValue
ship.physicsBody!.categoryBitMask = ColliderType.ship.rawValue
ship.physicsBody!.collisionBitMask = ColliderType.ship.rawValue

torpedoNode.physicsBody!.contactTestBitMask = ColliderType.alien.rawValue
torpedoNode.physicsBody!.categoryBitMask = ColliderType.torp.rawValue
torpedoNode.physicsBody!.collisionBitMask = ColliderType.alien.rawValue

然后为了检测船和仪表之间的碰撞,我正在使用以下代码:

if contact.bodyA.categoryBitMask == ColliderType.object.rawValue || contact.bodyB.categoryBitMask == ColliderType.object.rawValue

船与我使用的燃料发生碰撞:

if contact.bodyA.categoryBitMask == ColliderType.fuel.rawValue || contact.bodyB.categoryBitMask == ColliderType.fuel.rawValue {

最后是鱼雷和外星人之间的碰撞,我使用以下代码:

if contact.bodyA.categoryBitMask == ColliderType.alien.rawValue || contact.bodyB.categoryBitMask == ColliderType.torp.rawValue {

一切正常,但是我现在正试图检测飞船和外星人之间的碰撞,但我不知道该怎么做。我需要尝试理解逻辑并清理此代码。

【问题讨论】:

标签: swift enums sprite-kit collision


【解决方案1】:

如果您希望在船舶接触(而不是碰撞)陨石、燃料或外星人时通知您的代码,您应该:

ship.physicsBody!.contactTestBitMask = ColliderType.object.rawValue | ColliderType.fuel.rawValue | ColliderType.alien.rawValue

即联系人测试位掩码等于object OR fuel OR alien

在 SO 上查看这个简单的 Sprite-Kit 项目,其中包含接触、碰撞、触摸事件和辅助函数 (checkPhysics()),它将分析您的物理设置 - 此函数可以放入任何 sprite-Kit 项目并调用显示哪些物理物体之间会发生什么接触和碰撞。

Attack button in SpriteKit

其他信息:

值得记住的是,除非您另有说明,否则一切都会与其他一切发生冲突,并且没有任何东西会接触任何东西。

即每个节点的collisonBitMask 设置为所有1s,其contactTestbitMask 设置为所有0s。

nodeA 和 nodeB 之间的接触或碰撞可以通过以下方式关闭

nodeA.physicsBody?.collisionBitMask &= ~nodeB.category

我们将 nodeA 的位掩码与 nodeB 的类别位掩码的逆(逻辑非,~ 运算符)逻辑与,以“关闭”该位 nodeA 的位掩码。

nodeA 和 nodeC 之间的接触或碰撞可以在任何时候ON使用:

nodeA.physicsBody?.contactTestBitMask |= nodeC.category

我们将 nodeA 的 bitMask 与 nodeC 的类别位掩码进行逻辑与运算,以“打开”nodeA 的 bitMask 中的那个位。

您可以确保每个形状“反弹”屏幕边缘,如下所示:

// Make sure everything collides with the screen edge
enumerateChildNodes(withName: "//*") { node, _ in
    node.physicsBody?.collisionBitMask |= self.edgeCategory  //Add edgeCategory to the collision bit mask
}

【讨论】:

  • 我已将 ColliderType.alien.rawValue 添加到船舶联系位掩码中。如果contact.bodyA.categoryBitMask == ColliderType.alien.rawValue || 我会使用吗? contact.bodyB.categoryBitMask == ColliderType.alien.rawValue {?我尝试了一些组合,但它通常会混淆其他联系人。
  • @Alex - 是的,但是如果你想避免所有那些 'if..then' 以及 bodyA 和 bodyB 的事情,看看这个以更简洁的方式来实现 didBegin(contact:) - @ 987654322@
猜你喜欢
  • 2010-10-16
  • 1970-01-01
  • 1970-01-01
  • 2019-07-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-09-05
相关资源
最近更新 更多