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;
}

}

}

 

 

 

 

 

 

 

转载于:https://www.cnblogs.com/ispooky/archive/2010/11/09/1872924.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值