Dec 4

BOX2D HelloWorld!!

Box2D
创造一个世界总有几个步骤,那么创造一个模拟物理的世界就从这里开始



一、创建一个世界
模拟范围、重力、是否休眠
var theWorld = new b2World(worldAABB, gravity, doSleep);

二、创建地面
物体通常由以下步骤来创建:
先刚体定义,设置位置(position),阻尼(damping)等,并且你可以用一个MC 赋给 刚体定义.userData
然后通过世界对象创建 刚体实体
刚体实体 = theWorld.CreateBody(刚体定义)
刚体实例被创造之后,还得用他的CreateShape方法去创建具有物理特性的正真实体
刚体实体.CreateShape(物理形状定义)
最好用刚体实体的SetMassFromShapes方法去命令物体通过形状去计算其自身的质量
刚体实体.SetMassFromShapes() 否则这个刚体实体就不具备质量 也就不受重力影响了

三、创建物体
跟创建地面一样
1.刚体定义
2.形状定义
3.创建刚体
4.把刚体addChild进场景

四、addEventListener(Event.ENTER_FRAME, Enter);
Box2D 中有一些数学代码构成的积分器(integrator),积分器在离散的时间点上模拟物理方程,它将
与游戏动画循环一同运行。所以我们需要为 Box2D 选取一个时间步,通常来说游戏物理引擎需要至少
60Hz 的速度,也就是 1/60 的时间步。你可以使用更大的时间步,但是你必须更加小心地为你的世界调
整定义。我们也不喜欢时间步变化得太大,所以不要把时间步关联到帧频(除非你真的必须这样做)。直截
了当地,这个就是时间步:
m_timeStep = 1.0 / 30.0;
除了积分器之外,Box2D 中还有约束求解器(constraint solver)。约束求解器用于解决模拟中的所有
约束,一次一个。单个的约束会被完美的求解,然而当我们求解一个约束的时候,我们就会稍微耽误另
一个。要得到良好的解,我们需要迭代所有约束多次。建议的 Box2D 迭代次数是 10 次。你可以按自己
的喜好去调整这个数,但要记得它是速度与质量之间的平衡。更少的迭代会增加性能并降低精度,同样
地,更多的迭代会减少性能但提高模拟质量

代码:

package  
{
  import Box2D.Collision.b2AABB;
  import Box2D.Collision.Shapes.b2CircleDef;
  import Box2D.Collision.Shapes.b2PolygonDef;
  import Box2D.Common.Math.b2Vec2;
  import Box2D.Dynamics.b2Body;
  import Box2D.Dynamics.b2BodyDef;
  import Box2D.Dynamics.b2World;
  import flash.display.Sprite;
  import flash.events.Event;
  
  /**
   * ...
   * @author Emment
   */
  public class HelloWorld extends Sprite
  {
    private var _world:b2World;
    private var isSleep:Boolean;
    private var _gravity:b2Vec2;
    
    private var _body:b2Body;
    private var _bodyDef:b2BodyDef;
    private var _boxDef:b2PolygonDef;
    private var _circleDef:b2CircleDef;
    
    public function HelloWorld() 
    {
      initWorld();
      initGround();
      initObj();
      initLister();
    }
    private function initWorld():void
    {
      var _b2AABB:b2AABB = new b2AABB();
        _b2AABB.lowerBound.Set( -100, -100);
        _b2AABB.upperBound.Set(100, 100);
      _gravity = new b2Vec2(0,9.8);
      isSleep = true;
      //创建世界
      _world = new b2World(_b2AABB, _gravity, isSleep);
    }
    private function initGround():void
    {
      _bodyDef = new b2BodyDef();
      _bodyDef.position.Set(0, 13.7);
      _bodyDef.angle = 0.02;
      _bodyDef.userData = new PhysGround();
      _bodyDef.userData.width = 30 * 2 * 30;
      _bodyDef.userData.height = 30 * 2 * 3; 
      _bodyDef.userData.alpha = 0;
      _boxDef = new b2PolygonDef();
      _boxDef.SetAsBox(30,3);
      _boxDef.density = 0;
      _boxDef.friction = 0.5;
      _body = _world.CreateBody(_bodyDef);
      _body.CreateShape(_boxDef);
      addChild(_bodyDef.userData);
      //挡板
      _bodyDef = new b2BodyDef();
      _bodyDef.position.Set(18.8, 0);
      _bodyDef.angle = 3.14/2;
      _bodyDef.userData = new PhysGround();
      _bodyDef.userData.width = 30 * 2 * 30;
      _bodyDef.userData.height = 30 * 2 * 1; 
      _bodyDef.userData.alpha = 0;
      _boxDef = new b2PolygonDef();
      _boxDef.SetAsBox(30,1);
      _boxDef.density = 0;
      _boxDef.friction = 0.5;
      _body = _world.CreateBody(_bodyDef);
      _body.CreateShape(_boxDef);
      addChild(_bodyDef.userData);
      
    }
    private function initObj():void
    {
      _bodyDef = new b2BodyDef();
      _bodyDef.position.Set(10, 1);
      _bodyDef.userData = new PhysCircle();
      _bodyDef.userData.width = 1 * 2 * 30; 
      _bodyDef.userData.height = 1 * 2 * 30; 
      _circleDef = new b2CircleDef();
      _circleDef.radius = 1;
      _circleDef.density = 1;
      _circleDef.friction = 0.5;
      _circleDef.restitution = 0.4;
      _body = _world.CreateBody(_bodyDef);
      _body.CreateShape(_circleDef);
      _body.SetMassFromShapes();
      addChild(_bodyDef.userData);
    }
    private function initLister():void
    {
      addEventListener(Event.ENTER_FRAME, enter);
    }
    private function enter(e:Event):void
    {
      _world.Step(1 / 30, 10);
      for (var bb:b2Body = _world.GetBodyList(); bb ; bb = bb.GetNext()){  
        if (bb.GetUserData() is Sprite){
          var _sprite:Sprite = bb.GetUserData() as Sprite;
          _sprite.x = bb.GetPosition().x *30 ;
          _sprite.y = bb.GetPosition().y *30;
          _sprite.rotation = bb.GetAngle() * (180/Math.PI);
        }
      }
    }
  }
  
}

tags:

to "BOX2D HelloWorld!!"

  1. Chris Says:

    如何才能贴图?

  2. Sunny Says:

    非常想知道你的鼠标是怎么拖拽是怎么加的~~
    期待更新~

  3. longxing Says:

    楼主好象没有把代码全部贴上来吧

  4. cruel Says:

    请问球的阴影是如何实现的?

Leave a Reply