您好,欢迎访问三七文档
Box2D用户手册-2.2.0版本学生:陈泉宏学号:S201007154导师:张建标专业:计算机技术官方英文文档连接地址:文档目录:第一章:概述第二章:Box2D基本概念第三章:Common模块第四章:碰撞模块第五章:动态模块第六章:结构适配第七章:物体第八章:物体间的关节第九章:物体间的接触第十章:Box2D的物理世界第十一章:隐式销毁第十二章:调试绘图第十三章:Box2D的使用限制第十四章:资源引用第一章:概述1.1关于Box2DBox2D是一个用于2D游戏开发的刚体仿真库。程序员可以在他们的游戏里使用它,它可以使物体的运动形态更加逼真,让游戏看起来更具交互性。从游戏的视角来看,物理引擎就是一个程序性的动画(proceduralanimation)系统。应该由引擎而不是动画师去移动你的物体。Box2D是用可移植的C++语言来写的。在引擎中定义的大部分类型名都有b2前缀,这能有助于消除它和你其他游戏引擎之间的名字冲突。1.2学习Box2D的必备条件在此,假定你已经熟悉了基本的物理学概念,例如质量,力,扭矩和冲量。如果没有,请先通过Google或维基百科了解相关知识。Box2D是基于游戏开发中物理知识的相关特性开发的,你可以去box2D的官方网站下载相关内容。因为Box2D是使用C++写成的,所以你应该具备C++程序设计的经验,Box2D不应该成为你的第一个C++程序项目。你应该已经能熟练地编译,链接和调试了。1.3关于这本手册本手册涵盖了大部分的Box2D的API。然而,并非每一个环节都被覆盖。我们希望您去Box2D的测试平台了解更多。此外,box2d的代码是基于Doxygen格式的,很容易创建一个超链接API文档。本手册只更新新版本。该版本的源代码控制,很可能是过时的。1.4关于反馈和Bug提交关于问题的反馈和Bug的提交,可以去:。1.5核心概念Box2D中有一些基本的概念,先做一个简单的定义,在下面的文档里会有更详细的描述。1.形状(shape):Shape是指一个2D几何对象,如圆或多边形。2.刚体(rigidbody):rigidbody是指一块坚硬的物质,它上面的任何两点之间的距离都是完全不变的。它们就像钻石那样坚硬。在后面的文档中,我们用物体(body)来代替刚体。3.约束(constraint):一个约束(constraint)就是消除物体自由度的物理连接。在2D中一个物体有3个自由度。如果我们把一个物体钉在墙上(像摆锤那样),那我们就把它约束到了墙上。这样,此物体就只能绕着这个钉子旋转,所以这个约束消除了它2个自由度。3.接触约束(contactconstraint):一个防止刚体穿透,以及用于模拟摩擦(friction)和恢复(restitution)的特殊约束。你永远都不必创建一个接触约束,它们会自动被Box2D创建。4.关节(joint):它是一种用于把两个或多个物体固定到一起的约束。Box2D支持的关节类型有:旋转,棱柱,距离等等。关节可以支持限制(limits)和马达(motors)。5.关节限制(jointlimit):一个关节限制(jointlimit)限定了一个关节的运动范围。例如人类的胳膊肘只能做某一范围角度的运动。6.关节马达(jointmotor):一个关节马达能依照关节的自由度来驱动所连接的物体。例如,你可以使用一个马达来驱动一个肘的旋转。7.世界(world):一个物理世界就是物体,形状和约束相互作用的集合。Box2D支持创建多个世界,但这通常是不必要的。8.求解器(solver):物理世界有一个解算器,用于推进的时间以及解决接触和连接的限制。Box2D的求解器是一个高性能的迭代,其有效时间为N,其中N是求解上限。9.连续碰撞(continuouscollision):利用求解器的优势可以模拟连续碰撞。但若不加干预,这可能会导致无限循环碰撞。Box2D中包有自己特殊的算法来处理无限循环碰撞问题,如下图:1.6模块Box2D是由三个模块组成:Common、Collision、Dynamics。Common用于代码的分配,数学计算和相关设置。Collision用于定义物体的形状,阶段的推进,碰撞的功能及搜索。最后Dynamics用于世界,机构,装置和关节的模拟。如下图:1.7Box2D系统的单位Box2D使用浮点数,所以必须使用一些公差来保证它正常工作。这些公差已经被调谐得适合米-千克-秒(MKS)单位。尤其是,Box2D被调谐得能良好地处理0.1到10米之间的移动物体。这意味着从罐头盒到公共汽车大小的对象都能良好地工作。作为一个2D物理引擎,如果能使用像素作为单位是很诱人的。很不幸,那将导致不良模拟,也可能会造成古怪的行为。一个200像素长的物体在Box2D看来就有45层建筑那么大。想象一下使用一个被调谐好模拟玩偶和木桶的引擎去模拟高楼大厦的运动。那并不有趣。注意:Box2D已被调谐至MKS单位。移动物体的尺寸大约应该保持在0.1到10米之间。你可能需要一些缩放系统来渲染你的场景和物体。Box2D中的例子是使用OpenGL的视口来变换的。1.8使用工厂方法创建物体内存管理在Box2D的API设计中占有很重要的地位。当你创建一个b2Body的时候应该使用如下工厂方式创造,而非其他方法:b2Body*b2World::CreateBody(constb2BodyDef*def)b2Joint*b2World::CreateJoint(constb2JointDef*def)相应的销毁方法:voidb2World::DestroyBody(b2Body*body)voidb2World::DestroyJoint(b2Joint*joint)当需要创建自定义的联合物体时,需要用以下方式:2Fixture*b2Body::CreateFixture(constb2FixtureDef*def)voidb2Body::DestroyFixture(b2Fixture*fixture)当然也包括sharp和density的定义方式:b2Fixture*b2Body::CreateFixture(constb2Shape*shape,float32density)1.9用户数据的定义方式Box2D允许你用指针形式来定义b2Fixture、b2Body和b2Joint类。例如:GameActor*actor=GameCreateActor();b2BodyDefbodyDef;bodyDef.userData=actor;actor-body=box2Dworld-CreateBody(&bodyDef);用户数据指针的默认值是NULL。第二章:Box2D基本概念2.1创建一个世界每个Box2D程序都将从一个世界对象(worldobject)的创建开始。这是一个管理内存,对象和模拟的中心。要创建一个世界对象,我们首先需要定义一个重力矢量。是的,你可以使重力朝向侧面(或者你只好转动你的显示器)。b2Vec2gravity(0.0f,-10.0f);booldoSleep=true;并且,我们告诉世界(world)当物体停止移动时允许物体休眠。一个休眠中的物体不需要任何模拟。b2Worldworld(gravity,doSleep);现在我们已经有了个物理世界,让我们继续。2.2创建一个地面盒物体通常由以下步骤来创建:1.首先使用位置(position),阻尼(damping)等定义一个物体;2.使用世界对象创建物体;3.使用几何结构,摩擦,密度等定义形状;4.在物体上创建形状;5.根据需要调整物体的质量以便于和附加的形状相匹配;第一步,我们创建地面体。要创建它我们需要一个物体定义(bodydefinition),通过物体定义我们来指定地面体的初始位置。b2BodyDefgroundBodyDef;groundBodyDef.position.Set(0.0f,-10.0f);第二步,将物体定义传给世界对象来创建地面体。世界对象并不保存到物体定义的引用。地面体是作为静态物体(staticbody)创建的,静态物体之间并没有碰撞,它们是固定的。当一个物体具有零质量的时候Box2D就会确定它为静态物体,物体的默认质量是零,所以它们默认就是静态的。b2Body*groundBody=world.CreateBody(&groundBodyDef);第三步,我们创建一个地面的多边形定义。我们使用SetAsBox简捷地把地面多边形规定为一个盒子(矩形)形状,盒子的中点就位于父物体的原点上。b2PolygonShapegroundBox;groundBox.SetAsBox(50.0f,10.0f);其中,SetAsBox函数接收了半个宽度和半个高度,这样的话,地面盒就是100个单位宽(x轴)以及20个单位高(y轴)。Box2D已被调谐使用米,千克和秒来作单位,所以你可以用米来考虑长度。然而,改变单位系统是可能的,随后的文档中会有讨论。在第四步中,我们在地面体上创建地面多边形,以完成地面体。groundBody-CreateFixture(&groundBox,0.0f);重申一次,Box2D并不保存到形状或物体的引用。它把数据拷贝到b2Body的结构中。注意:每个形状都必须有一个父物体,即使形状是静态的。然而你可以把所有静态形状都依附于单个静态物体之上。这个静态物体之需求是为了保证Box2D内部的代码更具一致性,以减少潜在的bug数量。可能你已经注意到了,大部分Box2D类型都有一个b2前缀。这是为了降低它和你的代码之间名字冲突的机会。2.3创建一个动态物体现在我们已经有了一个地面体,我们可以使用同样的方法来创建一个动态物体。除了尺寸之外的主要区别是,我们必须为动态物体设置质量性质。首先我们用CreateBody创建物体。b2BodyDefbodyDef;bodyDef.type=b2_dynamicBody;bodyDef.position.Set(0.0f,4.0f);b2Body*body=world.CreateBody(&bodyDef);接下来我们创建并添加一个多边形形状到物体上。注意我们把密度设置为1,默认的密度是0。并且,形状的摩擦设置到了0.3。形状添加好以后,我们就使用SetMassFromShapes方法来命令物体通过形状去计算其自身的质量。这暗示了你可以给单个物体添加一个以上的形状。如果质量计算结果为0,那么物体会变成真正的静态。物体默认的质量就是零,这就是为什么我们无需为地面体调用SetMassFromShapes的原因。b2FixtureDeffixtureDef;fixtureDef.shape=&dynamicBox;fixtureDef.density=1.0f;fixtureDef.friction=0.3f;body-CreateFixture(&fixtureDef);这就是初始化过程。现在我们已经准备好开始模拟了。2.4Box2D的模拟世界我们已经初始化好了地面盒和一个动态盒。现在是让牛顿接手的时刻了。现在我们只有少数几个问题需要考虑。Box2D中有一些由数学代码构成的积分器(integrator),积分器利用离散的时间点模拟物理方程,它将与游戏动画循环同步运行,所以我们需要为Box2D选取一个时间步。通常来说游戏物理引擎需要至少60Hz的速度,也就是1/60的时间步。你可以使用更大的时间步,但是你必须更加小心地为你的世界调整定义。我们也不喜欢时间步变化得太大,所以不要把时间步关联到帧频(除非你真的必须这样做)。直截了当地,这个就是时间步:float32timeStep=1.0f/60.0f;除了积分器之外,Box2D中还有约束求解器(constraintsolver)。约束求解器用于解决模拟中的所有约束,一次一个。单个的
本文标题:Box2D中文
链接地址:https://www.777doc.com/doc-3767489 .html