首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >无法理解碰撞位掩码是如何工作的

无法理解碰撞位掩码是如何工作的
EN

Stack Overflow用户
提问于 2016-08-21 12:02:04
回答 2查看 3.5K关注 0票数 14

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

代码语言:javascript
复制
firstNode.physicsBody?.collisionBitMask = 0b01
secondNode?.collisionBitMask = 0b10

既然SpriteKit对这两个数字做了AND运算,那么结果不应该是自10 & 01 = 00以来的00吗?

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

谢谢。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-08-21 13:26:39

这不是碰撞处理的工作方式。当两个物体相交时,物理引擎在当前体collisionBitMask和他人身体categoryBitMask之间执行逻辑categoryBitMask运算符

当两个物理物体相互接触时,可能会发生碰撞。通过执行逻辑和操作,将该主体的碰撞掩码与另一个主体的类别掩码进行比较。如果结果是一个非零值,这个主体会受到碰撞的影响。每个身体独立地选择它是否想被另一个身体所影响。例如,您可以使用它来避免碰撞计算,因为碰撞计算会对物体的速度造成微不足道的变化。

来源

结果取决于如何在这两个身体上设置categoryBitMaskcategoryBitMask的默认值是0xFFFFFFFF,意味着设置了所有位。因此,当您在0xFFFFFFFF0b100b01之间执行&时,结果将是非零值,因此会发生冲突。

举个例子,你的身体是这样的:

代码语言:javascript
复制
spriteA.physicsBody?.categoryBitMask = 0b01
spriteA.physicsBody?.collisionBitMask = 0b01

代码语言:javascript
复制
spriteB.physicsBody?.categoryBitMask = 0b10
spriteB.physicsBody?.collisionBitMask = 0b10

会给你你想要的结果。而且,这可能不是您所需要的确切设置,它只是一个简单的例子,您将不得不根据您的需要更改值。在这种情况下,spriteA只会与categoryBitMask设置为0b01的物体发生碰撞。spriteB也是如此,它将与categoryBitMask设置为0b10的物体发生碰撞。

另外,如果您不希望这些精灵能够与任何东西发生冲突,只需将它们的collisionBitMask属性设置为0。

票数 11
EN

Stack Overflow用户

发布于 2016-08-22 08:23:06

这不是用碰撞位来测试节点间交互的方法。

  • categoryBitMask是对象的类别。
  • collisionBitMask是对象与之碰撞时响应的对象。
  • 当指定的位掩码发生交集时,contactTestBitMask用于通知。

假设我有以下内容:

代码语言:javascript
复制
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

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

代码语言:javascript
复制
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.
    }
  1. 变量碰撞使用的是按位或,也就是。在这种情况下(如果玩家接触到敌人),它得到玩家(bodyA)的类别( 2 ),它得到敌人的类别(bodyB),即4。因此,2 (0b10)或4 (0b100)等于分配给碰撞的6 (0b110)。
  2. 因此,在if语句中,它检查6的碰撞是否等于(PC.player \ PC.enemy),这是真的,因此玩家和敌人之间发生了交互,因为如果是6 == 6。

您可以使用变量冲突来测试任何交互。例如,在我的测试游戏中,我有下面的函数来测试所接触的对象。

代码语言:javascript
复制
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()
        }
    }
}
票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/39063949

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档