Are you using collision filters in Matter Physics to better control what should or shouldn't collide with each other?
Matter collision filtering can be confusing even though Phaser makes it easier than using the matterjs library directly.
If you are having a hard time understanding groups, categories, and masks or got the collisions to work by trial and error but don't understand why it works then this article is for you!
We will show you how things work with clear examples so that you can apply it confidently!
First, let's talk about groups. The default value for
0. This means that the default behavior is for the collision system to use the category/mask rules.
The practical outcome is that all bodies collide with each other.
Now, let's say we create two
MatterSprites and set the
group to different values:
Each ship has a different
group value so they should not collide, right?
This may feel unexpected as the docs say:
If the two bodies have the same non-zero value of collisionFilter.group, they will always collide if the value is positive, and they will never collide if the value is negative.
Clearly, we have 2 non-zero positive values that are different:
1 != 2.
So why are they colliding?
This is where the second half of the rules come in. If the
group values are positive or zero and different from each other then it will use the category/mask rules.
The outcome is the same as having the default
group value of
We can have the
group values work by setting the
collisionFilter.mask property to 0.
Now, the two ships will no longer collide with each other. Phaser 3 uses
setCollidesWith() as a more understandable way to set the
You can also directly set the
collisionFilter property of the Matter body like this:
The key point to remember is that if you want to use groups and ignore the category/mask rules then you need to set the
mask property to
mask property is set to
-1 by default which means everything will collide with each other.
The category/mask system is more complicated but also more powerful. It uses a bitmask system and this is where most people get lost.
Phaser will shield you from having to deal with bitmasks as long as you use the
setCollidesWith() method. But if you are trying to read the documentation then very little will make sense without some understanding of bitmasks.
Bitmasks for Simplicity
You may have heard that all computer programs eventually get turned into a series of 1's and 0's. This is the native language of all computers called binary or machine language. We read and write in code but the computer only understands 1 (on) or 0 (off).
All the code we write can be represented in binary including numbers. Binary representaton of numbers looks like this:
0 = 0000 1 = 0001 2 = 0010 4 = 0100 8 = 1000
You'll notice that we are only showing numbers that are a power of 2 from zero to eight. Numbers like 3, 5, 6, or 7 can also be represented but they don't matter for how we'll use bitmasks.
You can have up to 32 collision categories in Matter because of this system where each
1 needs to be by itself in a row of
0's. This is also known as a 32-bit integer because of the 32 binary spots used to represent numbers. Each spot is technically called a bit. 😎
A bitmask is the combination of these power of 2 numbers. We can use this to check which flags are set depending on which bit is set to
Let's say you have these 3 collision categories:
Notice that they are the binary representations of 1, 2, and 4. We can make a mask of
category3 like this:
The pipe symbol (
|) is the OR bitwise operator meaning that it will combine the two values and set the resulting bit to 1 if there is a 1 at that bit position in either value.
mask we can check which of the 3 categories are included in a very efficient manner.
That's the basics of bitmasks that you'll need to know to understand what the Matter Physics docs are saying.
Using Categories and Masks
There are 2 key things to understand when using Matter's category/mask rule and they are:
- each Matter body should have a category
- each Matter body mask should include the categories it will collide with
Let's use our ship example again:
We have a
player and an
enemy and they should collide with each other. Notice that we set the
player category to
CATEGORY_PLAYER and the mask to
Then we do the inverse for the enemy where the category is
CATEGORY_ENEMY and the mask is
This satisfies the 2 rules where each body has a category and their mask has the category that they should collide with.
Next, let's say the player shoots lasers and enemies should collide with those:
You can pass an array of categories to
setCollidesWith() and Phaser will automatically create the appropriate bitmask.
You can also apply your newly learned bitmask knowledge by doing this instead:
You should now be able to use collision groups, categories, and masks confidently!
Remember that these seemingly complicated computer concepts were designed by other humans and being able to understand them is within your abilities. 🤗 Might just take some work.
Be sure to sign up for our newsletter so you don't miss any future Phaser 3 game development tips and techniques!
Drop your email into the box below.
Don't miss any Phaser 3 game development content
Subscribers get exclusive tips & techniques not found on the blog!
Join our newsletter. It's free. We don't spam. Spamming is for jerks.