由于之前查资料时没有留意box2d中文教程中物理引擎使用的版本号,后来写代码发现,很多地方有差别,回头上官下了文档后,发现,最新版本已经更新到

2.2.1,而之前的上网找到的box2d中文教程是2.0。很抱歉没有留意到版本信息,现在我参考的资料是官方最新的文档内容。

想要了解更详细内容,读者可以到网上查阅。这里给出一个下载地址:http://box2d.org/

同时,我这里给出一个中文版的翻译,大家可以参考中文版来阅读英文版文档,http://blog.csdn.net/complex_ok/article/category/871440

一、重要概念

(1)形状(shape)

一个2D的几何物体,例如像圆或者多边形。

(2)刚体(rigid body)

就是一块十分坚硬的物质,它上面的任何两点之间的距离是完全不变。通常用物体(body)来代替刚体。

(3)夹具(fixture)

夹具是将形状捆绑到物体上,同时增加一些物理属性,如密度、摩擦和恢复。

(4)约束(constraint)

一个约束就是消除物体自由度的物理连接。自由度在物理上的定义是:完全确定一个物体在空间位置所需要的独立坐标数目。

在2D世界中,一个物体的自由度就是3,而不是2。要注意的是物体不是我们在数学中的一个点的坐标(x, y),如果是一个点(没有体积、大小)

,那它的自由如当然是2,但这里的物体是有体积、大小的。举例来说,想要确定一把尺子在2D世界中的位置,如果只知道吃上某一点的坐标(x,y),

那还不足以确定尺子的确切位置,因为尺子还可以绕着这个点旋转。故要确定尺子的位置,还需要一个自由度—–rotation(角度),就是说2D世界中,

三个自由度分别是x、y和rotation;

(5)接触约束(contact constraint)

一个防止刚体穿透,以及用于模拟摩擦和恢复的特殊约束。通俗地将就是物体间的摩擦和物体收到挤压后可以恢复原状。

(6)关节(joint)

将多个物体固定到一起的约束。就像人的胳膊。

(7)关节限制(joint limit)

一个关节限制限定了一个关节的运动范围。例如人的胳膊只能做一定角度的旋转。

(8)关节马达(joint motor)

一个关节马达能依照关节的自由度来驱动所连接的物体。例如人可以通过肌肉来趋势胳膊转动。

(9)世界(world)

一个物理世界就是物体,形状和约束相互作用的集合。

(10)解决者(solver)

物理世界的解决者是用来提前时间还有恢复接触和关节约束。

(11)连续的碰撞(continual collision)

解决者通过使用离散的时间点来检测物体。

二、Hello box2d

step1:创建一个世界

box2d程序都是从世界对象的创建开始的。每个物理世界都管理着内存、物体和模拟。

首先是定义重力矢量:

b2Vec2 gravity(0.0f, -10.0f);
bool doSleep = true;

这里的gravity包括了大小和方向,方向是沿y轴负方向,大小事该矢量的绝对值即sqrt(0.0的平方 + -10.0绝对值的平方);

接着就是创建世界对象:

b2World world(gravity,doSleep);

step2:创建一个地表

1.  用位置(position), 阻尼(damping)等来定义body

2.  通过world对象来创建body

3.   用形状(shape), 摩擦(friction), 密度(density)等来定义fixture

4.   在body上来创建fixture

既然创建了一个物理世界,这个世界当然就得有个平台来支撑其他物体,就像地球有陆地来支撑森林、建筑等等物体。在box2d中就叫

作地面体,地面体是静态物体,默认的质量为0,它是固定不动的。

(1)创建ground body。

我们需要一个body定义。在定义中,我们指定ground body的初始位置。

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

(2)将body定义传給world对象, 创建ground body。

world对象并不保留body定义的引用。ground body是作为静态物体(static body)创建的。静态物体和其它静态物体之间并没有碰撞, 它们是固定的。当body的质量为零时, Box2D就认为它是静态的。物体质量的默认值就为零, 所以它们默认就是静态的。

b2Body* ground = world.CreateBody(&groundBodyDef);

(3)创建地面多边形。

我们用简便函数SetAsBox使得地面多边形构成一个盒子形状,盒子的中心点就是父body的原点。

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

SetAsBox函数接收半个宽度和半个高度作为参数。因此在这种情况下,地面盒就是100个单位宽(x轴),20个单位高(y轴)。Box2D已被调谐到使用米,千克和秒做单位。你可以认为长度单位就是米。当物体的大小跟真实世界一样时,Box2D通常工作良好。例如,一个桶约1米高。由于浮点算法的局限性,使用Box2D模拟冰川或沙尘的运动并不是一个好主意。

(4)我们创建shape fixture, 以完成ground body。

我们创建shape fixture, 以完成ground body。这步中,我们有个简便方法。我们并不需要修改fixture默认的材质属性, 可以直接将形状传给body而不需要创建fixture的定义。随后的教程中, 我们将会看到如何使用fixture定义来定制材质属性。

groundBody->CreateFixture(&groundBox, 0.0f);

step3:创建一个动态物体

 

现在我们已经有了一个地面body,我们可以使用同样的方法来创建一个动态body。除尺寸之外的主要区别是, 我们必须为动态body设置质量属性。

首先我们用CreateBody创建body。默认情况下,body是静态的, 所以在构造时候应该设置b2BodyType使得body成为动态

b2BodyDef bodyDef;

bodyDef.type = b2_dynamicBody;

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

注意:如果你想body受力的影响而运动, 你必须将body的类型设为b2_dynamicBody。

然后,我们创建一个多边形shapde, 并将它附加到fixture定义上。我们先创建一个box shape:

b2PolygonShape dynamicBox;

dynamicBox.SetAsBox(1.0f, 1.0f);

接下来我们使用box创建一个fixture定义。注意, 我们把密度值设置为1,而密度值默认是0。并且,fixture的摩擦系数设置为0.3。

b2FixtureDef fixtureDef;

fixtureDef.shape = &dynamicBox;

fixtureDef.density = 1.0f;//设置密度
shapeDef.friction = 0.3f//设置摩擦系数

 使用fixture定义, 我们现在就可以创建fixture。这会自动更新body的质量。要是你喜欢, 你可以为body添加许多不同的fixture。每个fixture都会增加物体的总质量。

body->CreateFixture(&fixtureDef);

 

 

 

 

打赏

发表评论

电子邮件地址不会被公开。