第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 |
Box2D v2.1.0用户手册翻译 - 第06章 夹具(Fixtures)
最新推荐文章于 2022-01-24 11:47:06 发布