zoukankan      html  css  js  c++  java
  • [box2d] Box2d学习笔记 Class.01 2012.10.5

    怎么样创建一个box2d的世界。


    step.1 :  

    创建一个世界。 

    var world:b2World = new World( new b2Vec2(0,10) , true );

    var1 : (gravity:b2Vec2) , 即重力。

    var2 : (doSleep:Boolean) , 用来管理世界中的物体是否可以休眠。

    step.2 :

    创建一个地面,把地面看成一个巨大的四边形刚体。所以我们现在要做的也相对于创建一个四边形刚体。

    首先创建一个地面的definition,即b2BodyDef。
    var _groundDef:b2BodyDef = new b2BodyDef(); 

    _groundDef.position.Set(SWF_HALF_WIDTH/PIXELS_TO_METER,(SWF_HEIGHT-20)/PIXELS_TO_METER);

    _groundDef.type = b2Body.b2_staticBody;

    b2BodyDef是用来存放刚体在这个世界中的所有数据。

    这里要注意一下box2d的特性,1:所有object的注册点都在中心。2:box2d中的单位是米。

    所以如果我们想将地面放置在舞台底部往上20个像素的地方。我们需要这样处理

     _groundDef.position.Set(SWF_HALF_WIDTH/PIXELS_TO_METER,(SWF_HEIGHT-20)/PIXELS_TO_METER);

    其中SWF_HALF_WIDTH即舞台宽度的一半,SWF_HEIGHT即舞台高度,PIXEL_TO_METER是一个比例尺,用来描述多少个像素对应1米(一般是30)。

    type是刚体类型。分为三种:staticBody , kinematicBody , dynamicBody 。由于地面是静止的刚体,所以我们给他设置为staticBody。

    至于kinematicBody和dynamicBody的区别我们以后再研究。

    然后创建地面刚体,即b2Body。

    var _groundBody:b2Body = _world.CreateBody(_groundDef);

    b2Body就是刚体啦。

    这里我们可以注意到,box2d采取的是工厂模式。即通过world完成所有创建刚体的工作。

    接着我们需要创建这个刚体的形状,这里我们使用b2PolygonShape。当然还有一些其他的形状,我们以后再去了解。

    var _groundBox = new b2PolygonShape();
    _groundBox.SetAsBox(SWF_HALF_WIDTH/PIXELS_TO_METER,20/PIXELS_TO_METER);

    b2PolygonShape就是这个刚体的形状啦。

    通常要创建四边形的话会用到SetAsBox()或者SetAsOrientedBox(),其中后者可以指定注册点和角度。

    另外需要注意的是,在这个方法中传递的宽度值和高度值都是半宽和半高。当然还需要转换到以米为单位。

    我们刚才创建的形状只是这个刚体的definition的一部分。最终我们需要创建的是我们这个地面刚体的definition。

    var _groundFixtureDef:b2FixtureDef = new b2FixtureDef();
    _groundFixtureDef.shape = _groundBox;
    _groundFixtureDef.density = 1;
    _groundFixtureDef.friction = 1;
    _groundFixtureDef.restitution = 0;
                
    _groundBody.CreateFixture(_groundFixtureDef);

    b2FixtureDef与之前的b2BodyDef的区别在于。

    b2BodyDef是用来存放刚体在世界中的数据,比如position(x,y) , angle 等等属性。

    b2FixtureDef则是用来存放刚体自身的数据,比如shape(polygonShape,等等),density,friction等等属性。


    这样我们就已经完成了创建地面刚体的整个过程。 

    接下来我们需要让他们动起来。


    step.3:

    stage.addEventListener(Event.ENTER_FRAME, update);

    private function update(e:Event):void
    {
      var timeStep:Number = 1 / 30;
      var velocityIterations:int = 6;
      var positionIterations:int = 2;
               
      _world.Step(timeStep,velocityIterations,positionIterations);
      _world.ClearForces();
    }

    我们通过b2World的step方法来刷新整个世界。

    step方法要传递三个参数,timeStep,velocityIterations, positionIterations。

    timeStep,时步。通常建议设置为1/60,这样的话你的fps最好也设置到60。但是我发现更好的办法就是把timeStep设置为fps的倒数即可。如果你的fps是30,那么就设置为1/30。

    velocityIterations,速度迭代

    positionIterations,位置迭代

    这两个值通常建议设置为10,更低的迭代值会让你牺牲一些准确性,相反的为你的程序提升一部分性能。


    另外在box2d version2.1中我们需要清除力。

    _world.ClearForces();

    step.4:

    现在我们尝试在空中放置一个小小的刚体让他自由下落。

    这跟我们刚才创建地面刚体的做法基本上一致,唯一不同的是需要把刚体的种类设置为dynamicBody。 

    所以我们把创建四边形刚体的所有步骤集合在一个方法内。方便反复调用。

    createBox(new Point(SWF_HALF_WIDTH, 4), 30, 30, true, 1, 0.3);       

    private function createBox(position:Point,hw:Number,hh:Number,isDynamic:Boolean,density:Number=0,friction:Number=0,restitution:Number=0):void
    {
      var bodyDef:b2BodyDef = new b2BodyDef();
      if( isDynamic )
      {
        bodyDef.type = b2Body.b2_kinematicBody.b2_dynamicBody;
      }
      else
      {
        bodyDef.type = b2Body.b2_staticBody;
      }
      bodyDef.position.Set(position.x/PIXELS_TO_METER,position.y/PIXELS_TO_METER);          
      var body:b2Body = _world.CreateBody(bodyDef);
      var shape:b2PolygonShape = new b2PolygonShape();
      shape.SetAsBox(hw/PIXELS_TO_METER,hh/PIXELS_TO_METER);
      var fixtureDef:b2FixtureDef = new b2FixtureDef();
      fixtureDef.shape = shape;
      fixtureDef.density = density;
      fixtureDef.friction = friction;
      fixtureDef.restitution = restitution;
      body.CreateFixture(fixtureDef);


    同时把刚才创建地面刚体的过程通过我们写好的方法来实现。

    createBox(new Point(SWF_HALF_WIDTH, SWF_HEIGHT - 20), SWF_HALF_WIDTH, 20, false, 1, 1);


    这样我们基本上已经完成了一个世界的搭建。

    可是当我们编译的时候却看不到任何东西。

    什么情况!!

    step.5 :

    不要急,原来我们刚才创建的世界只是一个虚拟的世界。我们并没有给他付于实质性的ui,所以我们压根什么都看不见。

    我们现在没有ui,那该怎么办呢?

    没关系,box2d已经提供给我们一个debug模式,可以让我们在没有ui的时候看到我们的世界。

    private function createDebug():void
    {
      _debugSprite = new Sprite();
      addChild(_debugSprite);
                
      _debugDraw = new b2DebugDraw();
      _debugDraw.SetSprite(_debugSprite);
      _debugDraw.SetDrawScale(PIXELS_TO_METER);
      _debugDraw.SetLineThickness(1);
      _debugDraw.SetAlpha(1);
      _debugDraw.SetFillAlpha(0.4);
      _debugDraw.SetFlags(b2DebugDraw.e_shapeBit);
      _world.SetDebugDraw(_debugDraw);
    }

    b2DebugDraw中有一些属性可以自定义,来改变debug模式的外观,这个看个人喜好就行啦。

    flag可以有以下几种选择。如果你想复用的话,这样即可:  b2DebugDraw.e_aabbBit | b2DebugDraw.e_jointBit 

    b2DebugDraw.e_aabbBit :表示显示刚体的边界盒

    b2DebugDraw.e_jointBit :表示显示刚体相连时的节点和连线

    b2DebugDraw.e_obbBit :显示凸多边形的边界,不显示圆的边界

    b2DebugDraw.e_pairBit:draw broad-phase pairs

    b2DebugDraw.e_coreShapeBit:draw core (TOI) shapes

    b2DebugDraw.e_shapeBit:显示刚体的形状,不管是何种形状

    b2DebugDraw.e_centerOfMassBit:显示重心

    另外还需要在帧监听中添加语句

    _world.DrawDebugData(); 


    编译一下。 

    OK,大功告成~

    附源码:

      1 package
      2 {
      3     import Box2D.Collision.Shapes.b2PolygonShape;
      4     import Box2D.Common.Math.b2Vec2;
      5     import Box2D.Dynamics.b2Body;
      6     import Box2D.Dynamics.b2BodyDef;
      7     import Box2D.Dynamics.b2DebugDraw;
      8     import Box2D.Dynamics.b2FixtureDef;
      9     import Box2D.Dynamics.b2World;
     10     
     11     import flash.display.Sprite;
     12     import flash.events.Event;
     13     import flash.geom.Point;
     14     
     15     [SWF(frameRate=60,width=800,height=600)]
     16     public class Box2dClass_1 extends Sprite
     17     {
     18         private const PIXELS_TO_METER:int = 30;
     19         private const SWF_WIDTH:int = 800;
     20         private const SWF_HEIGHT:int = 600; 
     21         private const SWF_HALF_WIDTH:int = SWF_WIDTH>>1;
     22         private const SWF_HALF_HEIGHT:int = SWF_HEIGHT>>1;
     23         
     24         private var _world:b2World;
     25         private var _groundDef:b2BodyDef;
     26         private var _groundBody:b2Body;
     27         private var _groundBox:b2PolygonShape;
     28         private var _groundFixtureDef:b2FixtureDef;
     29         private var _debugSprite:Sprite;
     30         private var _debugDraw:b2DebugDraw;
     31         
     32         public function Box2dClass_1()
     33         {
     34             stage.color = 0x333333;
     35             createWorld();
     36             createGround();
     38             createBox(new Point(SWF_HALF_WIDTH, 4), 10, 10, true, 1, 0.3);
     39             createDebug();
     40             stage.addEventListener(Event.ENTER_FRAME, update);
     41         }
     42             
     43         private function createWorld():void
     44         {
     45             _world = new b2World(new b2Vec2(0,10),true );    
     46         }
     47         
     48         private function createDebug():void
     49         {
     50             _debugSprite = new Sprite();
     51             addChild(_debugSprite);
     52             
     53             _debugDraw = new b2DebugDraw();
     54             _debugDraw.SetSprite(_debugSprite);
     55             _debugDraw.SetDrawScale(PIXELS_TO_METER);
     56             _debugDraw.SetLineThickness(1);
     57             _debugDraw.SetAlpha(1);
     58             _debugDraw.SetFillAlpha(0.4);
     59             _debugDraw.SetFlags(b2DebugDraw.e_shapeBit);
     60             _world.SetDebugDraw(_debugDraw);
     61         }
     62         
     63         private function createGround():void
     64         {
     65             _groundDef = new b2BodyDef();
     66             _groundDef.position.Set(SWF_HALF_WIDTH/PIXELS_TO_METER,(SWF_HEIGHT-20)/PIXELS_TO_METER);
     67             _groundDef.type = b2Body.b2_staticBody;
     68             
     69             _groundBody = _world.CreateBody(_groundDef); 
     70             
     71             _groundBox = new b2PolygonShape();
     72             _groundBox.SetAsBox(SWF_HALF_WIDTH/PIXELS_TO_METER,20/PIXELS_TO_METER);
     73             
     74             _groundFixtureDef = new b2FixtureDef();
     75             _groundFixtureDef.shape = _groundBox;
     76             _groundFixtureDef.density = 0;
     77             _groundFixtureDef.friction = 0;
     78             _groundFixtureDef.restitution = 0;
     79             
     80             _groundBody.CreateFixture(_groundFixtureDef);
     81         }
     82         
     83         private function createBox(position:Point,hw:Number,hh:Number,isDynamic:Boolean,density:Number=0,friction:Number=0,restitution:Number=0):void
     84         {
     85             var bodyDef:b2BodyDef = new b2BodyDef();
     86             if( isDynamic )
     87             {
     88                 bodyDef.type = b2Body.b2_dynamicBody;
     89             }
     90             else
     91             {
     92                 bodyDef.type = b2Body.b2_staticBody;
     93             }
     94             bodyDef.position.Set(position.x/PIXELS_TO_METER,position.y/PIXELS_TO_METER);
     95             
     96             var body:b2Body = _world.CreateBody(bodyDef);
     97             
     98             var shape:b2PolygonShape = new b2PolygonShape();
     99             shape.SetAsBox(hw/PIXELS_TO_METER,hh/PIXELS_TO_METER);
    100             
    101             var fixtureDef:b2FixtureDef = new b2FixtureDef();
    102             fixtureDef.shape = shape;
    103             fixtureDef.density = density;
    104             fixtureDef.friction = friction;
    105             fixtureDef.restitution = restitution;
    106             
    107             body.CreateFixture(fixtureDef);
    108             
    109         }
    110         
    111         protected function update(event:Event):void
    112         {
    113             var timeStep:Number = 1 / 30;
    114             var velocityIterations:int = 6;
    115             var positionIterations:int = 2;
    116             
    117             _world.Step(timeStep,velocityIterations,positionIterations);
    118             _world.ClearForces();
    119             _world.DrawDebugData();
    120         }
    121     }
    122 }

    另附上box2d结构图一枚: 

     

  • 相关阅读:
    Powershell数据处理
    Powershell About Active Directory Group Membership of a domain user
    Powershell About Active Directory Server
    Oracle Schema Objects——Tables——TableStorage
    Oracle Schema Objects——Tables——TableType
    English Grammar
    Oracle Database Documentation
    Oracle Schema Objects——Tables——Oracle Data Types
    Oracle Schema Objects——Tables——Overview of Tables
    What is Grammar?
  • 原文地址:https://www.cnblogs.com/Memo/p/2712400.html
Copyright © 2011-2022 走看看