【问题标题】:What are Sprite Kit's "Category Mask" and "Collision Mask"?Sprite Kit 的“类别蒙版”和“碰撞蒙版”是什么?
【发布时间】:2017-03-28 09:09:26
【问题描述】:

我遵循 Sprite Kit 指南,在场景编辑器中,它要求我将 Category Mask 设置为 32,Collision Mask 设置为 11。这些数字有什么关系?

【问题讨论】:

    标签: ios macos sprite-kit


    【解决方案1】:
    • 类别位掩码告诉 Sprite-Kit 这是什么类型的对象。
    • 碰撞位掩码告诉 Sprite Kit 这个对象是什么对象 碰撞(即会击中并反弹)。
    • ContactTest 位掩码告诉 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”。

    另外 - 所有这些都适用于物理体,而不是节点。

    【讨论】:

    • 我正在打印这个,然后在我四处走动时把它挂在一个挂在我面前的衣架上。驴寻找胡萝卜。
    • 我打算做一篇关于 tis 主题的文档帖子,然后再写一篇关于对一个对象使用多个类别以及如何关闭和打开单个 contactTest 和碰撞位(例如播放器已收集金币,10秒内不接触蓝色怪物)。
    • 很遗憾,没有更好的平台来获得这种洞察力和智慧,并且 SO 已经设法以各种可能的方式完全搞砸了 SO.docs,而我没有以其他方式'真的认为是可能的。
    猜你喜欢
    • 2020-05-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多