Box2D v2.1.0用户手册翻译 - 第06章 夹具(Fixtures)

来源:互联网 发布:西安聚云网络诈骗 编辑:程序博客网 时间:2024/04/28 04:03

内容很多摘自
Aman JIANG(江超宇)翻译的Box2D v2.0.1 用户手册

第06章 夹具(Fixtures)

6.1 关于

回想一下,形状并不知道物体的存在,可以独立使用。因此Box2D需要提供b2Fixture类,用于将形状附加到物体上。 fixture具有下列属性:

•         关联的形状

•         密度(density),摩擦(friction),恢复(restitution)

•         碰撞筛选标记(collision filtering flags)

•         指向父物体的指针

•         用户数据

•         传感器标记(sensor flag)

这些都会在接下来的小节中描述。

6.2 创建夹具(Fixture Creation)

要创建fixture,先要创始化一个fixture定义,并将定义传到父物体中。

b2FixtureDef fixtureDef;

fixtureDef.shape = &myShape;

fixtureDef.density = 1.0f;

b2Fixture* myFixture = myBody->CreateFixture(&fixtureDef);

这会创建fixture,并将它附加到物体之上。你不需要保存fixture的指针,因为当它的父物体摧毁时,fixture也会自动被摧毁。 你可以在单个物体上创建多个fixture。.

你也可以摧毁父物体上的fixture,来模拟一个可分裂开的物体。你也可以不理会fixture,让物体的释放函数来摧毁附加其上的fixture。

myBody->DestroyFixture(myFixture);

密度(Density)

fixture的密度用来计算父物体的质量属性。密度值可以为零或者是整数。你所有的fixture都应该使用相似的密度,这样做可以改善物体的稳定性。

当你添加一个fixture时,物体的质量会自动调整。

摩擦(Friction)

摩擦可以使对象逼真地沿其它对象滑动。Box2D支持静摩擦和动摩擦,两者都使用相同的参数。摩擦在Box2D中会被精确地模拟,摩擦力的强度与正交力(称之为库仑摩擦)成正比。摩擦参数经常会设置在0到1之间, 也能够是其它的非负数,0意味着没有摩擦, 1会产生强摩擦。当计算两个形状之间的摩擦时,Box2D必须联合两个形状的摩擦参数。这是通过以下公式完成的:

float32 friction;

friction = sqrtf(shape1->friction* shape2->friction);

所以当其中一个fixture的摩擦参数为0时,接触的摩擦就为0。

恢复(Restitution)

恢复可以使对象弹起。恢复的值通常设置在0到1之间。想象一个小球掉落到桌子上,值为0表示着小球不会弹起, 这称为非弹性碰撞。值为1表示小球的速度跟原来一样,只是方向相反, 这称为完全弹性碰撞。恢复是通过下面的公式合成的:

float32 restitution;

restitution = b2Max(shape1->restitution,shape2->restitution);

ixture会携带碰撞筛选信息,让你防止某些游戏对象相互碰撞。

当一个形状多次碰撞时,恢复会被近似地模拟。Box2D使用了迭代求解器,当冲撞速度很小时,Box2D也会使用非弹性碰撞,这是为了防止抖动。

筛选(Filtering)

碰撞筛选是一个防止某些形状发生碰撞的系统。比如,你创造了一个骑自行车的角色。你希望自行车与地形之间有碰撞,角色与地形有碰撞,但你不希望角色和自行车之间发生碰撞 (因为它们必须重叠)。Box2D通过种群和分组支持了这样的碰撞筛选。

Box2D支持16个种群。任意fixture你都可以指定它属于哪个种群。你还可以指定这个fixture可以和其它哪些种群发生碰撞。例如,你可以在一个多人游戏中指定玩家之间不会碰撞,怪物之间也不会碰撞,但是玩家和怪物会发生碰撞。这是通过掩码来完成的,例如:

playerFixtureDef.filter.categoryBits= 0x0002;

monsterFixtureDef.filter.categoryBits= 0x0004;

playerFixtureDef.filter.maskBits =0x0004;

monsterFixtureDef.filter.maskBits =0x0002;

碰撞分组让你指定一个整数的组索引。你可以让同一个组的所有fixture总是相互碰撞(正索引)或永远不碰撞(负索引)。组索引通常用于一些以某种方式关联的事物,就像自行车的那些部件。在下面的例子中,fixture1 和 fixture2 总是碰撞,而 fixture3 和 fixture4 永远不会碰撞。

fixture1Def.filter.groupIndex = 2;

fixture2Def.filter.groupIndex = 2;

fixture3Def.filter.groupIndex = -8;

fixture4Def.filter.groupIndex = -8;

如果组索引不同,碰撞筛选就会按照种群和掩码来进行。换句话说, 分组筛选与种群筛选相比,具有更高的优选级。

注意在 Box2D 中还有其它的碰撞筛选,这里是一个列表:

•         static物体上的fixture永远不会与另一个static体上的fixture发生碰撞

•         同一个物体上的fixture永远不会相互碰撞

•         如果两个物体用关节连接起来,物体上面的fixture可以选择启用或禁止它们之间相互碰撞

有时你可能希望在形状创建之后去改变其碰撞筛选。 你可以使用b2Shape::GetFilterData 以及 b2Shape::SetFilterData来访问及设置已存在fixture的b2FilterData结构。注意就算修改了筛选数据,下一个时间步为止,现在的接触并不会增加或删除(见world类)。

6.3 传感器(Sensors)

有时候游戏逻辑需要判断两个fixture是否相交,但却不应该有碰撞反应。这可以通过传感器(sensor)来完成。传感器也是个fixture,但只会侦测碰撞而不产生其它反应。

你可以将任一fixture标记为传感器。传感器可以是static或dynamic的。记住,每个物体上可以有多个fixture, 传感器和实体fixture是可以混合存在的。

传感器不会生成接触点。这里有两种方法得到传感器的状态:

1.       b2Contact::IsTouching

2.       b2ContactListener::BeginContact 和 EndContact


原创粉丝点击