【发布时间】:2010-10-30 12:46:16
【问题描述】:
有谁知道身体是否只在 (body1.categoryBits & body2.maskBits) && (body1.maskBits & body2.categoryBits) 发生碰撞? 或者当 (body1.categoryBits & body2.maskBits) || 时它们是否已经发生碰撞? (body1.maskBits & body2.categoryBits) ?
【问题讨论】:
有谁知道身体是否只在 (body1.categoryBits & body2.maskBits) && (body1.maskBits & body2.categoryBits) 发生碰撞? 或者当 (body1.categoryBits & body2.maskBits) || 时它们是否已经发生碰撞? (body1.maskBits & body2.categoryBits) ?
【问题讨论】:
如果有人还在寻找更多的解释,我在这里做了一个详细的教程:
http://aurelienribon.wordpress.com/2011/07/01/box2d-tutorial-collision-filtering/
【讨论】:
来自 Box2D manual:
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 工作原理的方式。 假设您有 3 个对象:objectA、objectB 和 objectC。
为每个对象定义一个类别:
objectA.categoryBits = 0x0002;
objectB.categoryBits = 0x0004;
objectC.categoryBits = 0x0008;
然后,设置 maskBits,它定义了每个 categoryBits 的碰撞规则:
-> 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的源码,发现如果fixture属于不同的组(或者组为0),那么category和mask比较如下:
bool collide = (filterA.maskBits & filterB.categoryBits) != 0 &&
(filterA.categoryBits & filterB.maskBits) != 0;
所以看起来只有当两个灯具的掩码都允许碰撞时,灯具才会发生碰撞。 (即:与逻辑)
【讨论】:
我使用过墙壁和许多玩家(我们的玩家和敌人)。我的玩家和敌人与墙壁发生碰撞,但不会相互碰撞。我已经这样做了,它奏效了。您必须将 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));
【讨论】: