本文是对Box2D v2.1.2 manual中文翻译(现在网上流行的一个中文翻译是针对以前版本的,跟最新的2.1.2版有些不对应)的第二章。持续更新中。。。。。。

2. Hello Box2D

在Box2D的分发包里包含一个HelloWorld项目,它创建一个巨大的地面盒和一个小小的动态盒。代码中不包含任何图形。你总是在控制台看到盒子随时间而改变位置。

这是一个介绍怎样运行Box2D的很好例子。

2.1      创建world

每个Box2D程序都将从一个b2World对象的创建开始,这是一个管理内存、对象和模拟的物理中心。你可以从栈、堆或数据区中分配物理world。这是由你决定的。

创建Box2D world很简单。首先,定义重力因子。然后我们告诉world允许body在苏醒之前沉睡。沉睡中的body不需要任何模拟。

b2Vec2 gravity(0.0f, -10.0f);

bool doSleep = true;

现在我们创建world对象。注意,我们通常在栈上创建world。

b2World world(gravity, doSleep);

那么现在我们有了自己的物理world,让我们再加些东西进去吧。

2.2      创建地面盒

物体通常由以下步骤来创建:

1、 使用位置(position),阻尼(damping)等定义body。

2、 使用world对象创建body。

3、 使用shape(形状)、friction(摩擦)、density(密度)等定义fixture。

4、 在body上创建fixture。

第一步,我们创建地面体。要创建它我们需要一个物体定义(body definition),通过物体定义我们来指定地面体的初始位置。

b2BodyDef groundBodyDef;

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

第二步,将物体定义传给world对象来创建地面体。world对象并不保存物体定义的引用。地面体是作为静态物体(static body)创建的,静态物体之间并没有碰撞,它们是固定的。当一个物体具有零质量的时候Box2D就会确定它为静态物体,物体的默认质量是零,所以它们默认就是静态的。

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

第三步,我们创建一个地面多边形。使用SetAsBox简捷地把地面多边形规定为一个盒子形状,盒子的中点就位于父body的原点上。

b2PolygonShape groundBox;

groundBox.SetAsBox(50.0f, 10.0f);

其中,SetAsBox函数接收半个宽度和半个高度,这样的话,地面盒就是100个单位宽(x轴)以及20个单位高(y轴)。Box2D已被调整为使用米,千克和秒来做单位。所以你可以考虑用米作为长度单位。当物体具有真实世界中物体的大小时,Box2D通常工作良好。例如,一个桶约1米高。由于浮点算法的局限性,使用Box2D驱动冰河或沙尘的运动并不是一个好主意。

在第4步中通过创建shape fixture,我们结束地面盒的创建。在这步中有一个捷径,我们不需要修改默认fixture的材质属性,所以可以直接把shape传递给body而不用创建fixture定义。在后面的介绍中,我们将会看到如何使用fixture定制材质属性。

groundBody->CreateFixture(&groundBox);

Box2D不保存shape的引用。它把数据克隆到一个新的b2Shape对象中。

注意,每个fixture都必须有一个父body,即使fixture是静态的。然而,你可以把所有静态fixture都依附于单个静态body之上。这个静态物体是为了保证Box2D内部的代码更具一致性,以减少潜在的bug数量。

大多Box2D类型以b2为前缀。这是这是为了减少与你的代码之间命名冲突的情况。

2.3      创建动态body

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

首先,我们使用CreateBody方法创建body。默认情况下body是静态的,所以我们应当在构造期间设置b2BodyType,使得body变为动态的。

b2BodyDef bodyDef;

bodyDef.type = b2_dynamicBody;

bodyDef.position.Set(0.0f, 4.0f);

b2Body* body = world.CreateBody(&bodyDef);

然后,我们使用fixture定义创建并添加一个多边形形状到物体上。我们先创建一个box shape:

b2PolygonShape dynamicBox;

dynamicBox.SetAsBox(1.0f, 1.0f);

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

b2FixtureDef fixtureDef;

fixtureDef.shape = &dynamicBox;

fixtureDef.density = 1.0f;

fixtureDef.friction = 0.3f;

我们使用fixture定义可以创建fixture。这会自动更新body的质量。你可以为body添加许多fixture。每个fixture对总质量都有贡献。

body->CreateFixture(&fixtureDef);

这就是初始化过程。现在我们已经准备好开始模拟了。

2.4      模拟(Box2D的)世界

我们已经初始化了地面盒和动态盒。现在是让牛顿接手的时刻了。我们只有少数几个问题需要考虑。

Box2D使用数学算法中的积分器(integrator)。积分器在离散的时间点上模拟物理方程,它将与传统游戏动画循环一同运行。所以我们需要为Box2D选取一个时间步,通常来说游戏的物理引擎需要至少要60Hz的速度,也就是1/60s的时间步。你可以使用更大的时间步,但是你必须更加小心地为你的世界调整定义。我们也不喜欢时间步变化得太大,所以不要把时间步关联到帧频(除非你真的必须这样做)。直截了当地,这就是时间步:

float32 timeStep = 1.0f / 60.0f;

除了积分器之外,Box2D中还有更大段代码称为约束求解器(constraint solver)。约束求解器用于解决模拟中的所有约束,一次一个。单个的约束会被完美的求解,然而当我们求解一个约束的时候,我们就会稍微破坏另一个。要得到好的解,我们需要迭代所有约束多次。

在约束求解器中有两个相位:速度相位和位置相位。在速度相位中,求解器计算使得body运动的脉冲。在位置相位中,求解器调整body的位置以减少重叠和关节脱离。每个相位拥有自己的迭代计数。此外,如果错误小的话,位置相位可能早期退出迭代。

对于速度和位置两者而言,建议的Box2D迭代次数是10次。你可以按自己的喜好去调整这个数字,但要记得它是速度与精度之间的折中。更少的迭代会增加性能并降低精度,同样地,更多的迭代会降低性能但提高模拟质量。对于这个简单示例,我们不需要更多迭代。这是我们选择的迭代次数。

int32 velocityIterations = 6;

int32 positionIterations = 2;

注意,时间步和迭代次数是完全无关的。一次迭代不是一个子步。一次迭代就是在时间步之内单次遍历所有约束。你可以在单个时间步内多次遍历约束。

现在我们可以开始模拟循环了,在游戏中模拟循环应该并入游戏循环。每次循环你都应该调用b2World::Step。通常调用一次就够了,这取决于帧频以及物理时间步。步进后,你应当调用b2World::ClearForces清除你施加到body上的任何力。

这个Hello World程序设计得非常简单,所以它没有图形输出。胜于完全没有输出,代码会打印出动态body的位置以及旋转角度。这是在1秒钟时间内模拟60个时间步的模拟循环。

for (int32 i = 0; i < 60; ++i)

{

world.Step(timeStep, velocityIterations, positionIterations);

world.ClearForces();

b2Vec2 position = body->GetPosition();

float32 angle = body->GetAngle();

printf("%4.2f %4.2f %4.2f/n", position.x, position.y, angle);

}

输出展示了盒子降落到地面盒的情况。你的输出应当看起来是这样:

0.00 4.00 0.00

0.00 3.99 0.00

0.00 3.98 0.00

...

0.00 1.25 0.00

0.00 1.13 0.00

0.00 1.01 0.00

2.5      清理工作

当一个world对象超出它的作用域,或通过指针将其delete时,所有body、fixture和joint的内存都会被释放。这能使你的工作变得更简单。然而,你应该将body,fixture或joint的指针都清零,因为它们已经无效了。

2.6      关于testbed

一旦你征服了HelloWorld,你应该开始看Box2D的testbed了。testbed是一个单元测试框架以及演示环境,这是一些它的特点:

l  可移动和缩放的摄像机

l  鼠标拣选动态body的shape

l  可扩展的测试集

l  通过图形界面选择测试,调整参数,以及设置调试绘图

l  暂停和单步模拟

l  文字渲染

Box2D翻译_第二章相关推荐

  1. ArcGIS for Desktop入门教程_第二章_Desktop简介 - ArcGIS知乎-新一代ArcGIS问答社区

    原文:ArcGIS for Desktop入门教程_第二章_Desktop简介 - ArcGIS知乎-新一代ArcGIS问答社区 1 Desktop简介 1.1 ArcGIS for Desktop ...

  2. c语言运行时更入下一行,C语言高级语言程序设计(一)_第二章 C程序设计基础(二).ppt...

    C语言高级语言程序设计(一)_第二章 C程序设计基础(二) * 问a,b能否交换?不能.示例 传值调用 如何改变参数的值?在后续章节中介绍 下:传值 * 传值的好处 下:问题3.2 * * * 使用范 ...

  3. 微型计算机控制数字量输入输出,[工学]WX_微型计算机控制技术_第二章5.ppt

    [工学]WX_微型计算机控制技术_第二章5 数字量输出驱动电路 三极管驱动电路 继电器驱动电路 晶闸管驱动电路 固态继电器驱动电路 达林顿驱动电路 微型计算机控制技术 第2章 输入/输出接口与过程通道 ...

  4. 微信小程序零基础入门_第二章 小程序框架_逻辑层

    第二章 小程序框架_逻辑层 2.1 逻辑层 小程序开发框架的逻辑层是基于JavaScript进行编写和实现的.在开发过程中写的所有代码,最终都被整合成一份JavaScript,在小程序启动的时候开始执 ...

  5. kelvin模型蠕变方程_第二章:黏弹性与波传播——2.4 力学模型和波传播

    Wave Fields in Real Media:Wave Propagation in Anisotropic,Anelastic,Porous and Electromagnetic Media ...

  6. 2的10次方-1的python表达式_第二章PythonⅠ的基本语法,python,I

    第二章 python基本语法 I 整数 交换两个变量的值 num1 = 10 num2 = 15 ##常规蛇形变换 tmp = num1 num1 = num2 num2 = tmp ##python ...

  7. 两平面平行但不重合的条件是_____黑龙江省大庆外国语学校高中数学_第二章《2.2_直线、平面平行的判定及其性质》单元测试5_新人教A版必修3...

    黑龙江省大庆外国语学校高一数学必修二第二章<2.2 直线.平面平 行的判定及其性质>单元测试5 一.选择题1.若两个平面互相平行,则分别在这两个平行平面内的直线( ) A.平行 B.异面 ...

  8. 信号与系统_第二章 连续系统的时域分析

    第二章 连续系统的时域分析 ( 连续系统在时域上进行分析 ) 2.1 引言 2.2 LTI系统的微分方程表示及响应 2.3 零输入响应与零状态响应 2.4 单位冲激响应 2.5 卷积积分 2.6 卷积 ...

  9. 用python编程、假设一年期定期利率_第二章-习题答案

    第二章习题 1 . 写一个算法(流程图和 python 程序) :输入三个数,输出其最 大者. numA=3 numB=4 numC=5 if numA <= numB: if numC pri ...

最新文章

  1. BZOJ 3566: [SHOI2014]概率充电器
  2. MyBatis架构分层
  3. R中控制输出数值的小数点位数round,和有效数字位数signif
  4. kafka高可用集群原理
  5. C语言试题二十之利用以下的简单迭代方法求方程cos(x)-x=0的一个实根。
  6. linux- root管理员权限
  7. 程序员告诉你如何用技术手段玩转冲顶大会
  8. C# 中格式化字符串中包含 { 或者 } 如何转义?
  9. 多媒体计算机技术英文,掌握多媒体计算机技术中各专业语句的英文表达方式.doc...
  10. WinRAR去广告方法,了解一下?
  11. TCP/IP框架总结
  12. laravel 阿里云短信验证码
  13. java识别手写文字_Java 实现OCR 识别图像文字(手写中文)----tess4j
  14. Origin_8.0_crack(origin8.0序列号(origin8.0破解补丁))
  15. 计算机网络 | 网络层(数据平面)
  16. 电动汽车连接器的全球与中国市场2022-2028年:技术、参与者、趋势、市场规模及占有率研究报告
  17. 计算机老师的作文,电脑,我的好老师作文
  18. 【转载】利用ENVI直接建立掩膜去除背景Inf值或NaN值
  19. VS2017初学者如何打开右侧的解决方案资源管理器
  20. 佛说 众生皆苦 今日果昨日因

热门文章

  1. python web py入门-7-响应处理(下)
  2. 女儿7岁就要做牙齿矫正,这些年我都做错了什么?
  3. 使用UE4创建一个简单真实的地球(一)
  4. Java-opts变量没生效,使用JAVA_OPTS env变量运行java无效
  5. C语言编程学习制作最好玩的报数游戏
  6. 【windows】系统账户策略的应用
  7. 主体阶段钢筋工程、模板工程、混凝土、管线预埋施工要点都有哪些?
  8. Windows2000 内核级进程隐藏、侦测技术[毕业论文]
  9. UVM-TLM通信机制(四)
  10. java导出txt文件列对齐