Search code examples
swiftsprite-kitcontactsbitmaskuint32

How does the category bit mask work in SpriteKit?(0xFFFFFFFF)


I have trouble understanding how this bit mask work. I know that this is set to 0xFFFFFFFF by default and if you want two bodies to contact you set two different bitmask.

My problem is how can I set 2(or more) different Bitmask, how can I change the default value to get a different value? I know that there are 32 different categories. Could you give me some of them?


Solution

  • Categories

    You can have 32 different categories. Categories could be vessel, bullets, wall, enemies, etc). If you are interested in collisions and contacts then you need first to set a category for a given objet. For example, vessel category 0, bullets category 1, wall category 2, enemies category 3. As they are bitmask then you have (respectively) 1, 2, 4, 8. Now categories are more a matter of behavior than identity. Some objects may behave like two different categories: rocks (no category per-se) behave like walls (you bounce on it) and enemies (you can throw bullet at them). Then the categories for rocks would be 2 and 3, as bit mask this give 12. It is not easy to imagine that an object is in different categories, but if you think about behavior sets and not identity sets, that ease to think about it.

    Default value for masks are 0xFFFFFFFF meanings that every object is in every possible category and every object collides with every other. Fine tuning these values can seriously improve the physical engine.

    Collisions

    Collisions are used to define which objects collides in the physical world. Some objects may cross to each other while other bounce. Example: a magical bullet may travel walls, while ordinary ones are stopped at walls.

    magicBullet.physicsBody.categoryBitMask = 1
    ordinaryBullet.physicsBody.categoryBitMask = 1 // both bullets behave as bullets
    wall.physicsBody.categoryBitMask = 2
    
    ordinaryBullet.physicsBody.collisionBitMask = 2 // hits walls
    magicBullet.physicsBody.collisionBitMask = 0 // do not physically see walls
    

    Collisions are declared as bit masks because you have to declare which other category a given object is able to physically interact with or not.

    Contacts

    Contacts are exactly the same as collisions but to capture in your code the fact that two objects are in contact. So if you are interested in ordinary bullets hitting a wall (for magical it is not necessarily interesting):

    ordinaryBullet.physicsBody.contactTestBitMask = 2 // want to catch wall hit
    magicBullet.physicsBody.contactTestBitMask = 0 // don't bother
    

    A slightly more complex example

    Now if you add another kind of object say hard wall, that could give:

    magicBullet.physicsBody.categoryBitMask = 1
    ordinaryBullet.physicsBody.categoryBitMask = 1 // both bullets behave as bullets
    wall.physicsBody.categoryBitMask = 2 // some bullets may travel through
    hardWall.physicsBody.categoryBitMask = 4 // nothing can travel through thses
    
    ordinaryBullet.physicsBody.collisionBitMask = 6 // hits walls and hard walls
    magicBullet.physicsBody.collisionBitMask = 4 // do not physically see walls but only hard walls
    
    ordinaryBullet.physicsBody.contactTestBitMask = 6 // want to catch all wall hit
    magicBullet.physicsBody.contactTestBitMask = 4 // just want to catch hard wall hitting