(body1.categoryBits & body2.maskBits) && (body1.maskBits & body2.categoryBits) の場合にのみ体が衝突するかどうかは誰にもわかりませんか? または、(body1.categoryBits & body2.maskBits) || のときに既に衝突していますか? (body1.maskBits & body2.categoryBits) ?
5 に答える
誰かがまだ詳細な説明を探している場合は、ここで詳細なチュートリアルを作成しました:
http://aurelienribon.wordpress.com/2011/07/01/box2d-tutorial-collision-filtering/
Box2Dマニュアルから:
6.2.3. フィルタリング
衝突フィルタリングは、形状間の衝突を防止するためのシステムです。たとえば、自転車に乗るキャラクターを作成するとします。自転車を地形に衝突させ、キャラクタを地形に衝突させたいのですが、キャラクタを自転車に衝突させたくありません (オーバーラップする必要があるため)。Box2D は、カテゴリとグループを使用したこのような衝突フィルタリングをサポートしています。
Box2D は 16 の衝突カテゴリをサポートしています。形状ごとに、それが属するカテゴリを指定できます。この形状が衝突できる他のカテゴリも指定します。たとえば、マルチプレイヤー ゲームで、すべてのプレイヤーが互いに衝突せず、モンスターも互いに衝突しないように指定できますが、プレイヤーとモンスターは衝突する必要があります。これはマスキングビットで行われます。例えば:
playerShapeDef.filter.categoryBits = 0x0002; monsterShapeDef.filter.categoryBits = 0x0004; playerShape.filter.maskBits = 0x0004; monsterShapeDef.filter.maskBits = 0x0002;
衝突グループを使用すると、整数グループ インデックスを指定できます。同じグループ インデックスを持つすべてのシェイプを常に衝突させる (正のインデックス) または衝突させない (負のインデックス) ことができます。グループ インデックスは、通常、自転車の部品など、なんらかの関連性があるものに使用されます。次の例では、shape1 と shape2 は常に衝突しますが、shape3 と shape4 は決して衝突しません。
shape1Def.filter.groupIndex = 2; shape2Def.filter.groupIndex = 2; shape3Def.filter.groupIndex = -8; shape4Def.filter.groupIndex = -8;
異なるグループ インデックスのシェイプ間の衝突は、カテゴリとマスク ビットに従ってフィルタリングされます。つまり、グループ フィルタリングはカテゴリ フィルタリングより優先度が高くなります。
これは、maskBits と categoryBits がどのように機能するかを理解した方法です。objectA、objectB、objectC の 3 つのオブジェクトがあるとします。
オブジェクトごとにカテゴリを定義します。
objectA.categoryBits = 0x0002;
objectB.categoryBits = 0x0004;
objectC.categoryBits = 0x0008;
次に、各 categoryBits の衝突ルールを定義する maskBits を設定します。
-> objectA は全員と衝突し (0xFFFF)、(&) not(~) objectB (0x0004)
objectA.maskBits = 0xFFFF & ~0x0004;
-> objectB は objectA (0x0002) または (|) objectC (0x0008) と衝突しますが、他には衝突しません
objectB.maskBits = 0x0002 | 0x0008;
-> objectC は objectA (0x0002) と衝突しますが、他には衝突しません
objectC.maskBits = 0x0002;
これが正しいかどうかはわかりませんが、私にとってはうまくいきました。
HTH
Box2d のソースを見ると、フィクスチャが異なるグループに属している場合 (またはグループが 0 の場合)、カテゴリとマスクが次のように比較されることが示されています。
bool collide = (filterA.maskBits & filterB.categoryBits) != 0 &&
(filterA.categoryBits & filterB.maskBits) != 0;
したがって、両方のフィクスチャのマスクで衝突が許可されている場合にのみ、フィクスチャが衝突するように見えます。(IE:AND論理)
私は壁と多くのプレイヤー (プレイヤーと敵) を使用しました。プレイヤーと敵が壁に衝突するが、互いに衝突しない。私はこのようにしましたが、うまくいきました。オブジェクトが互いに衝突しないようにするには、groupIndex を負の値に設定する必要があります。このようにフィクスチャを定義します。
/* 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);
そしてあなたの体に適用します。
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));