早上在网上看了好多资料,都不知道BOX2D要怎么样才能使用自定义皮肤,直到看到这个
Box2D for Flash and AS3: Bitmaps and Boxes
的时候,我才恍然大悟,明白了什么神马叫做引擎,太高级啦。原来BOX2D本身不支持外部皮肤导入,并且他本身制作的不b2Body根本就不可见,所以要drawDebugView,这个也就是之前debugView的功能了,真实应用中new出来的显示实例只需要通过某种方法绑定到BOX2D里面对应的b2Body即可,然后在ENTER_FRAME时间中进行同步更新就可以了。
所以在我的例子中,我在stage上点击一下,会同时生成一个b2Body和一个Sprite,存放在两个不同的数组当中,然后在enterframe事件中进行位置更新。
新代码如下
package { /** * @create_time Apr 13, 2012 4:00:54 PM * @author Ado * @E-mail: adodo08@163.com **/ import Box2D.Collision.Shapes.b2CircleShape; import Box2D.Collision.Shapes.b2PolygonShape; import Box2D.Common.Math.b2Vec2; import Box2D.Dynamics.b2Body; import Box2D.Dynamics.b2BodyDef; import Box2D.Dynamics.b2DebugDraw; import Box2D.Dynamics.b2FixtureDef; import Box2D.Dynamics.b2World; import flash.display.Sprite; import flash.events.Event; import flash.events.MouseEvent; [SWF(width=1000,height=600,frameRate=60,backgroundColor=0xcccccc)] public class BoxTester extends Sprite { private var world:b2World; private var worldSprite:Sprite; private var drawScale:Number=20; private var bodys:Array = []; private var sps:Array = []; public function BoxTester() { //创建世界,两个参数:重力与是否睡眠 world = new b2World(new b2Vec2(0,10),true); //地板 createFloor(0,(stage.stageHeight - 10)/drawScale,stage.stageWidth/drawScale,10/drawScale); //天花板 createFloor(0,0,stage.stageWidth/drawScale,10/drawScale); //左墙 createFloor(0,0,10/drawScale,stage.stageHeight/drawScale); //右墙 createFloor((stage.stageWidth-10)/drawScale,0,10/drawScale,stage.stageHeight/drawScale); //调试用的,估计,待研究 // drawDebug(); addEventListener(Event.ENTER_FRAME, update); //让我很奇怪的是为什么监听不到鼠标事件 stage.addEventListener(MouseEvent.CLICK, generateBody); } private function createFloor($x:Number,$y:Number,$w:Number,$h:Number):void { var shape:b2PolygonShape = new b2PolygonShape(); shape.SetAsBox($w,$h); var fixture:b2FixtureDef = new b2FixtureDef(); fixture.density = 1; fixture.friction = 1; fixture.shape = shape; fixture.restitution = 1; var bodyDef:b2BodyDef = new b2BodyDef(); bodyDef.type = b2Body.b2_staticBody; bodyDef.position.Set($x,$y); var floor:b2Body = world.CreateBody(bodyDef); floor.CreateFixture(fixture); } private function generateBody(e:MouseEvent=null):void { var shape:b2CircleShape = new b2CircleShape(10/drawScale); var sp:Sprite = getSprite(); var fixture:b2FixtureDef = new b2FixtureDef(); fixture.userData = sp; fixture.density = 1; fixture.friction = 2; fixture.restitution = 1; fixture.shape = shape; var bodyDef:b2BodyDef = new b2BodyDef(); bodyDef.type = b2Body.b2_dynamicBody; bodyDef.position.Set(this.mouseX/drawScale, this.mouseY/drawScale); var body:b2Body = world.CreateBody(bodyDef); body.CreateFixture(fixture); bodys.push(body); sps.push(sp); addChild(sp); } private function getSprite():Sprite { var sp:Sprite = new Sprite(); sp.graphics.beginFill(0xffffff,.5); sp.graphics.lineStyle(1); sp.graphics.drawCircle(0,0,10); sp.graphics.endFill(); return sp; } private function update(e:Event):void { world.Step(1/drawScale,10,10); world.ClearForces(); world.DrawDebugData(); for each(var i:b2Body in bodys) { var sp:Sprite = sps[bodys.indexOf(i)]; sp.x = i.GetPosition().x*drawScale; sp.y = i.GetPosition().y*drawScale; } } private function drawDebug():void { var debugDraw:b2DebugDraw = new b2DebugDraw(); var debugSprite:Sprite = new Sprite(); addChild(debugSprite);//讲debugdraw的关联视图添加到舞台上 debugDraw.SetSprite(debugSprite);//关联sprite到debugdraw debugDraw.SetDrawScale(drawScale);//设置debugdraw的比例 debugDraw.SetFlags(b2DebugDraw.e_shapeBit|b2DebugDraw.e_jointBit);//? debugDraw.SetFillAlpha(0.5);//设置背景填充透明度 world.SetDebugDraw(debugDraw);//关联世界 } } }
注意细节:真实环境中测试需要将尺寸*worldScale
以上效果图如下: