【发布时间】:2017-03-28 09:09:26
【问题描述】:
我遵循 Sprite Kit 指南,在场景编辑器中,它要求我将 Category Mask 设置为 32,Collision Mask 设置为 11。这些数字有什么关系?
【问题讨论】:
标签: ios macos sprite-kit
我遵循 Sprite Kit 指南,在场景编辑器中,它要求我将 Category Mask 设置为 32,Collision Mask 设置为 11。这些数字有什么关系?
【问题讨论】:
标签: ios macos sprite-kit
Sprite-Kit 游戏引擎会自动处理碰撞;联系人由您的代码处理 - 当您感兴趣的联系人发生时,您的代码(didBeginContact'for Swift 2,'didBegin(contact:) for Swift 3 及更高版本)被调用。
您需要以二进制形式考虑这些位掩码,为简单起见,我们将从简单的类别位掩码开始,即场景中的每个对象仅属于一个类别。
例如在您的场景中,您有一个玩家、一个玩家导弹、一个敌人和屏幕边缘。我们假设位掩码是 8 位而不是 32 位。将每个数字视为 8 个二进制数字(8 位)的范围,每个数字是 0 或 1。
场景中的对象必须具有唯一的类别,因此我们将按如下方式分配它们:
player.categoryBitMask = 00000001 (1 in decimal)
playerMissile.categoryBitMask = 00000010 (2 in decimal)
enemy.categoryBitMask = 00000100 (4 in decimal)
screenEdge.categoryBitMask = 00001000 (8 in decimal)
如果您使用的十进制数不是 2 的幂(1、2、4、8、16、32、64、128 等),则类别位中将设置超过 1 位使事情复杂化的掩码(这意味着该对象属于多个类别)并且您的代码必须变得更复杂。
现在想想什么从什么(碰撞)中反弹。假设除了导弹穿过屏幕边缘之外,其他所有东西都会反弹。
每个对象的碰撞位掩码由表示该对象与之碰撞的对象的位组成,即:
player.collsionBitMask = 00001111 (15 in decimal) (the bits for all other objects are set)
playerMissile.collisionBitMask = 00000111 (7) (all object EXCEPT screenEdge)
enemy.collisonBitMask = 00001111 (15) (everything)
screenEdge.collisonBitMask = 00000000 (0) (collides with nothing)
现在我们考虑我们对哪些对象交互感兴趣。我们想知道什么时候:
这表示为:
player.contactTestBitMask = 00000100 (4) (the enemy's categoryBitMask)
enemy.contractTestBitMask = 00000011 (3) (the player's categoryBitMask combined with the missile's categoryBitMask))
注意,如果你想知道A和B什么时候接触,只要让A的contactTestBitMask(CTBM)包含B的categoryBitMask就足够了;您也不必将 B 的 CTBM 设置为 A 的类别。但是如果你想让它们相互反弹,那么每个对象的碰撞位掩码必须包含对方的 categoryBitMask。如果 A 的 collisonbitMask 包含 B 的类别,反之则不然,那么当 2 发生碰撞时,A 会反弹,但 B 不会受到影响。
对于您的具体示例,(类别掩码为 32,碰撞掩码为 11),categoryBitMask 为 32,即 00100000(仅保留 8 位)。碰撞位掩码为 11,即 8 + 4 + 1,因此在二进制中为“00001101”,这意味着它与 categoryBitMask 为 8、4 或 1 的对象发生碰撞,因此我假设您的场景中有具有这些 categoryBitMask 的对象。
默认情况下,所有内容都会从其他所有内容中反弹,即,collisionBitMask 全部为“1”,即 b'111111..',并且没有通知与其他任何内容的联系,即 contactTestBitMask 全部为“0”。
另外 - 所有这些都适用于物理体,而不是节点。
【讨论】: