// userData是系统内置的 并且添加到了舞台的 假如你要自定义body 就用bodyDef.userData将其改变 ,并添加至舞台
// 下面是自定义pollygon形状 box2d里默认的polygon形状是方形 。 下面创建一个三角形 和一个不规则的六边形
// 其中点vertices 是这样设置 vertices[0].Set(0,1) 表示该点距形状中心点(Polygon center)的水平距离 为0,
//垂直距离为 1 水平方向 正数表示 在中心点的右边 负数表示在中心点的左边 垂直方向 : 正数表示在中心点下面,
//负数表示在中心点上面 。
// 注意创建 的图像要是凸的,不是凹的,是凹的就无交互作用
package {
import Box2D.Collision.*;
import Box2D.Collision.Shapes.*;
import Box2D.Common.Math.*;
import Box2D.Dynamics.*;
import Box2D.Dynamics.Joints.*;
import flash.display.Sprite;
import flash.events.Event;
import Box2D.Dynamics.Joints.*
import flash.events.MouseEvent;
public class CreateIrregularPolygon extends Sprite {
private var jointDef:b2MouseJointDef;
private var joint:b2MouseJoint;
private var m_world:b2World;
private var m_timeStep:Number;
private var m_iterations:uint;
private var phsScale:uint=30;
private var AABB:b2AABB;
private var body:b2Body;
private var bodyDef:b2BodyDef;
private var gravity:b2Vec2;
private var boxDef:b2PolygonDef;
private var debugDraw:b2DebugDraw;
/*
* @author :Dream@Night~夜梦惊魂
* date :10/13/2009
*
*/
public function CreateIrregularPolygon() {
m_timeStep=1.0/30.0;
m_iterations=10;
createWorld();
createGround();
createPolygons();
createDebugDraw();
addEventListener(Event.ENTER_FRAME,Update,false,0,true);
stage.addEventListener(MouseEvent.MOUSE_DOWN,onDown);
// trace(this.getChildAt(1));//测试表明对象是否添加进舞台,结果为超出索引:故 在不用useData时,其默认的userData是添加进Sprite Sprite在添加进文档类
//文档类再添加进舞台。
stage.addEventListener(MouseEvent.MOUSE_UP,onUp);
}//增加调试状态
private function createDebugDraw():void{
debugDraw= new b2DebugDraw();
var userDataSprite= new Sprite ();
var debugSprite:Sprite= new Sprite();
debugDraw.m_sprite=userDataSprite;
addChild(debugDraw.m_sprite);
userDataSprite.addChild(debugSprite);
debugDraw.m_drawScale=30;//即 1 pixel
debugDraw.m_alpha=1;//为1时线全部显示出来 为0 ,即其透明了 显示不出线
debugDraw.m_fillAlpha=0.5;//对象的颜色显示出来的透明度 为1就不显示对象原来的颜色了
debugDraw.m_lineThickness=1.5;//线显示的粗细 。
debugDraw.m_drawFlags=0xFFFFFF;//此句很重要,有了此句,一些线才会显示出来
m_world.SetDebugDraw(debugDraw);
}
private function createWorld():void {
AABB= new b2AABB();
AABB.lowerBound.Set(-100.0, -100.0);
AABB.upperBound.Set(100.0, 100.0);
gravity=new b2Vec2(0,10.0);
//gravity.Set(0,10.0);
m_world=new b2World(AABB,gravity,true);
}
private function createGround():void {
bodyDef = new b2BodyDef();
var X:Number= 20/(phsScale*2);
var Y:Number= 700/(phsScale*2);
bodyDef.position.Set(X,Y);
boxDef = new b2PolygonDef ();
boxDef.vertexCount=4;
boxDef.density=0;
boxDef.restitution=0.4;
boxDef.friction=0.3;
boxDef.SetAsBox(30,2);
/*bodyDef.userData= new Ground();//Ground
bodyDef.userData.width=30*2*phsScale;
bodyDef.userData.height=2*2*phsScale;*/
body=m_world.CreateBody(bodyDef);
body.CreateShape(boxDef);
body.SetMassFromShapes();
//addChild(bodyDef.userData);
}
// 下面在这个函数中创建三角形和不规则六边形, 左下角的点为 索引为0点 逆时针 第二个点为按逆时针方向旋转到的点,依次类推
private function createPolygons():void {
//创建三角形:
bodyDef = new b2BodyDef();
bodyDef.position.x=Math.random()*15+1;
bodyDef.position.y=Math.random();
//var crate_width:Number=1.5;
// var crate_height:Number=1.5;
var triangle:b2PolygonDef = new b2PolygonDef();
//boxDef.SetAsBox(crate_width, crate_height); 这里创建了点, 就相当于是创建SetAsBox ()只不过它是矩形
//创建点 :三角形有三个点:
triangle.vertexCount=3;
triangle.vertices[0].Set(0,-1);
triangle.vertices[1].Set(1,-1);
triangle.vertices[2].Set(-1,1);
triangle.density=1.0;
triangle.friction=0.5;
triangle.restitution=0.2;//设置角度。
bodyDef.angle = 0;// 设置body的角度
/*bodyDef.userData = new Box();
bodyDef.userData.width=crate_width*2*phsScale;
bodyDef.userData.height=crate_height*2*phsScale;*/
body=m_world.CreateBody(bodyDef);
body.CreateShape(triangle);
body.SetMassFromShapes();
// addChild(bodyDef.userData);
// 创建凸的六边形 多边形只能创建凸的 创建凹的将无交互作用
var polyDef = new b2PolygonDef();
polyDef.vertexCount = 6;
polyDef.vertices[0].Set(-1.5,-0.5);
polyDef.vertices[1].Set(0.5,-1);
polyDef.vertices[2].Set(1,-0.5);
polyDef.vertices[3].Set(1,1.5);
polyDef.vertices[4].Set(0.5,1.5);
polyDef.vertices[5].Set(-0.5,1.3);
polyDef.density = 1.0;
polyDef.friction = 0.3;
polyDef.restitution = 0.1;
bodyDef.position.Set(10,2);
bodyDef.angle = 0;
body = m_world.CreateBody(bodyDef);
body.CreateShape(polyDef);
body.SetMassFromShapes();
}
private function onDown(e:MouseEvent):void {
var body=getBodyAtMouse();
if (body) {
// body.WakeUp();
jointDef= new b2MouseJointDef();
jointDef.maxForce =5000;//此处力设大点
jointDef.target.Set(mouseX/phsScale,mouseY/phsScale);
// jointDef.frequencyHz=10;
// jointDef.dampingRatio=0.3;
//注意:body1 body2的对象不能搞错了
jointDef.body1=m_world.GetGroundBody();
jointDef.body2=body;
jointDef.timeStep=m_timeStep;
joint= m_world.CreateJoint(jointDef) as b2MouseJoint;
/*//添加向上的冲力
var impulse:b2Vec2=new b2Vec2(0,-80);
body.ApplyImpulse(impulse,body.GetWorldCenter());
if (Math.random()<0.382) {
body.ApplyTorque(450);
} else {
body.ApplyTorque(-450);
}*/
}
}
private function getBodyAtMouse():b2Body {
var body:b2Body;
var mouseBox2dX=stage.mouseX/phsScale;
var mouseBox2dY=stage.mouseY/phsScale;
var mousePosition:b2Vec2=new b2Vec2(mouseBox2dX,mouseBox2dY);
var AABB:b2AABB= new b2AABB();
AABB.lowerBound.Set(mouseBox2dX-0.001,mouseBox2dY-0.001);
AABB.upperBound.Set(mouseBox2dX+0.001,mouseBox2dY+0.001);
var shapes:Array= new Array();
var maxCount:uint=6;
var count:int=m_world.Query(AABB,shapes,maxCount);
for (var i:uint=0; i<count; i++) {
if (shapes[i].m_body.IsStatic()==false) {
var shape=shapes[i] as b2Shape;
var shapeXform=shape.m_body.GetXForm();
var inside:Boolean=shape.TestPoint(shapeXform,mousePosition);
if (inside) {
body=shape.m_body;
}
}
}
return body;
}
//释放内存
private function onUp(e:MouseEvent):void {
if(joint){
trace("destroy it!");
m_world.DestroyJoint(joint);
joint=null;
}
}
//直接copy这个模板
private function Update(e:Event):void {
m_world.Step(m_timeStep, m_iterations);
//更新目标点的作用位置
if(joint){
var targetPosition:b2Vec2= new b2Vec2(mouseX/phsScale,mouseY/phsScale);
joint.SetTarget(targetPosition);
}
// Go through body list and update sprite positions/rotations
for (var bb:b2Body = m_world.m_bodyList; bb; bb = bb.m_next) {
if (bb.m_userData is Sprite) {
bb.m_userData.x=bb.GetPosition().x*30;
bb.m_userData.y=bb.GetPosition().y*30;
bb.m_userData.rotation = bb.GetAngle() * (180/Math.PI);
}
}
}
}
}