2009-06-01 16 views
10

personne ne sait si les corps entrent en collision que lorsque (body1.categoryBits & body2.maskBits) & & (body1.maskBits & body2.categoryBits)? ou sont-ils déjà en collision lorsque (body1.categoryBits & body2.maskBits) || (body1.maskBits & body2.categoryBits)?groupes de collision Box2D

Répondre

15

De l'Box2D manual:

6.2.3. Filtrage

Le filtrage de collision est un système pour qui empêche la collision entre les formes. Par exemple, disons que vous faites un personnage qui fait du vélo. Vous voulez que le vélo entre en collision avec le terrain et que le personnage entre en collision avec le terrain , mais vous ne voulez pas que le personnage entre en collision avec le vélo (car ils doivent se chevaucher). Box2D prend en charge un tel filtrage de collision en utilisant des catégories et des groupes. Box12D prend en charge 16 catégories de collision

Pour chaque forme, vous pouvez spécifier à quelle catégorie il appartient. Vous spécifiez également les autres catégories qui peuvent entrer en collision avec cette forme. Pour exemple, vous pouvez spécifier dans un jeu multijoueur que tous les joueurs entrent en collision ne pas les uns avec les autres et monstres ne sont pas en collision les uns avec les autres , mais les joueurs et les monstres devraient entrer en collision . Ceci est fait avec le masquage bits. Par exemple:

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

groupes de collision vous permettent de spécifier un indice de groupe intégré . Vous pouvez avoir toutes les formes avec le même indice de groupe toujours entrer en collision (index positif) ou ne jamais entrer en collision (index négatif). Groupe indices sont généralement utilisés pour les choses qui sont en quelque sorte liés, comme les pièces d'une bicyclette. Dans l'exemple suivant , shape1 et shape2 toujours entrent en collision, mais shape3 et shape4 ne sont jamais en collision .

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

Les collisions entre les formes des différents indices de groupe sont filtrés en fonction les bits de la catégorie et un masque. Dans les autres mots , le filtrage de groupe a une plus grande précision que le filtrage de catégorie .

3

regardant la source de Box2d, il montre que si les appareils appartiennent à différents groupes (ou les groupes sont 0), le catgory et les masques sont comparés comme suit:

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

Il semble donc Un appareil similaire ne peut entrer en collision que si la collision est autorisée par les masques des appareils. (IE: ET logique)

11

C'est ainsi que j'ai compris comment fonctionnent maskBits et categoryBits. Disons que vous avez 3 objets: objectA, objectB et objectC.

Définir pour chaque objet une catégorie:

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

Ensuite, définissez les maskBits, qui définissent les règles de collisions pour chaque categoryBits:

-> objectA entrer en collision avec tout le monde (0xFFFF) et (&) non (~) objectB (0x0004)
objectA.maskBits = 0xFFFF & ~ 0x0004;

-> objetB entrer en collision avec objectA (0x0002) ou (|) objectC (0x0008) mais personne d'autre
objectB.maskBits = 0x0002 | 0x0008; -> objetC entrer en collision avec objectA (0x0002) mais personne d'autre
objectC.maskBits = 0x0002;

Je ne sais pas si c'est correct, mais cela a fonctionné pour moi.

HTH

+0

Merci, cela a fonctionné pour moi. – noob

0

J'ai utilisé des murs et de nombreux joueurs (notre joueur et ennemis) . Mon joueur et mes ennemis entrent en collision avec les murs, mais n'entrent pas en collision les uns avec les autres. J'ai fait comme ça et ça a marché. Vous devez définir l'attribut groupIndex à une valeur négative pour que les objets ne se chevauchent pas. Définissez les appareils comme ceci.

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

et de l'appliquer sur votre corps.

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