Box2Dv2.2.0用户指南Box2Dv2.2.0用户指南1Box2Dv2.2.0用户手册版权©2007--2011EirnCatto翻译:潘学军第一章介绍---------------------------------------------2第二章HelloBox2D---------------------------------------8第三章common--------------------------------------------14第四章碰撞模块---------------------------------------16第五章动态模块---------------------------------------27第六章fixture-----------------------------------------28第七章Body---------------------------------------------32第八章关节---------------------------------------------39第九章触点(contact)---------------------------------48第十章世界级-------------------------------------------56第十一章零碎材料---------------------------------------62第十二章调试图纸(debugdrawing)---------------------64第十三章局限-------------------------------------------65第十四章参考-------------------------------------------66Box2Dv2.2.0用户指南Box2Dv2.2.0用户指南2第一章介绍1.1关于BOX2D是一个关于2D游戏的刚体仿真库。程序员可以用此,使游戏中的角色灵活移动,并且可以使游戏世界更具有交互性。从游戏角度来看,物理引擎就是一个程序性动画(proceduralanimation)的系统。Box2D用可移植c++编写的。定义在引擎中的大部分类型都有b2的前缀。这样的好处就是足以避免与你的游戏引擎命名冲突。1.2先决条件在本手册中我假定你已经熟悉了基本物理概念,例如质量,力,扭矩和冲量。请先考虑读一下ChrisHecker和DavidBaraff(google这些名字)的那些教程,你不需要了解得非常细致,但他们可以使你很好地了解一些基本概念,以便你使用Box2D。Box2D是在一次游戏开发商会议上作为一种物理教程被创建的。你可以从box2d.org网页上下载这些教程。因为Box2D是用C++编写的,所以,首先,您应该在C++编程方面有一定的基础。Box2D不应该是你的第一个c++程序设计项目。你应该从编译,链接,和调试做起。1.3关于这个指南这个指南涵盖了大部分的Box2DAPI。你应该通过观看更多的Box2D程序来学习更多的知识。Box2D的代码库已经被Doxygen格式化,所以,很容易的创建一个超链接API文档。此手册不能随着新版本的发行而更新。所以此版本内容也可能会过时。1.4反馈信息和报告故障如果您有问题或者需要反馈关于Box2D的问题,请在论坛上留言。这也提供了一个大家交流的平台。注意:Box2D不应该是你的第一个c++程序设计项目。在使用Box2D之前,请先学会C++编程,编译,链接,和调试。在网上有许多这方面的资源。Box2Dv2.2.0用户指南Box2Dv2.2.0用户指南3Box2D问题是利用谷歌代码项目进行跟踪的,这是用一个伟大的方式来追踪问题,并保障你的问题将不会迷失在深海的论坛中。你可以确保你的问题得到解答的前提是---你描述的问题足够详细。最好是提供一个试验范例给我们,那么不久之后,你就可以在这篇文档中看到试验范例了。1.5核心概念Box2D中有一些基本的对象。这里,我们先简短的介绍这些对象,在后面的章节中,我们将更详细介绍这些对象。形状(shape)一块严格依附于物体(body)的2D碰撞几何结构(collisiongeometry)。形状具有摩擦(friction)和恢复(restitution)的材料性质。刚体(rigidbody)一块十分坚硬的物质,它上面的任何两点之间的距离都是完全不变的。它们就像钻石那样坚硬。在后面的讨论中,我们用物体(body)来代替刚体。夹具(fixture)一个固定装置将一个形状捆绑到一个body上,并添加材料属性,例如密度,摩擦力和恢复。约束(constraint)约束就是一个物理连接,目的是消除body的自由度。在2D中,body中一共有三个自由度(两个转换坐标和一个旋转坐标)。如果我们拿出一个body,并把他用钉子钉到墙体上(像一个挂钟一样)这样我们就把body约束到了墙上。这时,body只能围绕钉子旋转,所以,此时,约束已经消除了两个自由度。触点约束(contactconstraint)一个特殊的约束,目的在于防止侵入刚体,模拟摩擦,恢复。你不能创造接触约束,他们是被Box2D自动形成的。请再这里提交故障并且描述你的需求:用户指南Box2Dv2.2.0用户指南4关节(joint)这是一个用来将两个或更多的body连接在一起的约束,Box2D支持多种类型的关节:旋转,棱柱,距离等。关节也可以支持限制和马达。关节限制(jointlimit)一个关节限制限制了一个关节的运动范围。例如,人物手肘只能确定范围的移动一样。。关节马达(jointmotor)一个关节马达能依照关节的自由度来驱动所连接的物体。例如,你可以使用一个马达来驱动一个肘的旋转。Page4World物理世界(physicsworld)是body,fixtures和约束相互作用的集合。Box2D支持创造多个世界,但通常情况下是没有必要的。Solver求解器物理世界的求解器,专美用来提前时间(advancetime),解决接触和关节约束。Box2D求解器是一个高平台的迭代求解器,它在N时间运行,这个时候N是约束的数字编号。连续碰撞(continuouscollision)求解器用离散的时间步提前时间。如果在没有介入的情况下,这会导致一个隧道效应。Box2D包含一些特殊的算法,用以解决隧道效应。第一,碰撞算法能同时篡改两个Body的运动,以找出第一次碰撞的时间。第二,有一个能将Body移动到其第一次碰撞时间继而解决碰撞的sub-steppingsolver。1.6模块ModulesBox2D由三个模块组成:Common共同,Collision碰撞,和Dynamics.共同模块(Commonmodule)包括分配,数学和设置的相关代码。碰撞模块(collisionmodule)定义了shape,broad-phase,和碰撞功能。力学模块提供了模拟世界,body,fixture,和关节。Box2Dv2.2.0用户指南Box2Dv2.2.0用户指南51.7单元Box2D使用浮点数,所以必须使用一些公差来保证它正常工作。这些公差已经被调谐得适合米-千克-秒(MKS)单位。尤其是,Box2D被调谐得能良好地处理0.1到10米之间的移动物体。这意味着从罐头盒到公共汽车大小的对象都能良好地工作。作为一个2D物理引擎,如果能使用像素作为单位是很诱人的。很不幸,那将导致不良模拟,也可能会造成古怪的行为。一个200像素长的物体在Box2D看来就有45层建筑那么大。想象一下使用一个被调谐好模拟玩偶和木桶的引擎去模拟高楼大厦的运动。那并不有趣。注意Box2D已经被调整为MKS单位,移动物体的尺寸大约应该保持在0.1到10米之间。你可能需要一些缩放系统来渲染你的场景和物体。Box2D中的例子是使用OpenGL的视口来变换的。你最好把box2d的body想象成一个移动的广告牌,在这个广告牌上,你可以将你的艺术品,图像等附属在其上。这个广告牌可能只移动一个米单位系统。但你可以通过一个简单比例因子将它转换成像素坐标。然后你就可以利用这些像素坐标放置你的怪物等等。Box2D使用弧度为角度。Body的旋转被存在弧度中,其生长无界限(maygrowunbounded)。当角度过大时,需要考虑body角度的规范。(useb2Body::SetAngle).Page61.8工厂和定义如上所述,内存管理在Box2DAPI的设计中担当了一个中心角色。所以当你创建一个b2Body或者一个b2Joint,时候,你需要调用b2World的工厂函数(factoryfunctions)。这些事创建函数:(creationfunctions:):b2Body*b2World::CreateBody(constb2BodyDef*def)b2Joint*b2World::CreateJoint(constb2JointDef*def)相应的摧毁函数(correspondingdestructionfunctions):voidb2World::DestroyBody(b2Body*body)voidb2World::DestroyJoint(b2Joint*joint)当你创建一个body或者joint的时候,你需要给他们提供定义。这些定义应该包含所有关于创建body和joint的信息。通过这种方法,我们能避免构造错误,使函数参数的数量较小,提供有意义的的默认参数,减少访问子的数量。因为形状必须有父物体,所以b2Body上有创建和摧毁形状的工厂:b2Fixture*b2Body::CreateFixture(constb2FixtureDef*def)voidb2Body::DestroyFixture(b2Fixture*fixture)有一个直接从形状、密度来创建fixture的捷径:Box2Dv2.2.0用户指南Box2Dv2.2.0用户指南6b2Fixture*b2Body::CreateFixture(constb2Shape*shape,float32density)工厂并不保留到定义的引用,所以你可以在栈上创建定义,临时的保存它们。1.9UserData用户数据b2Shape,b2Body和b2Joint类都允许你通过一个void指针来附加用户数据。这在你测试Box2D数据结构,以及你想把它们联系到自己的引擎中的时候是较方便的。典型的例子就是在角色上的刚体中附加到角色的指针,这就构成了一个循环引用。如果你有角色,你就能得到刚体。如果你有刚体,你就能得到角色。Page7GameActor*actor=GameCreateActor();b2BodyDefbodyDef;bodyDef.userData=actor;actor-body=box2Dworld-CreateBody(&bodyDef);这是需要用户数据事件的一些例子:•使用碰撞结果给角色施加伤害•当玩家进入一个包围盒时播放一段脚本事件•当Box2D通知你一个关节即将摧毁时访问一个游戏结构记住:用户数据是可选择的,并且能放入任何东西。然而,你需要保持一致性。例如,如果你想在一个物体中保存一个角色的指针,那你就应该在所有物体中都保存一个角色指针。不要在一个物体中保存角色指针,却在另一个物体中保存一个其它指针。这可能会导致程序崩溃。用户数据指针在默认情况下为空。第二章helloworld每个Box2D程序都将从一个世界对象(worldobject)的创建开始。这个程序创建了一个大的地面盒和一个小的动态盒.这些代码不包含任何图形,你能看到的只是在控制框的测试输出结果。2.1创建一个世界对象每个Box2D程序都是以创建一个b2World对象开始的。b2World是管理内存、对象和模拟的中心,你可以在栈,堆,或数据区配置物理世界。创建一个Box2Dworld是很容易