Box2d笔记–Hello b2World2015-02-05 13:59:35

( 还没有投票,继续加油! )
分享:
31.3K

Box2d中的物理世界,即b2World类就是一个包含了各种物体(body,物理体,或者叫刚体),固定附着物(fixture,形状与物理体的绑定物)以及各种约束体(比如关节),并使其在当中完成各种交互的这样一个集合体.

这个世界可能存在重力,所以,在创建这个世界的时候我们需要传一个描述重力的二维向量(v2对象),当然这取决于你的视角设定,也许你是做的横版游戏,这样的确需要一个重力.如果是顶视图,那可能就不需要重力了.

var gravity:V2=new V2(0,10);

var world:b2World=new b2World(gravity);

然后世界定期需要刷新

//刷新时间粒度

var stepTime:Number=1/30;

//速度计算层级

var velocityIterations:int=8;

//位置计算层级

var positionIterations:int=8;

world.Step(stepTime,velocityIterations,positionIterations);

在这个Step方法中进行了碰撞的检测,速度的更新等操作.

正如一开始描述的那样,world是一个管理刚体的集合.那么,刚体的产生,销毁以及碰撞判断都由world来处理.所以我们很容易找到b2World.CreateBody,b2World.DestoryBody这样的方法刚体共有三种类型,分别是staticBody,dynamicBody以及kinematicBody其含意分别是指,静态刚体(即不受力影响的物体,比如边界墙),动态刚体(完全模拟真实物理情况的物体),运动刚体(这是2.1版新增的一个类型,和静态刚体相比,就是它可以移动.它也同样不会被环境力所影响)现在我尝试在world中创建两个刚体

var mybodyA:b2Body=world.CreateBody(new b2BodyDef());

var mybodyB:b2Body=world.CreateBody(new b2BodyDef());

但实际上,仅仅只是这样创建两个刚体是没有意义的.因为它还没有具体的形状.所以它们即存在于这个世界中,但又无法参与到具体的碰撞运算中.这个时候我们需要再定义一下形状形状有两类,一种是b2PolygonShape(多边形),一种是b2CircleShape(圆形)多边形最多有8个边,并且多边形必须是凸边形.当然,你也可以使用组合来形成更为伪凹边形或者更复杂的形状.这里我们分别把上边的两个刚体一个定义成一个普通的矩形方形,另一个定义成圆形.

var shapeA:b2PolygonShape=new b2PolygonShape();

var boxWidth:Number=100;

var boxHeight:Number=100;shapeA.SetAsBox(boxWidth,boxHeight);

var radius:Number=100;

var shapeB:b2CircleShape=new b2CircleShape(radius);

接下来就是将刚体和形状通过附着对象(b2Fixture)绑定起来.

var fixtureDef:b2FixtureDef=new b2FixtureDef();

fixtureDef.shape=shapeA;

new b2Fixture(myBodyA,fixtureDef);

也可以使用更简洁的写法

var density:Number=1;

myBodyA.CreateFixtureShape(shapeA,density);

此时场景中便有了一个方形的刚体了.现在我们把方形刚体当做"地板",放在下方*注意,一般来说,定义刚体初始的位置时,要尽量在刚开始使用b2BodyDef对象建立刚体的时候就定义好,而不是已经创建好后再去更新位置,因为会有一瞬间,所有刚体都会堆积在同一个位置诞生,那样不利于正确的碰撞运算.所以我们这里要修改一下我们开始创建刚体的代码.

var bodyDefA:b2BodyDef=new b2BodyDef();

bodyDefA.postion.v2=new V2(0,400);

bodyDefA.type=b2Body.b2_staticBody;

var mybodyA:b2Body=world.CreateBody(bodyDefA);

这样就在下方创建了一个静态刚体用着"地板"了.现在我们要再把开始那个球给完善了.先修改一下创建时的代码var bodyDefB:b2BodyDef=new b2BodyDef();

bodyDefB.postion.v2=new V2(10,0);

bodyDefB.type=b2Body.b2_dynamicBody;

var mybodyB:b2Body=world.CreateBody(bodyDefB);

再建立形状关联

myBodyB.CreateFixtureShape(shapeB,1);


这样两个可以进行物理模拟的有形状的刚体就形成,但是它们现在还并不是可视的.一般来说.我们在游戏开发中都会将自己的贴图(Sprite)附着在刚体上.当刚体发生位移或者旋转时,我们只需要同步一下即可.刚体有一个userData属性是专门用来存放刚体对应的自定义对象的.我们可以将我们的贴图放在这里.比如我们的库中有两个导出名分别叫Ball和Box的影片剪辑,那么我们可以象下边这样将影片剪辑的实例存放在userData中.

mybodyA.SetUserData(new Box());

mybodyB.SetUserData(new Ball());

当然,你也可以在刚体定义对象中就申明

var bodyDefB:b2BodyDef=new b2BodyDef();

bodyDefB.userData=new Ball();

然后再在EnterFrame事件中执行world.Step方法.

addEventListener(Event.EnterFrame,update);

function update(e:Event){

world.Step(1/30,8,8);

for(var body:b2Body = world.GetBodyList(); body; body = body.GetNext()){

var userData:*=body.GetUserData();

if(userData is Sprite){

userData.x = body.GetPosition().x;

userData.y = body.GetPosition().y;

userData.rotation = body.GetAngle() * (180/Math.PI);

}

}

}

有时候我们在做测试的时候可能没有准备什么box,什么ball的影片剪辑,这时,我们可以先使用debugdraw来绘制形状,查看一个演算的效果.使用的方式为var debug:b2DebugDraw = new b2DebugDraw(world);

addChild(debug);

然后在update中刷新绘图即可

debug.Draw();


参考资料:

[jbox2d-library-2.1.2/jbox2d-testbed-2.1.2/jbox2d-library-2.1.2.0-javadoc]

Box2d笔记–Hello b2World jbox2d-library.rar [登录雪炭网后可见]






头像

snowcoal
  • box2d
  • 笔记

本文标签:

box2d笔记

收藏到我的私密空间

标题:Box2d笔记–Hello b2World

作者:柳岸花明

你暂未登录,请登录后才可收藏至您的私密空间 确认取消
雪炭网

键盘操作 更便捷 -雪炭网雪中送炭-乐趣无限