Sprite Kit中允许的categoryBitMask数量的最大值是多少?

4

我听说每个Sprite Kit游戏只允许使用32种不同的categorybitmask。有没有办法解决这个限制?因为我需要更多(大约是3-4倍,因为我的游戏是一个开放世界的游戏)。我设置了我的categorybitmask如下:

static const uint64_t boundaryCategory    = 0x1 << 0;
static const uint64_t mainCharCategory    = 0x1 << 1;
...
static const uint64_t someOtherCategory   = 0x1 << 31;

我甚至将uint32_t更改为uint64_t,希望能将可以使用的categorybitmask数量翻倍。不幸的是,它并没有实现这一目标。如果有人知道绕过此限制的技巧,我将非常感激。


你是对的。因为Sprite Kit使用位掩码来表示32个不同的物理类别,所以你不能有更多(即使在Xcode 7中也是如此)。对于最大值(UInt32 * 2),4294967295,即二进制中的11111111111111111111111111111111,你可以让这个对象与所有其他对象碰撞。 - hippo_san
好的。那么绝对没有办法突破这个限制吗?也许有其他技术可以使用,能够提供与“char1.physicsBody.categoryBitMask = char1Category;”相同或类似的功能吗? - Krekin
2个回答

7

有许多方法可以在这个问题上发挥创意。例如,您可以使用节点的名称属性。将所有敌人归于一个categoryBitMask,并使用他们的名称来区分它们一旦接触到了他们。

另一种选择是使用SKNode字典属性。如果需要,这允许您存储比字符串更详细的数据。

创建SKNode字典:

myNode.userData = [NSMutableDictionary dictionary];
[myNode.userData setObject:@"goblin" forKey:@"enemyType"];

阅读字典:

NSString *myString = [myNode.userData objectForKey:@"enemyType"];

太棒了!我为什么没想到呢?谢谢。 - Krekin
好的!第一个例子,关于节点的名称属性,非常出色地发挥了作用!就像这样:"(firstBody.categoryBitMask == [_worldNode childNodeWithName:@"charRed"].physicsBody.categoryBitMask) && (etc.)"。然而,sangony,你能展示一下如何执行第二个方法吗?这涉及到SKNode字典属性。 - Krekin

1
您可以使用UInt32来定义超过32个对象。
一种方法是保留最后一位或几位。这会减少您用于项目的位数,但是您可以通过使用的位数乘以该数字来增加它们的数量。因此,如果我们只在31个以上的项目上使用32位掩码,我们可以拥有2 * 31个对象。如果我们为更多项保留第32位和第31位,则可以拥有4 * 30个对象,依此类推。
即:从SKScene中获取的普通32位。
(void)didBeginContact:(SKPhysicsContact *)contact
{
    uint32_t catagoryContactBitMask = (contact.bodyA.categoryBitMask | contact.bodyB.categoryBitMask); 

    if (catagoryContactBitMask == (carCategory | wallCategory))
    {    ....
    }

}

例如,如果我们需要更多的类别高于32... 因此,让我们将第32位保留为超过31个项目的“二级”位...这将给我们2 * 31或62个项目。
静态常量uint32_t 32bitMask = 0x1 << 32; //10000000000000000000000000000000
静态常量uint32_t wallCategory = 0x1 << 0; // 00000000000000000000000000000001
静态常量uint32_t porcheCategory = 0x1 << 1; // 00000000000000000000000000000010
静态常量uint32_t lamboCategory = 0x1 << 1 | 32bitMask; //10000000000000000000000000000010
碰撞检测应该是相同的
再次从SKScene开始
(void)didBeginContact:(SKPhysicsContact *)contact
{
    uint32_t catagoryContactBitMask = (contact.bodyA.categoryBitMask | contact.bodyB.categoryBitMask); 

    if ( catagoryContactBitMask == (wallCategory|porcheCategory))
    {    ....
    }
    else if ( catagoryContactBitMask == (wallCategory|lamboCategory))
    {    ....
    }

}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接