SpriteKit中的物理联系人

时间:2016-10-08 06:43:54

标签: sprite-kit physics bit-masks skphysicscontact

是否有可能解释bitmasking如何适用于这种简单的情况:

 A big (blue) ball.    Contact BitMask 0b0001

 A medium (red) ball.  Contact BitMask 0b0010

 A small (white) ball. Contact BitMask 0b0100

它们之间没有碰撞,因为它们之间的某种程度上是关闭的。我假设将他们的碰撞掩码设置为00一直到32位...但是让我们留下另一个问题,我还没弄明白如何关闭它们。

将每个球设置为具有唯一的接触位掩码,在接触时会提供哪些联系信息?

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

是否可以在任何指定联系人中仅通过最大球接收联系信息?

UPDATE:

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

但我真正理解的是了解bitmasking如何提供逻辑,以便确定"谁"参与任何联系。

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

更新2:

了解流程进展情况:

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

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

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

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

  4. 在注册为委托的同一个SKView子类中,使用代码填充联系人回调

  5. 创建一些魔术代码,用于确定谁与谁联系。

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

2 个答案:

答案 0 :(得分:2)

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

在检查冲突时,物理引擎的宽相例程仅将这些对报告为可能发生碰撞,其碰撞位掩码中至少有一个公共位设置为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,但是根据我从this SO answer获得的少量信息,contactTestBitmask设置了在联系时引发事件的类别,而collisionBitmask集合身体实际碰撞的类别。因此,如果您只想从涉及蓝色球的联系人获取联系信息,则可以将contactTestBitmask设置为上面示例中的值。

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

作为旁注,您可能希望使用适当的游戏引擎(如Unity)来实现这一切。

答案 1 :(得分:1)

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

contactBitMask告诉精灵它应该寻找的名称。

因此在物理阶段,引擎将获取给定的精灵,并使用contactBitMask中提供的搜索名称查找所有其他物理精灵。

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

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