注:点击鼠标添加Body,R键清空Body
原来博客园要注册才能看到swf的,附有截图
package { import Box2D.Collision.b2AABB; import Box2D.Collision.Shapes.b2CircleDef; import Box2D.Collision.Shapes.b2PolygonDef; import Box2D.Common.Math.b2Math; import Box2D.Common.Math.b2Vec2; import Box2D.Common.Math.b2XForm; import Box2D.Dynamics.b2Body; import Box2D.Dynamics.b2BodyDef; import Box2D.Dynamics.b2DebugDraw; import Box2D.Dynamics.b2World; import flash.display.Bitmap; import flash.display.BitmapData; import flash.display.Sprite; import flash.events.Event; import flash.events.KeyboardEvent; import flash.events.MouseEvent; import flash.geom.Point; import flash.ui.Keyboard; import ipk.bmpd.CutCtrl; /** * ... * @description HelloWorldの多边形 * @author ispooky * @date 2010.11.09 * * @see http://ispooky.cnblogs.com */ public class PolygonsApp extends Sprite { public static const ITERATIONS :int = 30; public static const TIME_STEP :Number = 1 / 30; public static const RATIO :int = 30; private static var world :b2World; private static var spriteToDrawOn :Sprite; public function PolygonsApp() { if (stage) init(); else addEventListener(Event.ADDED_TO_STAGE, init); } private function init(e:Event = null):void { removeEventListener(Event.ADDED_TO_STAGE, init); initB2D(); stage.addEventListener(MouseEvent.CLICK, onClickHandler); stage.addEventListener(KeyboardEvent.KEY_DOWN, onKeyDownHandler); } private function onKeyDownHandler(e:KeyboardEvent):void { if (e.keyCode == 82/*R*/) { ///// // 销毁Body ///// for (var bb:b2Body = world.m_bodyList; bb; bb = bb.m_next) { if (bb.m_userData is Sprite) { removeChild(bb.m_userData); world.DestroyBody(bb); } } } } private function onClickHandler(e:MouseEvent):void { if (world == null) return; createPolygon(); } private function initB2D():void { addEventListener(Event.ENTER_FRAME, onLoopHandler, false, 0, true); createWorld(); //showDebug(); createGrounds(); createPolygon(); createPolygon(); createPolygon(); } /** * 添加Body * @param _type */ private function createPolygon(_type:int = -1):void { var bodyDef:b2BodyDef = new b2BodyDef(); var boxDef:b2PolygonDef = new b2PolygonDef(); var circleDef:b2CircleDef = new b2CircleDef(); var body:b2Body; var type:int if (_type == -1) { var tmp_arr:Array = [0, 3, 4, 6, 8]; type = tmp_arr[int(Math.random() * 5)]; }else { type = _type; } var skin:Sprite = new Sprite(); var tmp_asset:Bitmap; var radius:int; var i:int; var tmp_radius:int = Math.random() * 40 + 30; var start_pos:Point = new Point(Math.random() * 100 - 50 + 275, Math.random() * 100 - 50 -100); switch(type) { case 0: bodyDef.position.Set(start_pos.x / RATIO, start_pos.y / RATIO); radius = int(Math.random() * 25) + 10; circleDef.radius = radius / RATIO; circleDef.density = 1; circleDef.friction = 0.2; circleDef.restitution = 0.3; tmp_asset = getAssets(0, radius); tmp_asset.x = -tmp_asset.width * 0.5; tmp_asset.y = -tmp_asset.height * 0.5; skin.addChild(tmp_asset); bodyDef.userData = skin; addChild(bodyDef.userData); body = world.CreateBody(bodyDef); body.CreateShape(circleDef); body.SetMassFromShapes(); break; case 3: createPolygonTypeOf(start_pos.x, start_pos.y, 3, tmp_radius); break; case 4: createPolygonTypeOf(start_pos.x, start_pos.y, 4, tmp_radius); break; case 5: createPolygonTypeOf(start_pos.x, start_pos.y, 5, tmp_radius); break; case 6: createPolygonTypeOf(start_pos.x, start_pos.y, 6, tmp_radius); break; case 7: createPolygonTypeOf(start_pos.x, start_pos.y, 7, tmp_radius); break; case 8: createPolygonTypeOf(start_pos.x, start_pos.y, 8, tmp_radius); break; } } /** * 创建正多边形Body * @param xpos * @param ypos * @param vertexCount * @param radius */ private function createPolygonTypeOf(xpos:Number, ypos:Number, vertexCount:int, radius:Number):void { var boxDef:b2PolygonDef = new b2PolygonDef(); boxDef.vertexCount = vertexCount; var angle:Number = Math.PI * 2 / vertexCount; var radius:Number = radius / RATIO; for (var i:int = 0; i < vertexCount; i++) { var dx:Number = radius * Math.cos(angle * i); var dy:Number = radius * Math.sin(angle * i); boxDef.vertices[i] = b2Math.b2MulX(new b2XForm(),new b2Vec2(dx, dy)); } boxDef.density = 2; boxDef.friction = 0.3; boxDef.restitution = 0.3; var bodyDef:b2BodyDef = new b2BodyDef(); bodyDef.angle = Math.random() * 360; bodyDef.position.Set(xpos / RATIO, ypos / RATIO); var skin:Sprite = new Sprite(); var tmp_asset:Bitmap; switch(vertexCount) { case 3: tmp_asset = getAssets(vertexCount, radius * RATIO); tmp_asset.x = -(tmp_asset.width - radius * RATIO); tmp_asset.y = -tmp_asset.height * 0.5; skin.addChild(tmp_asset); break; case 4: tmp_asset = getAssets(vertexCount, radius * RATIO); tmp_asset.x = -tmp_asset.width*0.5; tmp_asset.y = -tmp_asset.height * 0.5; skin.addChild(tmp_asset); break; case 6: tmp_asset = getAssets(vertexCount, radius * RATIO); tmp_asset.x = -tmp_asset.width*0.5; tmp_asset.y = -tmp_asset.height * 0.5; skin.addChild(tmp_asset); break; case 8: tmp_asset = getAssets(vertexCount, radius * RATIO); tmp_asset.x = -tmp_asset.width*0.5; tmp_asset.y = -tmp_asset.height * 0.5; skin.addChild(tmp_asset); break; } bodyDef.userData = skin; addChild(bodyDef.userData); var body:b2Body = world.CreateBody(bodyDef); body.CreateShape(boxDef); body.SetMassFromShapes(); } /** * 创建地板 */ private function createGrounds():void { var bodyDef:b2BodyDef = new b2BodyDef(); var boxDef:b2PolygonDef = new b2PolygonDef(); var body:b2Body; bodyDef.position.Set(275 / RATIO, 360 / RATIO); boxDef.SetAsBox(900 / 2 / RATIO, 30 / 2 / RATIO); boxDef.density = 0; boxDef.friction = 0.3; boxDef.restitution = 0.2; body = world.CreateBody(bodyDef); body.CreateShape(boxDef); boxDef.SetAsOrientedBox(30 / 2 / RATIO, 90 / 2 / RATIO, new b2Vec2( -200 / RATIO, -60 / RATIO), 0); body = world.CreateBody(bodyDef); body.CreateShape(boxDef); boxDef.SetAsOrientedBox(30 / 2 / RATIO, 90 / 2 / RATIO, new b2Vec2( 200 / RATIO, -60 / RATIO), 0); body = world.CreateBody(bodyDef); body.CreateShape(boxDef); boxDef.SetAsOrientedBox(30 / 2 / RATIO, 45 / 2 / RATIO, new b2Vec2( -435 / RATIO, -37.5 / RATIO), 0); body = world.CreateBody(bodyDef); body.CreateShape(boxDef); boxDef.SetAsOrientedBox(30 / 2 / RATIO, 45 / 2 / RATIO, new b2Vec2( 435 / RATIO, -37.5 / RATIO), 0); body = world.CreateBody(bodyDef); body.CreateShape(boxDef); } /** * 显示Debug图 */ private function showDebug():void { spriteToDrawOn = new Sprite(); addChild(spriteToDrawOn); var dbgDraw:b2DebugDraw = new b2DebugDraw(); dbgDraw.m_sprite = spriteToDrawOn; dbgDraw.m_drawScale = RATIO; dbgDraw.m_fillAlpha = 0.6; dbgDraw.m_lineThickness = 1.0; dbgDraw.m_drawFlags = b2DebugDraw.e_shapeBit | b2DebugDraw.e_jointBit; world.SetDebugDraw(dbgDraw); } /** * 创建物理空间 */ private function createWorld():void { var worldAABB:b2AABB = new b2AABB(); worldAABB.lowerBound.Set( -3000 / RATIO, -3000 / RATIO); worldAABB.upperBound.Set(3000 / RATIO, 3000 / RATIO); var gravity:b2Vec2 = new b2Vec2(0, 10); var doSleep:Boolean = true; world = new b2World(worldAABB, gravity, doSleep); } /** * 刷新物理空间 * @param e */ private function onLoopHandler(e:Event):void { if (world == null) return; world.Step(TIME_STEP, ITERATIONS); for (var bb:b2Body = world.m_bodyList; bb; bb = bb.m_next) { if (bb.m_userData is Sprite) { bb.m_userData.x = bb.GetPosition().x * RATIO; bb.m_userData.y = bb.GetPosition().y * RATIO; bb.m_userData.rotation = bb.GetAngle() * (180 / Math.PI); } } } /** * 获取贴图 * @param type * @param radius * @return */ private function getAssets(type:int = 0, radius:int = 20):Bitmap { var target_mc:Sprite = new Sprite(); target_mc.visible = false; addChild(target_mc); var tmp_bmpd:BitmapData = new Alsace_Pic(); var tmp_bmp:Bitmap = new Bitmap(tmp_bmpd); target_mc.addChild(tmp_bmp); var tmp_mc:Sprite = new Sprite(); tmp_mc.visible = false; tmp_mc.x = target_mc.x; tmp_mc.y = target_mc.y; addChild(tmp_mc); var new_bmp:Bitmap; var i:int; var pos:Point = new Point(Math.random() * 600 - 300 + 720, Math.random() * 200 - 100 + 450); tmp_mc.graphics.clear(); tmp_mc.graphics.beginFill(0x900000); switch(type) { case 0: tmp_mc.graphics.drawCircle(pos.x, pos.y, radius); tmp_mc.graphics.endFill(); new_bmp = new Bitmap(CutCtrl.cutOutSuper(target_mc, tmp_mc).clone()); break; case 3: tmp_mc.graphics.moveTo(pos.x + radius, pos.y); for (i = 1; i < 3; i++) { tmp_mc.graphics.lineTo(pos.x + radius * Math.cos(Math.PI * 2 / 3 * i), pos.y + radius * Math.sin(Math.PI * 2 / 3 * i)); } new_bmp = new Bitmap(CutCtrl.cutOutSuper(target_mc, tmp_mc).clone()); break; case 4: tmp_mc.graphics.moveTo(pos.x + radius, pos.y); for (i = 1; i < 4; i++) { tmp_mc.graphics.lineTo(pos.x + radius * Math.cos(Math.PI * 2 / 4 * i), pos.y + radius * Math.sin(Math.PI * 2 / 4 * i)); } new_bmp = new Bitmap(CutCtrl.cutOutSuper(target_mc, tmp_mc).clone()); break; case 5: tmp_mc.graphics.moveTo(pos.x + radius, pos.y); for (i = 1; i < 5; i++) { tmp_mc.graphics.lineTo(pos.x + radius * Math.cos(Math.PI * 2 / 5 * i), pos.y + radius * Math.sin(Math.PI * 2 / 5 * i)); } new_bmp = new Bitmap(CutCtrl.cutOutSuper(target_mc, tmp_mc).clone()); break; case 6: tmp_mc.graphics.moveTo(pos.x + radius, pos.y); for (i = 1; i < 6; i++) { tmp_mc.graphics.lineTo(pos.x + radius * Math.cos(Math.PI * 2 / 6 * i), pos.y + radius * Math.sin(Math.PI * 2 / 6 * i)); } new_bmp = new Bitmap(CutCtrl.cutOutSuper(target_mc, tmp_mc).clone()); break; case 7: tmp_mc.graphics.moveTo(pos.x + radius, pos.y); for (i = 1; i < 7; i++) { tmp_mc.graphics.lineTo(pos.x + radius * Math.cos(Math.PI * 2 / 7 * i), pos.y + radius * Math.sin(Math.PI * 2 / 7 * i)); } new_bmp = new Bitmap(CutCtrl.cutOutSuper(target_mc, tmp_mc).clone()); break; case 8: tmp_mc.graphics.moveTo(pos.x + radius, pos.y); for (i = 1; i < 8; i++) { tmp_mc.graphics.lineTo(pos.x + radius * Math.cos(Math.PI * 2 / 8 * i), pos.y + radius * Math.sin(Math.PI * 2 / 8 * i)); } new_bmp = new Bitmap(CutCtrl.cutOutSuper(target_mc, tmp_mc).clone()); break; } tmp_bmpd.dispose(); removeChild(tmp_mc); tmp_mc = null; removeChild(target_mc); target_mc = null; return new_bmp; } } }