2

是否可以解释位掩码如何仅适用于这种简单的情况:

 A big (blue) ball.    Contact BitMask 0b0001

 A medium (red) ball.  Contact BitMask 0b0010

 A small (white) ball. Contact BitMask 0b0100

他们之间没有碰撞,因为不知何故,这在他们之间被关闭了。我假设通过将它们的碰撞掩码设置为 00 一直到 32 位......但是让我们把它留给另一个问题,我还没有想出如何关闭这些。

将每个球设置为具有唯一的接触位掩码后,如何在它们接触时提供联系信息?

如何知道哪两个球相互接触?

是否可以让任何给定接触中的最大球只收到联系信息?


更新:

我不一定在代码之后。如果你需要代码来解释什么是什么,它是如何工作的,以及为什么不管做什么,那就去做吧。

但我真正追求的是理解位掩码如何工作以提供允许确定“谁”参与任何联系的逻辑。

我给每个球尺寸一个不同的位掩码的原因是我认为这可能有助于确定两个球之间任何给定接触中的较大球。不过,我可能错了。

更新 2:

对进展过程的理解:

据我了解,这些是该过程的一部分:

  1. 将 SKView 子类化为 SKScene 注册为符合物理世界联系通知委托。也说是这样。

  2. 将位掩码设置为希望在模拟中了解和/或控制的每种身体交互类型的类别

  3. 使用这些位掩码,通过适当地应用它们来阐明希望成为接触和/或碰撞一部分的每个对象的性质(这里有一些神奇的决策)。

  4. 在注册为委托的同一个 SKView 子类中,使用执行操作的代码覆盖联系人回调

  5. 创建一些魔术代码来确定谁/什么联系了谁。


我了解其中一些,但不了解设置联系人位掩码与命名类别位掩码的推理之间的差异,也不了解如何确定谁联系了谁。

4

2 回答 2

2

在几乎所有物理引擎中,碰撞层都由位掩码表示。同一碰撞层中的所有对象将相互碰撞。在位掩码中,每一层都由一个位表示。如果位置 0 的位打开,则对象将与其他在其位掩码中具有相同位置的位的对象发生碰撞。

在检查碰撞时,物理引擎的广泛阶段例程仅将那些在其碰撞位掩码中至少有一个公共位设置为 1 的对报告为潜在碰撞。该检查只需通过 ANDing ( &) 两个位掩码即可完成。仅当上述检查返回非零结果时,才将潜在碰撞对报告给窄相例程。

例如,如果您希望蓝色球与红色和白色球碰撞,但希望红色和白色球相互碰撞,您可以将位掩码设置为如下所示:

Blue  -> 0b0011
Red   -> 0b0001
White -> 0b0010

在您的示例中,由于没有一个物体在其碰撞位掩码中设置了一个公共位,因此它们都不会相互碰撞。在上面的示例中,由于红球和白球在其位掩码中没有共同位,因此它们不会发生碰撞。

您可能希望将所有冲突位掩码设置为-1(打开所有位)并通过 XORing 从掩码中删除位/类别。然后,上面的示例将由以下伪代码实现:

blueBody.collisionMask = -1;
whiteBody.collisionMask = -1;
redBody.collisionMask = -1;

redBodyCategory   = 0b0001;
whiteBodyCategory = 0b0010;

whiteBody.collisionMask ^= redBodyCategory;
redBody.collisionMask ^= whiteBodyCategory;

我不使用 SpriteKit,但是从我从这个 SO answer获得的少量信息中,contactTestBitmask设置了在接触时将引发事件的类别,而collisionBitmask设置了正文将实际发生碰撞的类别。因此,如果您只想从涉及Blue ball的联系人中获取联系信息,您可以将 设置contactTestBitmask为上面示例中的值。

要检查哪些球相互碰撞,您必须检查位掩码值并辨别哪个是哪个。在上面的例子中,蓝色球可以通过检查是否body.contactTestBitmask == 0b0011,等等来识别其他身体。

附带说明一下,您可能想考虑使用像Unity这样的适当游戏引擎,这将使这一切变得更加容易。

于 2016-10-08T07:10:50.890 回答
1

首先,您需要定义您的精灵是什么,这就是categoryBitMask它的用途。将此视为您的精灵的二进制名称,每个数字都是唯一的名称。现在可以为您的精灵指定多个名称,但为了简单起见,我们将其保留为一个。

contactBitMask告诉精灵它应该寻找什么名字。

因此,在物理阶段,引擎将采用给定的精灵,并使用contactBitMask.

在此之后,对原始精灵和过滤列表中的精灵执行评估。

在一个联系人上,didBegin(contact:)被调用,并且联系人包含您需要的所有信息,包括 2 个联系人正文。然后,您检查categoryBitMask以获取相关精灵的名称,并根据这些名称进行调节。

于 2016-10-08T11:31:27.420 回答