Hello Box2dAs3
以前做化学课件,发现Flash里处理对象的碰撞是个很麻烦的问题,即使是对于规则的对象,比如某个仪器(滴管,试剂瓶等),也查过很多资料来解决碰撞问题,但都很复杂,看了后一头雾水。一次偶然发现box2dAs3,它竟然能把对象碰撞模拟得如此真实,并且Box2dAs3中处理碰撞并不需要开发者处理,开发者只需要创建一个一个的对象(box2d中称为刚体),它会自动处理每个刚体的碰撞,即物理特性。下面是我的第一篇关于box2dAs3的入门。
package { import Box2D.Collision.b2AABB; import Box2D.Collision.Shapes.b2PolygonDef; import Box2D.Common.Math.b2Vec2; import Box2D.Dynamics.b2Body; import Box2D.Dynamics.b2BodyDef; import Box2D.Dynamics.b2DebugDraw; import Box2D.Dynamics.b2World; import flash.display.Sprite; import flash.events.Event; /** * Box2dAs3 Version 2.0.1 * @author ywxgod--http://www.cnblogs.com/ywxgod/ * */ [SWF(backgroundColor="333333",frameRate="30",width="550",height="400")] public class HelloBox2dAs3 extends Sprite { private var physcale:Number = 30.0; private var timeStep:Number = 1 / physcale; private var iteration:int = 10; private var body:b2Body; private var world:b2World; private const FLOOR_WIDTH:int = 550; private const FLOOR_HEIGHT:int = 20; private const WALL_WIDTH:int = 20; private const WALL_HEIGHT:int = 400; private var maxBodysNum:int = 50; private var count:int = 0; public function HelloBox2dAs3():void { init(); } private function init():void { createWorld(); createFloorAndWalls(); showDebuger(); run(); addEventListener(Event.ENTER_FRAME,onFrame); } private function createWorld():void { var aabb:b2AABB = new b2AABB(); aabb.lowerBound.Set( -100, -100); aabb.upperBound.Set(100, 100); var gravity:b2Vec2 = new b2Vec2(0, 9.8); world = new b2World(aabb, gravity, true); } private function createFloorAndWalls():void { var floorShapeDef:b2PolygonDef = new b2PolygonDef(); floorShapeDef.density = 0; floorShapeDef.friction = 0.3; floorShapeDef.restitution = 0.4; floorShapeDef.SetAsBox(FLOOR_WIDTH / 2 / physcale, FLOOR_HEIGHT / 2 / physcale); var floorBodyDef:b2BodyDef = new b2BodyDef(); floorBodyDef.position.Set(FLOOR_WIDTH / 2 / physcale, (WALL_HEIGHT-FLOOR_HEIGHT/2) / physcale); var floorBody:b2Body = world.CreateBody(floorBodyDef); floorBody.CreateShape(floorShapeDef); floorBody.SetMassFromShapes(); var leftWallShapeDef:b2PolygonDef = new b2PolygonDef(); leftWallShapeDef.density = 0; leftWallShapeDef.friction = 0.3; leftWallShapeDef.restitution = 0.4; leftWallShapeDef.SetAsBox(WALL_WIDTH / 2 / physcale, WALL_HEIGHT / 2 / physcale); var leftWallBodyDef:b2BodyDef = new b2BodyDef(); leftWallBodyDef.position.Set(WALL_WIDTH / 2 / physcale, (WALL_HEIGHT / 2) / physcale); var leftWallBody:b2Body = world.CreateBody(leftWallBodyDef); leftWallBody.CreateShape(leftWallShapeDef); leftWallBody.SetMassFromShapes(); var rightWallShapeDef:b2PolygonDef = new b2PolygonDef(); rightWallShapeDef.density = 0; rightWallShapeDef.friction = 0.3; rightWallShapeDef.restitution = 0.4; rightWallShapeDef.SetAsBox(WALL_WIDTH / 2 / physcale, WALL_HEIGHT / 2 / physcale); var rightWallBodyDef:b2BodyDef = new b2BodyDef(); rightWallBodyDef.position.Set((FLOOR_WIDTH-WALL_WIDTH / 2) / physcale, (WALL_HEIGHT / 2) / physcale); var rightWallBody:b2Body = world.CreateBody(rightWallBodyDef); rightWallBody.CreateShape(rightWallShapeDef); rightWallBody.SetMassFromShapes(); } private function createActors(count:int):void { var boxShapeDef:b2PolygonDef = new b2PolygonDef();
boxShapeDef.density = 2;
boxShapeDef.friction = 0.3;
boxShapeDef.restitution = 0.4;
boxShapeDef.SetAsBox(40 / 2 / physcale, 15 / 2 / physcale);
var boxShapeBodyDef:b2BodyDef = new b2BodyDef();
boxShapeBodyDef.position.Set((275) / physcale, (-count*15) / physcale);
var boxShapeBody:b2Body = world.CreateBody(boxShapeBodyDef);
boxShapeBody.CreateShape(boxShapeDef);
boxShapeBody.SetMassFromShapes();
} private function onFrame(e:Event):void { world.Step(timeStep, iteration); if (count--<5&&world.m_bodyCount< maxBodysNum) { createActors(count); count = 5; } } private function showDebuger():void { var sprite:Sprite = new Sprite(); addChild(sprite); var dbg:b2DebugDraw = new b2DebugDraw(); dbg.m_sprite = sprite; dbg.m_alpha = 0.5; dbg.m_drawScale = physcale; dbg.m_drawFlags = b2DebugDraw.e_obbBit; dbg.m_fillAlpha = 0.5; world.SetDebugDraw(dbg); } private function run():void { } } }
18行 定义swf文件的舞台背景,帧频,宽度,高度
21-23行 定义物理世界与flash世界中长度单位,box2d模拟频率及迭代次数
50-57行 创建一个物理世界world,所有的刚体都是存在其中,world的作用就像flash中的stage,所有的显示对象都被添加到stage一样。创建world需要三个参数:边界盒,重力加速度,是否休眠。
59-93行 创建地面,墙壁等。
95-108行 创建方形刚体,跟59-93行中唯一不同的地方是密度的赋值。
110-119行 在EnterFrameEvent中创建刚体。
121-132行 利用box2dAs3本身的调试显示函数来显示创建的刚体。因为box2das3中没有显示对象的概念,所以无法像flash添加显示对象到舞台一样去做了。
总结:
1。flash中的长度是以像素为单位,box2d中的长度是以米为单位,且一米等于30个像素。
2。flash中有显示对象,且显示对象都是位于stage上,box2d中有刚体,且刚体都是存在于world中。
3。flash中创建对象是需要制定其宽度和高度,box2d中定义形状只需要其高度宽度的各一半。
4。创建刚体的步骤:
a。定义形状,在形状定义中定义摩擦系数friction,反弹系数restitution,密度density,形状的大小SetAsBox
b。刚体定义,在刚体定义中设置刚体的位置position
c。创建刚体,传入刚体定义,由world来创建刚体
d。创建于刚体关联的形状,传入形状定义,有刚体来创建自己关联的形状。
e。设置质量。
5。设置b2DebugDraw时的参数
a。m_sprite 用来显示刚体的显示对象
b。m_alpha 显示对象的透明度
c。m_drawScale 放大系数,这个只应该跟长度单位相同,否则显示的刚体将会只有原来的1/30。
d。m_fillAlpha 绘制刚体时的填充色透明度。
e。m_drawFlags 标志,告诉b2DebugDraw要绘制刚体哪些相关属性,具体值为b2DebugDraw.e_obbBit,b2DebugDraw.e_aabbBit,b2DebugDraw.e_centerOfMassBit等,也可以是几个值的和。
E-mail:给我发邮件
出处:http://ywxgod.cnblogs.com
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。