2009-06-01 4 views
10

weiß jemand, ob nur Körper kollidieren, wenn (body1.categoryBits & body2.maskBits) & & (body1.maskBits & body2.categoryBits)? oder kollidieren sie schon wenn (body1.categoryBits & body2.maskBits) || (body1.maskBits & body2.categoryBits)?box2d Kollisionsgruppen

Antwort

15

Vom Box2D manual:

6.2.3. Filtern

Kollisionsfilterung ist ein System für verhindert Kollision zwischen Formen. Zum Beispiel sagen Sie, dass Sie einen Charakter machen, der Fahrrad fährt. Sie möchten, dass das Fahrrad mit dem Gelände kollidiert und das Zeichen mit dem Gelände kollidiert, aber Sie wollen nicht, dass das Zeichen mit dem Fahrrad kollidiert (weil sie sich überschneiden müssen). Box2D unterstützt solche Kollisionsfilter mit Kategorien und Gruppen.

Box2D unterstützt 16 Kollision Kategorien. Für jede Form können Sie angeben, zu welcher Kategorie es gehört. Sie geben auch an, welche anderen Kategorien mit dieser Form kollidieren können. Für Beispiel könnten Sie in einem Multiplayer-Spiel geben, die alle Spieler miteinander und Monster nicht nicht mit jedem andere, aber die Spieler und Monster sollten kollidieren kollidieren kollidieren. Dies geschieht mit Maskierung Bits. Zum Beispiel:

playerShapeDef.filter.categoryBits = 0x0002; 
monsterShapeDef.filter.categoryBits = 0x0004; 
playerShape.filter.maskBits = 0x0004; 
monsterShapeDef.filter.maskBits = 0x0002; 

Kollisionsgruppen können Sie einen integralen Gruppenindex angeben. Sie können alle Formen mit dem gleichen Gruppenindex immer kollidieren lassen (positiver Index) oder niemals kollidieren (negativer Index). Gruppe Indizes werden normalerweise für Dinge verwendet, die irgendwie verwandt sind, wie die Teile eines Fahrrades. Im folgenden Beispiel kollidieren shape1 und shape2 immer , aber shape3 und shape4 nie kollidieren.

shape1Def.filter.groupIndex = 2; 
shape2Def.filter.groupIndex = 2; 
shape3Def.filter.groupIndex = -8; 
shape4Def.filter.groupIndex = -8; 

Kollisionen zwischen verschiedenen Formen von Gruppenindizes gefiltert werden nach die Kategorie und Maskenbits. In anderen Wörtern hat die Gruppenfilterung eine höhere Priorität als die Kategoriefilterung.

3

Mit Blick auf die Quelle der Box2D, zeigt es, dass, wenn die Armaturen zu verschiedenen Gruppen gehören (oder die Gruppen 0), dann die Warengruppe und Masken verglichen werden, wie folgt:

bool collide = (filterA.maskBits & filterB.categoryBits) != 0 && 
        (filterA.categoryBits & filterB.maskBits) != 0; 

So sieht es aus Die gleiche Vorrichtung kollidiert nur dann, wenn die Kollision von beiden Masken erlaubt ist. (IE: UND-Logik)

11

So habe ich verstanden, wie maskBits und categoryBits funktionieren. Nehmen wir an, Sie haben 3 Objekte: objectA, objectB und objectC.

für jedes Objekt definiert eine Kategorie:

objectA.categoryBits = 0x0002;
objectB.categoryBits = 0x0004;
objectC.categoryBits = 0x0008;

Dann stellen Sie die maskBits, die die Kollisionen Regeln für jede categoryBits definieren:

-> Objecta kollidieren mit jeder (0xFFFF) und (&) nicht (~) ObjectB (0x0004)
objectA.maskBits = 0xFFFF & ~ 0x0004;

-> ObjectB mit Objecta kollidieren (0x0002) oder (|) ObjectC (0x0008), aber niemand sonst
objectB.maskBits = 0x0002 | 0x0008;

-> objectC kollidiert mit objectA (0x0002) aber sonst niemand
objectC.maskBits = 0x0002;

Ich weiß nicht, ob das richtig ist, aber es hat für mich funktioniert.

HTH

+0

Danke, es hat für mich funktioniert. – noob

0

ich verwendet habe, Wände und viele Spieler (unsere Spieler und Feinde) . Mein Spieler und Gegner kollidieren mit Wänden, kollidieren aber nicht miteinander. Ich habe es so gemacht und es hat funktioniert. Sie müssen den Gruppenindex auf einen negativen Wert setzen, damit die Objekte nicht miteinander kollidieren. Definieren Sie die Fixtures so.

/* 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); 

und gelten für Ihre Körper.

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));