当前位置: 首页 > 工具软件 > Box2D > 使用案例 >

box2D(转)

孙弘博
2023-12-01

转自:http://www.ityran.com/thread-650-1-1.html

第六章  fixture
6.1关于
记得,shape不了解body,并且shape可以在物理模拟中被单独使用。因此Box2D
提供了b2Fixture类将shape附属到body上,fixture持有以下:
         单个外形a singleshape
      ·broad-phaseproxies
      ·密度,摩擦,和恢复
      ·碰撞过滤旗帜
      ·返回父辈body的指针
      ·用户数据user data

     ·传感器旗帜sensorflag
具体将在以下章节中描述


6.2创建Fixture

fixture是通过初始化fixture定义并把定义传递给父辈body创建的。
     b2FixtureDeffixtureDef;
     fixtureDef.shape=&myShape;
     fixtureDef.density=1.0f;
     b2Fixture*myFixture =myBody->CreateFixture(&fixtureDef);
这创建了fixture,并把它附属到body上。你没必要存储fixture指针,因为
当父辈body被破坏时,fixture会自动被破坏。

你可以在父辈body上破坏fixture,你可以用这种方法来创建一个易碎的对象。
否则
youcanjustleavethefixture andletthebodydestructiontakecare
of destroyingthe attachedfixtures.
       myBody->DestroyFixture(myFixture);


密度

Fixture的密度可以用来计算父辈body的质量性能。密度可以为零或者为正数。
对所有的fixture,你应该使用相似的密度,这样可以提高堆的稳定性。

当你设置密度时,Body的质量是不可改变的。你需要访问ResetMassData才能
改变。
      fixture->SetDensity(5.0f);
      body->ResetMassData();


摩擦

摩擦用来保证对象像现实生活中一样移动。Box2D提供了静态和动态摩擦,但都
需要使用相同的参数。 在Box2D模拟中,摩擦需要非常准确,摩擦强度与正常
力量成正比(这就是所谓的库仑摩擦)。

摩擦参数通常是设置在0和1之间,但也可以是任何非负价值。将值设为0,摩擦关
掉。值为1,摩擦增强。当计算两个shape之间的摩擦力的时候,Box2D必须结
合两个父辈夹具的摩擦参数。
This isdonewith thegeometricmean:
     float32friction;
     friction=sqrtf(shape1->friction*shape2->friction);
如果一个夹具含有零摩擦,那么接触也会有零摩擦。


恢复Restitution

恢复用来使对象弹回。恢复值通常设置在0和1之间。考虑将一个球坠到桌子上,
9值意味着这个球不能返回。这就是所谓的一个非弹性碰撞。1值意味着这个球会
准确快速的反弹。这就是所谓的“完全弹性碰撞”。恢复则是组合使用下列公式:
      float32restitution;
     restitution=b2Max(shape1->restitution,shape2->restitution);

夹具通过携带碰撞过滤器的信息来帮助你阻止游戏对象之间的碰撞。
当一个形状发展多种接触时候,恢复会被近似模拟.这是因为Box2D使用一个迭
代求解器进行求解。当碰撞速度小的时候,Box2D也采用弹性碰撞。这是为了防
止抖动。


过滤

碰撞过滤可以帮助你防止fixture之间的碰撞。例如,你创建一个骑着自行车的
角色,你像让这个自行车和角色与地形碰撞,但是你不想让自行车与角色碰撞(因
为他们必须重叠), Box2D通过类别和分组支持这样的过滤碰撞。
Box2D支持16种碰撞类别,对于每一个夹具,你都能制定其属于哪一个类别。你
也可以制定这个夹具可以与哪种类型碰撞。例如,

你可以在一个多人游戏中指定,所有玩家之间不能互相碰撞,怪物与怪物之间不
能碰撞,但是玩家与怪物之间可以碰撞。Thisis donewith maskingbits.例
如:
    playerFixtureDef.filter.categoryBits=0x0002;
    monsterFixtureDef.filter.categoryBits=0x0004;
    playerFixtureDef.filter.maskBits=0x0004;
    monsterFixtureDef.filter.maskBits=0x0002;
    这是碰撞规则:

         uint16catA =fixtureA.filter.categoryBits;
         uint16maskA =fixtureA.filter.maskBits;
         uint16catB =fixtureB.filter.categoryBits;
         uint16maskB =fixtureB.filter.maskBits;

          if((catA &maskB)!=0&&(catB&maskA) !=0)
         {
            //fixtures cancollide
          }
    碰撞组让你指定一个整体分类指标。你可以让所有包含相同群指标的夹具永
远碰撞或者从不碰撞(negative index).集团指标通常用于一些相关的东西,像
自行车的一部分,在下面的例子中,夹具1和夹具2一直互相碰撞,但是夹具3和

夹具4却始终不碰撞。
         fixture1Def.filter.groupIndex=2;
         fixture2Def.filter.groupIndex=2;
         fixture3Def.filter.groupIndex=-8;
         fixture4Def.filter.groupIndex=-8;

     不同的群指标(groupindex)夹具之间的碰撞,会根据类别和屏蔽位(mask
bits)而被过滤。换句话说,集团过滤优先级高于类别过滤。
     注意在Box2D中的额外碰撞过滤,清单如下:
          静态body上的夹具只能与动态body上的夹具碰撞
          运动的body上的夹具只能与动态body上的夹具碰撞
          相同body上的夹具永远不能互相碰撞
          Youcanoptionallyenable/disablecollisionbetweenfixtureson
bodiesconnectedby ajoint.

有时候当一个fixture被创建的时候,你可能需要修改它的碰撞过滤。你可以用
b2Fixture::GetFilterData和b2Fixture::SetFilterData获取和设置一个已经
存在的fixture的b2Filter结构。要注意过滤数据不会增加或删除接触,直到
下一个时间步。


6.3 传感器

有些时候,游戏逻辑需要知道,什么时候两个fixture相交但不会碰撞。这将通
过传感器实现。传感器可以检测碰撞但不会产生碰撞反应。

你可以将任一shape标记为传感器,传感器可以是静态或动态的。记得,每个物
体上可以有多个shape,并且传感器和实体shape是可以混合的。传感器可以
是静态的或者动态的。记住每个body都可以有多个fixture并且也可以有任何
的混合传感器,和固体fixture。

传感器器不会产生触点,有两种方式获得感应器的状态;
     1. b2Contact::IsTouching
     2. b2ContactListener::BeginContactandEndContact   

另外,有下边一些概念要记住:

1,钢体

2,形状

3,约束

4,接触约束

5,关节

6,关节限制

7,关节马达

8,世界

一、创建一个世界的步骤:

1.先创建世界的AABB盒子:

     b2AABB worldAABB;

     worldAABB.lowerBound.Set(-100.0f,-100.0f);

     worldAABB.upperBound.Set(100.0f,100.0f);

2.再设置世界的重力失量

   b2Vec2 gravity(0.0f,-10.0f);

3.再设置是否使能世界体眠功能

   bool doSleep = true;

4.创建世界

  b2World World(worldAABB,gravity,doSleep);

二、创建一个物体的步骤:

1.创建物体定义

   b2BodyDef groundBodyDef;

2.设置定义物体的初始坐标

  groundBodyDef.position.Set(0.0f,10.0f);

3.使用世界创建这个物体

b2Body *groundbody = world.CreatBody(&groundBodyDef);

4.创建物体定义形状

b2PolygonDef groundShapeDef;
groundShapeDef.SetAsBox(50.0f, 10.0f);

5.将形状绑定到物体

groundBody->CreateShape(&groundShapeDef);

三、创建活动物体

1.先使用世界创建一个物体

b2BodyDef bodyDef;
bodyDef.position.Set(0.0f, 4.0f);
b2Body* body = world.CreateBody(&bodyDef);

2.设置形状,并设定物体密度和摩擦系数

b2PolygonDef shapeDef;
shapeDef.SetAsBox(1.0f, 1.0f);
shapeDef.density = 1.0f;  //密码,如果密度为0说明物体是固定物体
shapeDef.friction = 0.3f;  //摩擦系数
body->CreateShape(&shapeDef);
body->SetMassFromShapes(); //通过物体形状和密度设置物体质量

四、模拟

float32 timeStep = 1.0f / 60.0f;

int32 iterations = 10;

for (int32 i = 0; i < 60; ++i)
{
    world.Step(timeStep, iterations);
    b2Vec2 position = body->GetPosition();
    float32 angle = body->GetAngle();
    printf("%4.2f %4.2f %4.2f\n", position.x, position.y, angle);
}

说明一下,以上的代码是box2D的2.0版的,2.2.0版好像形状这一块改了一些东西,我这里找到的是2.0版的说明文档

 类似资料: