Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the maximum number of categoryBitMask's allowed in Sprite Kit?

I heard only 32 different categorybitmask's are allowed to be used per Sprite Kit game. Is there any way around this? I absolutely need more then that (roughly 3-4 times more since the game is an open world one). I set up my categorybitmask's as following:

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

I even changed uint32_t to uint64_t hoping that would double the amount of categorybitmask's I could use. Unfortunately, it doesn't. If anyone knows any techniques to by-pass this limit, I will be very grateful.

like image 825
Krekin Avatar asked Feb 09 '23 21:02

Krekin


2 Answers

There are a number of ways you can get creative regarding this issue. You can, for example, use the name property of a node. Have all your enemies under one categoryBitMask and use their names to differentiate them once contact is made.

Another alternative is to use the SKNode dictionary property. This allows you to store more detailed data, if required, than just a string.

Creating a SKNode dictionary:

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

Reading the dictionary:

NSString *myString = [myNode.userData objectForKey:@"enemyType"];
like image 108
sangony Avatar answered May 07 '23 15:05

sangony


You can have more than 32 objects defined with a UInt32.

One way to do this is is to reserve the last bit(s). It will diminish the number of bits you have for items, but you will multiply that by the number of bits you use. So if we use just the 32 bit for a mask on items above the 31 count, we can have 2*31 number of objects. If we reserve the 32nd and 31st bit for more items, we can have 4*30 number of objects and so on.

i.e normal 32 bit from SKScene

(void)didBeginContact:(SKPhysicsContact *)contact
{
    uint32_t catagoryContactBitMask = (contact.bodyA.categoryBitMask | contact.bodyB.categoryBitMask); 

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

}

for example if we needed more categories higher than 32... So lets reserve the 32nd bit as a 'second level' bit for items more than 31...this will give us 2*31 or 62 items.

static const uint32_t 32bitMask = 0x1 << 32; //10000000000000000000000000000000

static const uint32_t wallCategory = 0x1 << 0; // 00000000000000000000000000000001

static const uint32_t porcheCategory = 0x1 << 1; // 00000000000000000000000000000010

static const uint32_t lamboCategory = 0x1 << 1 | 32bitMask; //10000000000000000000000000000010

collision detection should be the same

again from SKScene

(void)didBeginContact:(SKPhysicsContact *)contact
{
    uint32_t catagoryContactBitMask = (contact.bodyA.categoryBitMask | contact.bodyB.categoryBitMask); 

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

}
like image 38
ScottS Avatar answered May 07 '23 17:05

ScottS