Box2dの自定义多边形

注:点击鼠标添加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;
}

}

}

 

 

 

 

 

 

 

posted @ 2010-11-09 18:00  ispooky  阅读(1171)  评论(0编辑  收藏  举报