问题
does anyone know whether bodies only collide when (body1.categoryBits & body2.maskBits) && (body1.maskBits & body2.categoryBits) ? or do they already collide when (body1.categoryBits & body2.maskBits) || (body1.maskBits & body2.categoryBits) ?
回答1:
If anyone is still looking for more explanations, I made a detailed tutorial here :
http://aurelienribon.wordpress.com/2011/07/01/box2d-tutorial-collision-filtering/
回答2:
From the Box2D manual:
6.2.3. Filtering
Collision filtering is a system for preventing collision between shapes. For example, say you make a character that rides a bicycle. You want the bicycle to collide with the terrain and the character to collide with the terrain, but you don't want the character to collide with the bicycle (because they must overlap). Box2D supports such collision filtering using categories and groups.
Box2D supports 16 collision categories. For each shape you can specify which category it belongs to. You also specify what other categories this shape can collide with. For example, you could specify in a multiplayer game that all players don't collide with each other and monsters don't collide with each other, but players and monsters should collide. This is done with masking bits. For example:
playerShapeDef.filter.categoryBits = 0x0002; monsterShapeDef.filter.categoryBits = 0x0004; playerShape.filter.maskBits = 0x0004; monsterShapeDef.filter.maskBits = 0x0002;
Collision groups let you specify an integral group index. You can have all shapes with the same group index always collide (positive index) or never collide (negative index). Group indices are usually used for things that are somehow related, like the parts of a bicycle. In the following example, shape1 and shape2 always collide, but shape3 and shape4 never collide.
shape1Def.filter.groupIndex = 2; shape2Def.filter.groupIndex = 2; shape3Def.filter.groupIndex = -8; shape4Def.filter.groupIndex = -8;
Collisions between shapes of different group indices are filtered according the category and mask bits. In other words, group filtering has higher precendence than category filtering.
回答3:
This is the way I've understood how maskBits and categoryBits work. Let's say you have 3 objects : objectA, objectB and objectC.
Define for each object a category :
objectA.categoryBits = 0x0002;
objectB.categoryBits = 0x0004;
objectC.categoryBits = 0x0008;
Then, set the maskBits, which define the collisions rules for each categoryBits :
-> objectA collide with everyone (0xFFFF) and (&) not(~) objectB (0x0004)
objectA.maskBits = 0xFFFF & ~0x0004;
-> objectB collide with objectA (0x0002) or (|) objectC (0x0008) but no one else
objectB.maskBits = 0x0002 | 0x0008;
-> objectC collide with objectA (0x0002) but no one else
objectC.maskBits = 0x0002;
I don't know if this is correct, but it worked for me.
HTH
回答4:
Looking at the source of Box2d, it shows that if the fixtures belong to different groups (or the groups are 0) then the catgory and masks are compared as follows:
bool collide = (filterA.maskBits & filterB.categoryBits) != 0 &&
(filterA.categoryBits & filterB.maskBits) != 0;
So it looks like fixture only collide if the collision is allowed by both fixtures' masks. (IE: AND logic)
回答5:
I have used walls and many players (our Player and enemies). My player and enemies collides with walls but don't collide with each other. I have done like this and it worked. You have to set the groupIndex to negative value for the objects not to collide with each other. Define the fixtures like this.
/* The categories. */
public static final short CATEGORYBIT_WALL = 1;
public static final short CATEGORYBIT_PLAYERS = 2;
/* And what should collide with what. */
public static final short MASKBITS_WALL = CATEGORYBIT_WALL + CATEGORYBIT_PLAYERS;
public static final FixtureDef WALL_FIXTURE_DEF = PhysicsFactory.createFixtureDef(0, 0.5f, 0.5f, false, CATEGORYBIT_WALL, MASKBITS_WALL, (short)0);
public static final FixtureDef PLAYERS_FIXTURE_DEF = PhysicsFactory.createFixtureDef(1, 0.5f, 0.5f, false, CATEGORYBIT_PLAYERS, MASKBITS_WALL, (short)-1);
and apply to your bodies.
AnimatedSprite player, enemy;
Body playerBody, enemyBody;
player= new AnimatedSprite(CAMERA_WIDTH/2, CAMERA_HEIGHT/2, this.playerRegion, this.getVertexBufferObjectManager());
playerBody = PhysicsFactory.createBoxBody(this.mPhysicsWorld, player, BodyType.DynamicBody, PLAYERS_FIXTURE_DEF);
this.mPhysicsWorld.registerPhysicsConnector(new PhysicsConnector(player, playerBody, true, false));
enemy= new AnimatedSprite(CAMERA_WIDTH/4, CAMERA_HEIGHT/2, this.enemyRegion, this.getVertexBufferObjectManager());
enemyBody= PhysicsFactory.createCircleBody(this.mPhysicsWorld, enemy, BodyType.DynamicBody, PLAYERS_FIXTURE_DEF);
this.mPhysicsWorld.registerPhysicsConnector(new PhysicsConnector(enemy, enemyBody, true, false));
来源:https://stackoverflow.com/questions/936935/box2d-collision-groups