📜 ⬆️ ⬇️

Using Filters from Box2D in Libgdx

The last article dealt with ContactListener work with ContactListener . Here are just examples that I used, were not quite correctly selected. Box2D has much more convenient collision filtering tools, namely filters. I will write about them this time.
Using Filters from Box2D in Libgdx

Filters are processed before collision processing. That is, if at the filter level we specify that no objects collide, then there will be no handling of collisions between these objects in the future. In the case of using the ContactListener , its methods for such objects will not work. Face optimization. And now let's take a closer look.

Categories and Masks

Categories and masks are the most powerful way to filter collisions, but also the most difficult (for beginners). The idea is to define a category for object types, and use masks to filter collisions between these types of objects. To begin, we define categories.

 // 0000000000000001 in binary final public static short CATEGORY_PLAYER = 0x0001; // 0000000000000010 in binary final public static short CATEGORY_BALOOM = 0x0002; // 0000000000000100 in binary final public static short CATEGORY_RUNNER = 0x0004; // 0000000000001000 in binary final public static short CATEGORY_SCENERY = 0x0008; 

Then we will set them to our objects.
')
 // f.categoryBits = MyWorld.CATEGORY_PLAYER; //   f.categoryBits = MyWorld.CATEGORY_SCENERY; // Baloom' f.categoryBits = MyWorld.CATEGORY_BALOOM; // Runner' f.categoryBits = MyWorld.CATEGORY_RUNNER; 


You should have noticed that the numbering is 0 × 001, 0 × 002, 0 × 004 and 0 × 008. Why? The fact is that categories and masks are bitfields (encoded in 16 bits). This means that the possible categories are degree 2 (in decimal notation: 1, 2, 4, 8, 16, 32, 64, 128 ..., or in hexadecimal: 0 × 1, 0 × 2, 0 × 4, 0 × 8, 0 × 10, 0 × 20, 0 × 40, 0 × 80 ...). 16 bits means that there are 16 possible categories from 0 × 0001 to 0 × 8000.

Now we define the mask.
 final public static short MASK_PLAYER = CATEGORY_RUNNER | CATEGORY_SCENERY; //  ~MASK_PLAYER final public static short MASK_BALOOM = CATEGORY_SCENERY ; final public static short MASK_RUNNER = CATEGORY_PLAYER | CATEGORY_SCENERY ; final public static short MASK_SCENERY = -1; 


Ordinary Boolean algebra with typical operations on numbers. One has only to focus on the mask and the categories for landscape objects. Why is -1? -1 means the object will contact all other objects. If it is necessary that the object does not contact anyone, then set the value to 0.

Then we will set masks to our objects.
 // f.maskBits = MyWorld.MASK_PLAYER; //   f.maskBits = MyWorld.MASK_SCENERY; // Baloom' f.maskBits = MyWorld.MASK_BALOOM; // Runner' f.maskBits = MyWorld.MASK_RUNNER; 


If someone does not understand, the masks and categories of pieces of the code are presented. I will quote the entire filter assignment just in case, as an example for a player:
 Filter f = new Filter(); f.categoryBits = MyWorld.CATEGORY_PLAYER; f.maskBits = MyWorld.MASK_PLAYER; playerSensorFixture.setFilterData(f); playerPhysicsFixture.setFilterData(f); 

As a result, the player will interact only with landscape objects and with the Runner. Ballom only with landscape. Runner with player and landscape.



Filtering at the group level

You can work with categories and masks, but sometimes there is no need to use them, count bit masks, etc. Groups were specifically designed to disable / enable collision handling for some related objects.

To begin, add another player.
 BodyDef def2 = new BodyDef(); def.type = BodyType.DynamicBody; Body boxP2 = world.createBody(def2); player2 = new Player(boxP2); player2.getBody().setTransform(5.0f, 1.0f, 0); player2.getBody().setFixedRotation(true); 


In the Player class, set the group.
 Filter f = new Filter(); f.groupIndex = -1; playerSensorFixture.setFilterData(f); playerPhysicsFixture.setFilterData(f); 

It is also necessary to specify groups for all other objects. Let for groupIndex platform be 3, and for blocks 2. In principle, the platform and blocks can not be assigned a group, then the default value will be set to 0. Now, if you start the game, the character will contact all objects except other characters.



You should have noticed that the index is negative. If the index is positive - the objects are always in contact, if negative - they never contact .

Sources

You can download the source from here .

Source: https://habr.com/ru/post/163885/


All Articles