您的位置:首页 > 其它

《Box2D for Flash Games》翻译 (一)hello box2d world

2014-04-07 21:09 211 查看
http://blog.sina.com.cn/s/blog_441c62380101hkh5.html

(一) Hello Box2D World

如果你想编写一个 2d物理引擎的游戏或者应用,Box2d 是目前为止最好的选择,它已经被成功的应用在多个游戏中,比如 iphone 中的 angry bird 和 Tiny Wings,或者是 flash 版本的 Totem Destroyer 和 Red Remover,随便Google一下,你会知道这些游戏是有多么火了。

在开始研究 box2d World 之前,先来搞清楚一下刚体(rigid body)这个概念吧,刚体是一种十分坚硬的物体,在任何情况下都不会弯曲,无论你用多么坚硬的东西撞击它,它都不会改变形状,你可以把它想象成现实世界里的钻石或者更坚硬的物体,比如说来自于外太空的永远不被摧毁的陨石。

Box2d ,你依然可以模拟那些并不坚硬的东西,比如说弹力球。

下面是这一章我们需要了解的内容:

1,下载并且安装flash版本的 Box2d.
2,在flash项目中导入你需要的类
3,创建你的第一个 box2d World
4,理解重力和休眠刚体
5, 运行你的第一个空模拟器,处理时间步和约束

在本章结束的时候,你将学会建立一个空的,但是可以运行的box2d程序,以后呢,你就会在此基础上写出特别厉害的游戏了。

下载安装 Flash 版本的Box2d

你可以从官网( http://www.box2dflash.org/download) 或者从SourceForge
页面下载 (http://sourceforge.net/projects/box2dflash/ )
下载完压缩包时,解压 Box2D 压缩文件(你可以在 source 文件夹中找到)到你自己项目的同目录下,如下图所示:

如你所见 Box2D 文件夹,我建议你使用 640 x 480 大小的 flash文件,每秒30(fps),文档类命名为 Main,很多例子证明最好使用深颜色作为舞台背景,比如说#333333,反正在这本书里我都会这么设置。

现在我们导入 box2d 包。

Hello Box2d World

box2d是免费的开源项目,你不需要处理组件或者处理 SWC文件,你只需要把用到的类导入你的项目里就可以了。
打开Main.as 写入下面的代码片段

package {
import flash.display.Sprite
import Box2D.Dynamics.*;
import Box2D.Collision.*;
import Box2D.Collision.Shapes.*;
import Box2D.Common.Math.*;
public class Main extends Sprite {
public function Main() {
trace("my awesome game starts here");
}
}
}

测试影片你会看到输出窗口中输出“my awesome game starts here”,说明包已经成功导入。
以上代码不必多说。

虽然用 Hello Box2D World 标题但并不是教大家写 “Hello World” 程序,而是想介绍下所有 box2D 仿真和事件发生环境: 世界(world).
世界(world)就是模拟器发生的舞台,所有拥有Box2d物理性质的物体都要被塞到这个世界(world)里去,而且这个世界(world)足够大足够大不用担心边界问题,所有的物体都可以放进去,但是所有在计算机里的东西都是有所控制的,你世界里的物体越多,计算机的负担越重。

定义 Box2D World
跟现实世界一样,Box2D世界也有重力,那么我么先从定义重力说起。
在 main 方法中写入下面代码
var gravity:b2Vec2=new b2Vec2(0,9.81);
下面来介绍下第一个 box2d 数据类型:b2Vec2
b2Vec2是一个二维向量,是一种数据类型,他把(x,y)作为一组以向量的形式进行存储,构造函数中传有两个参数,都是 number 类型,分别代表了 x,y 方向上的值,
变量 gravity 用一个向量来表示,x= 0(水平方向无重力),y = 9.81(接近地球重力),物理上说物体在自由落体的时候速度每秒增加9.81米,如果不考虑空气阻力,
我们要模拟的是一个真实环境,如果想要了解更多物理方面的知识,请 google 或者 Wikipedia。

2,你可以用下面的代码从新规范你游戏。
var gravity:b2Vec2=new b2Vec2(0,1.63);

你也可以把参数设置为(0,0)模拟无重力的环境
var gravity:b2Vec2=new b2Vec2(0,0);

3,这个世界里的物体没事干的时候就可以休眠了。一个休眠的物体不受力的作用,也不需要模拟,他只是呆在原地不动,不会影响到其他的物体,box2d将忽略它,这样会提高程序的处理速度,提高性能,所以我要好好提醒你们,尽可能的让物体进入休眠状态。

休眠的物体不会永远休眠,只要有碰撞,或者有力直接作用于它身上的时候,它就会被激活。

4,下面行是boolean 变量的定义
var sleep:Boolean=true;

5,终于,我们要写第一个 world 啦
var world:b2World = new b2World(gravity,sleep);

6,现在我们已经有了这个容器,可以用它管理所有物体,进行仿真模拟了。

7,整理时间到,你的代码应该是这个样子的:

package {
import flash.display.Sprite;
import Box2D.Dynamics.*;
import Box2D.Collision.*;
import Box2D.Collision.Shapes.*;
import Box2D.Common.Math.*;
public class Main extends Sprite {
public function Main() {
var gravity:b2Vec2=new b2Vec2(0,9.81);
var sleep:Boolean=true;
var world:b2World = new b2World(gravity,sleep);
}
}
}

现在你已经学会如何创建和配置一个 Box2d World了。下面看看如何在它里面进行模拟物理

运行模拟

因为每一帧都在进行模拟,所以第一件事就是给每一帧都加上监听。
1,简单修改一下已写好的代码

package {
import flash.display.Sprite;
import flash.events.Event;
import Box2D.Dynamics.*;
import Box2D.Collision.*;
import Box2D.Collision.Shapes.*;
import Box2D.Common.Math.*;
public class Main extends Sprite {
public function Main() {
var gravity:b2Vec2=new b2Vec2(0,9.81);
var sleep:Boolean=true;
var world:b2World = new b2World(gravity,sleep);
addEventListener(Event.ENTER_FRAME,updateWorld);
}
private function updateWorld(e:Event):void {
trace("my awesome simulation runs here");
}
}
}

我们刚刚加上了 ENTER_FRAME 事件,这需要在 updateWorld 方法里添加模拟部分的功能,如果你对AS3中的事件处理机制有疑问,可以参考Adobe的官网或者查看《flash game development by example》,这本书会手把手教你写 flash 游戏。

box2d仿真过程是在每个不连续的时间步(steps of time)里不断进行模拟才完成的。也就是说,在每个时间步(steps of time)都要更新,我们得考虑给模拟器设置一个什么样的时间步(steps of time),通常来说,一般物理游戏中的时间步是 1/60 秒,但是呢,我的 flash文档中的帧频为 30 fps ,所以我这里设置的时间步(steps
of time)为 1/30。

updateWorld 方法里的第一行为:

var timeStep:Number=1/30;

光定义时间步是不够地,在每一步中,每一个物理实体的更新都是根据施加在它上面的力来决定的(除非他在休眠),处理这个的算法叫做约束求解器( constraint solver,这是什么东东啊),它每次都会遍历所有约束(constraint)并解决它,如果你想了解更多关于约束(constraint)的知识,请 google 或者 Wikipedia。

想象两个正在运动的球,在真实世界里,他们的位置时时刻刻都在发生变化,使用计算机模拟,就要用 for 循环(假设哈)在每一次迭代更新所有的球的位置,只要这些球没有相互作用就一切正常,但是如果第二个球碰到第一个球怎么办,这个球的位置已经被更新了吗?他们会有重叠,这在仿真环境是不可能发生的,要合理的解决这个问题,我们要不止一遍的循环所有的约束(constraint),问题是:需要循环多少遍。

这里有两个约束解算器(constraint solver),
速度解算器(velocity constraint solver) ,和位置解算器(position constraint solver)。速度解算器(velocity constraint solver) 是根据他们的冲量来移动物体,位置解算器(position constraint solver)是调整他们的物理位置来避免重叠。

因此,迭代次数越多,仿真越准确,但是性能越差,超过100个物体使用速度解算器的迭代次数为10, 位置解算器的迭代次数为10的设置 ,尽管
box2d的作者建议速度解算器的迭代次数为8,位置解算器的迭代次数为3的设置.

3,随你的喜好来设置这些值,好吧,这里我使用 10 来设置两个解算器的迭代次数。
看下面两行代码:

var velIterations:int=10;
var posIterations:int=10;

然后我们使用 world 变量调用 step() 方法去更新模拟器,
在 updateWorld 方法中使用 world 变量,我们要先声明 world 变量,代码如下:

package {
import flash.display.Sprite;
import flash.events.Event;
import Box2D.Dynamics.*;
import Box2D.Collision.*;
import Box2D.Collision.Shapes.*;
import Box2D.Common.Math.*;
public class Main extends Sprite {
private var world:b2World;
public function Main() {
var gravity:b2Vec2=new b2Vec2(0,9.81);
var sleep:Boolean=true;
world=new b2World(gravity,sleep);
addEventListener(Event.ENTER_FRAME,updateWorld);
}
private function updateWorld(e:Event):void {
var timeStep:Number=1/30;
var velIterations:int=10;
var posIterations:int=10;
world.Step(timeStep,velIterations,posIterations);
}
}
}

现在我们的世界已经构建完成了,但是这个世界来,里面什么东西都没有,没意思的很,下一章中我们将在世界中填入各种各样的物体。

5,最后一件事,在每个时间步后你都需要将力清零,让模拟器在下一个时间步重新开始,加上 world.ClearForces() 这句话就可以了,最终的代码如下:

package {
import flash.display.Sprite;
import flash.events.Event;
import Box2D.Dynamics.*;
import Box2D.Collision.*;
import Box2D.Collision.Shapes.*;
import Box2D.Common.Math.*;
public class Main extends Sprite {
private var world:b2World;
public function Main() {
var gravity:b2Vec2=new b2Vec2(0,9.81);
var sleep:Boolean=true;
world=new b2World(gravity,sleep);
addEventListener(Event.ENTER_FRAME,updateWorld);
}
private function updateWorld(e:Event):void {
var timeStep:Number=1/30;
var velIterations:int=10;
var posIterations:int=10;
world.Step(timeStep,velIterations,posIterations);
world.ClearForces();
}
}
}

如果你在
Packt 购买了该书,你可以下载所有示例的代码, 网址是http://www.packtpub.com,你通过其他途径购买的话,你可以问 http://www.packtpub.com/support 注册就可以邮件得到所有源文件。

总结:

我们刚刚完成了安装了 flash 版的 Box2D,把它导入到你的项目里,创建一个实时运行的受重力控制的模拟器,以及管理时间步和约束解算器,现在你已经为你的游戏准备了一个完整的世界了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: