无法理解碰撞位掩码的工作原理

Tre*_*vör 13 sprite-kit skphysicsbody swift

我试图在Swift中使用碰撞位掩码和接触测试位掩码,我希望两个对象不要碰撞在一起,所以我在做:

firstNode.physicsBody?.collisionBitMask = 0b01
secondNode?.collisionBitMask = 0b10
Run Code Online (Sandbox Code Playgroud)

由于SpriteKit不上这两个数字与操作,应该没有结果是00因为10 & 01 = 00

那么为什么碰撞会发生呢?

谢谢.

Whi*_*ind 10

这不是碰撞处理的工作原理.当两个物体交叉时,物理引擎AND在当前物体collisionBitMask和其他物体 之间执行逻辑运算符categoryBitMask:

当两个物理实体相互接触时,可能会发生碰撞.通过执行逻辑AND运算,将该物体的碰撞掩模与其他物体的类别掩码进行比较.如果结果为非零值,则此实体会受到碰撞的影响.每个身体独立地选择是否想要受到另一个身体的影响.例如,您可以使用它来避免碰撞计算,这会对身体的速度产生微不足道的变化.

.

所以结果取决于你如何设置categoryBitMask这两个实体.categoryBitMaskis 的默认值0xFFFFFFFF表示设置的所有位.所以,当你执行'之间0xFFFFFFFF0b100b01,其结果必然是非零值,从而碰撞.

例如,设置你的身体是这样的:

spriteA.physicsBody?.categoryBitMask = 0b01
spriteA.physicsBody?.collisionBitMask = 0b01
Run Code Online (Sandbox Code Playgroud)

spriteB.physicsBody?.categoryBitMask = 0b10
spriteB.physicsBody?.collisionBitMask = 0b10
Run Code Online (Sandbox Code Playgroud)

会给你想要的结果.此外,这可能不是您需要的确切设置,它只是一个简单的示例,您必须根据需要更改值.在这种情况下,spriteA只会与categoryBitMask设置为的主体发生冲突0b01.对于spriteB也是如此,它将与已categoryBitMask设置的主体发生冲突0b10.

此外,如果您不希望这些精灵能够与任何事物发生碰撞,只需将其collisionBitMask属性设置为0即可.


Jos*_*rez 5

这不是测试具有冲突位的节点之间的交互的方式。

  • categoryBitMask是对象的类别。
  • 这个碰撞位面具是物体碰撞时所做出的响应。
  • 当指定的位掩码发生交集时,contactTestBitMask用于通知。

假设我有以下内容:

struct PC {
    static var player: UInt32 = 0b10 //2
    static var enemy: UInt32 = 0b100 //4
    static var rock: UInt32 = 0b1000 //8
}

player.physicsBody!.categoryBitMask = PC.player
player.physicsBody!.collisionBitMask = PC.enemy | PC.rock
enemy.physicsBody!.categoryBitMask = PC.enemy
enemy.physicsBody!.collisionBitMask = PC.player
Run Code Online (Sandbox Code Playgroud)

因此,当您在didBeginContact函数中检查何时发生交互时,可以通过使用位逻辑来检查其交互是否发生。

func didBeginContact(contact: SKPhysicsCountact) {
    //1
    let collision: UInt32 = contact.bodyA.categoryBitMask | contact.bodyB.categoryBitMask

    //2
    if collision == PC.player | PC.enemy {
        //An interaction occured between the player and enemy.
    }
Run Code Online (Sandbox Code Playgroud)
  1. 变量冲突使用按位或,即|。在这种情况下(如果玩家触摸敌人),它将获得玩家(bodyA)的类别为2,并且获得敌人(bodyB)的类别为4。因此2(0b10)或4( 0b100)等于分配给碰撞的6(0b110)。

  2. 因此,然后在if语句中,它检查6的碰撞是否等于(PC.player | PC.enemy),这是正确的,因此,如果6 == 6,则玩家与敌人之间会发生相互作用。

您可以使用可变碰撞来测试任何交互。例如,在我的测试游戏中,我具有以下功能来测试触摸了哪些对象。

func didBeginContact(contact: SKPhysicsContact) {
    let collision: UInt32 = contact.bodyA.categoryBitMask | contact.bodyB.categoryBitMask

    //Collision between the penguin and land
    if collision == PhysicsCategory.Land | PhysicsCategory.Animal {
        lostLevel()
    } else if collision == PhysicsCategory.Animal | PhysicsCategory.Pillow {
        animalCounter -= 1
        if animalCounter == 0 {
            wonLevel()
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 非常感谢您的回答! (2认同)