box2d中创建不规则的形状

本文介绍如何在Box2D物理引擎中创建自定义多边形碰撞体,包括三角形和不规则六边形,并讲解了顶点设置、密度、摩擦力等参数配置。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

  }


 }
}

 

 

 

demo :  http://8781.kkgg.net/swf/CreateIrregularPolygon.swf

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值