Search code examples
swift3sprite-kitskphysicsbody

I don't understand SpriteKit physics bodies's categorybitmasks unit


I don't understand UInt32 in spritekit categorybitmask. They are very confusing to me because they are typed like: "0b01 << 1" or "0x01" or something like that. I understand their usage in spritekit, but I don't understand the unit.


Solution

  • You have to understand a little about binary which can be tricky when you first encounter it. The code that is confusing you is shorthand for working with binary.

    For example, in 0b01 << 1 the 0b prefix means the following number is given in binary. This is helpful because if you just saw, for example, 1001, you might think it is the number "one thousand and one". But if you write 0b1001 you know that here, 1001 is a binary number. (Read more)

    Similarly, 0x is a prefix used to express hexadecimal numbers (because x kinda sounds like "hex" I guess). I personally prefer to use the 0b prefix when dealing with bitmasks in SpriteKit, but that's just me.

    Now on to bit shifting. << is the bitwise left shift operator in Swift. It moves all of the bits in a number to the left by a certain number of places. For example, the decimal number 3 is written as 0011 in binary.

    3 = 0011            // the number 3 is 0011 in binary
    3 << 1 = 0110 = 6   // take 0011 and shift all bits one place to the left
    3 << 2 = 1100 = 12  // take 0011 and shift all bits two places to the left
    

    The example you gave was 0b01 << 1. If you just enter 0b01, that is the binary representation of the decimal number 1. By entering 0b01 << 1 you are telling the program to take the binary number 01 (more explicitly written as 0b01) and shift its bits one place to the left, which results in the binary number 10 (more explicitly written as 0b10) , which is the number 2 in decimal.

    You can actually write 0b01 as 0b1 for short and it means the same thing since you are just omitting the leading zero.

    Try entering the following in an Xcode Playground and look at the results you get:

    0b1        // decimal 1
    0b1 << 1   // decimal 2
    0b1 << 2   // decimal 4
    0b1 << 3   // decimal 8
    0b1 << 4   // decimal 16
    

    You can play around with this, bit shifting by greater amounts, and you will see that the numbers continue to double. It turns out that this is a handy way for SpriteKit to implement bitmasks for its physics engine.

    UPDATE:

    You can define up to 32 different categories to use for physics bitmasks. Here they all are with their corresponding decimal values:

    0b1       // 1
    0b1 << 1  // 2
    0b1 << 2  // 4
    0b1 << 3  // 8
    0b1 << 4  // 16
    0b1 << 5  // 32
    0b1 << 6  // 64
    0b1 << 7  // 128
    0b1 << 8  // 256
    0b1 << 9  // 512
    0b1 << 10 // 1,024
    0b1 << 11 // 2,048
    0b1 << 12 // 4,096
    0b1 << 13 // 8,192
    0b1 << 14 // 16,384
    0b1 << 15 // 32,768
    0b1 << 16 // 65,536
    0b1 << 17 // 131,072
    0b1 << 18 // 262,144
    0b1 << 19 // 524,288
    0b1 << 20 // 1,048,576
    0b1 << 21 // 2,097,152
    0b1 << 22 // 4,194,304
    0b1 << 23 // 8,388,608
    0b1 << 24 // 16,777,216
    0b1 << 25 // 33,554,432
    0b1 << 26 // 67,108,864
    0b1 << 27 // 134,217,728
    0b1 << 28 // 268,435,456
    0b1 << 29 // 536,870,912
    0b1 << 30 // 1,073,741,824
    0b1 << 31 // 2,147,483,648