flash on 2013-4-27

by alexnotkin
source code from nutsu  a great master of code
http://nutsu.com/blog/2008/082521_as_box2d_first.html

Box2Dなテスト

@author nutsu
♥0 | Line 115 | Modified 2013-05-02 05:50:01 | MIT License
play

ActionScript3 source code

/**
 * Copyright alexnotkin ( http://wonderfl.net/user/alexnotkin )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/a5Ec
 */

 //source code from nutsu  a great master of code
 // http://nutsu.com/blog/2008/082521_as_box2d_first.html
   package  

{

  import Box2D.Collision.b2AABB;

  import Box2D.Common.Math.b2Vec2;

  import Box2D.Dynamics.b2World;

  import Box2D.Dynamics.b2BodyDef;

  import Box2D.Collision.Shapes.b2PolygonDef;

  import Box2D.Collision.Shapes.b2CircleDef;

  import Box2D.Dynamics.b2Body;

  import Box2D.Collision.Shapes.b2Shape;

  import Box2D.Collision.Shapes.b2CircleShape;

  import Box2D.Dynamics.b2DebugDraw;

  import flash.geom.Rectangle;

  import flash.display.MovieClip;

  import flash.events.Event;

  import flash.events.MouseEvent;

  

  /**

  * Box2Dなテスト

  * @author nutsu

  */

  public class TestWorld extends MovieClip

  {

    private var world:b2World;

    

    private var WORLD_SCALE:Number = 100; // 100pixel/m

    private var VIEW_RECT:Rectangle;

    private var half_width:Number;

    private var half_height:Number;

    

    private var circles:Array;

    

    public function TestWorld() 

    {

      super();

      

      VIEW_RECT   = new Rectangle( 0, 0, stage.stageWidth/WORLD_SCALE, stage.stageHeight/WORLD_SCALE );

      half_width  = stage.stageWidth * 0.5;

      half_height = stage.stageHeight * 0.5;

      

      //動的オブジェクト用の配列 :b2CircleShape[]

      circles = [];

      

      //とりあえずワールドつくる

      initWorld();

      //静的なオブジェクト(四方壁)をつくる

      initObjects();

      //テストドローな設定

      initDraw();

      //とりあえず1こオブジェクトつくる

      addCircle( VIEW_RECT.width*0.5, VIEW_RECT.height*0.5 );

      

      addEventListener( Event.ENTER_FRAME, onEnterFrame );

      stage.addEventListener( MouseEvent.CLICK, onClick );

      

      stage.quality = "low";

    }

    

    private function initWorld():void

    {

      //物理計算エリア? お約束らしい

      var aabb:b2AABB = new b2AABB();

      aabb.lowerBound.Set( -1000, -1000 );

      aabb.upperBound.Set( 1000, 1000 );

      

      //重加速度。後でマウス位置で変えるので0にしとく

      var gravity:b2Vec2 = new b2Vec2( 0, 0 );

      

      //力が作用してないオブジェクトをスリープするか否か。今回はずっと動いてるのでfalse

      var dosleep:Boolean = false;

      

      //ワールドつくる

      world = new b2World( aabb, gravity, dosleep );

    }

    

    private function initObjects():void

    {

      //四方壁つくる

      //大きさの単位はメートルなそうな

      var wall_size:Number = 0.025;

      

      //ShapeなDef(形状決め)

      var wall_side_shape:b2PolygonDef = new b2PolygonDef();

      wall_side_shape.SetAsBox( wall_size, VIEW_RECT.height * 0.5 );

      wall_side_shape.density = 0; //静的な物体は0なそうな

      

      var wall_vt_shape:b2PolygonDef = new b2PolygonDef();

      wall_vt_shape.SetAsBox( VIEW_RECT.width*0.5, wall_size );

      wall_vt_shape.density = 0;

      

      //BodyなDef(位置決め)

      var wall_left:b2BodyDef   = new b2BodyDef();

      var wall_right:b2BodyDef  = new b2BodyDef();

      var wall_bottom:b2BodyDef = new b2BodyDef();

      var wall_top:b2BodyDef    = new b2BodyDef();

      

      //set position

      wall_left.position.Set(  wall_size, VIEW_RECT.height * 0.5 );

      wall_right.position.Set( VIEW_RECT.width - wall_size, VIEW_RECT.height * 0.5 );

      wall_bottom.position.Set( VIEW_RECT.width * 0.5 , VIEW_RECT.height - wall_size);

      wall_top.position.Set( VIEW_RECT.width*0.5 ,  wall_size);

      

      //worldに入れてく

      world.CreateBody( wall_left   ).CreateShape( wall_side_shape );

      world.CreateBody( wall_right  ).CreateShape( wall_side_shape );

      world.CreateBody( wall_bottom ).CreateShape( wall_vt_shape );

      world.CreateBody( wall_top    ).CreateShape( wall_vt_shape );

    }

    

    private function initDraw():void

    {

      //デバッグ用のドロー設定

      var debug_draw:b2DebugDraw = new b2DebugDraw();

      debug_draw.m_sprite        = this;

      debug_draw.m_drawScale     = WORLD_SCALE;

      debug_draw.m_fillAlpha     = 1;

      debug_draw.m_lineThickness = 0;

      debug_draw.m_drawFlags     = b2DebugDraw.e_shapeBit;

      world.SetDebugDraw( debug_draw );

    }

    

    private function addCircle( ax:Number, ay:Number ):void

    {

      //任意の位置にCircleオブジェクト追加してく

      //手順 ShapeなDef→BodyなDef→worldで実体をつくる感じ

      var s:b2CircleDef = new b2CircleDef();

      s.density = 1;

      s.restitution = 0.2;

      s.radius = 0.2;

      

      var b:b2BodyDef = new b2BodyDef();

      b.position.Set( ax, ay );

      

      var bb:b2Body  = world.CreateBody( b );

      var bs:b2Shape = bb.CreateShape( s );

      bb.SetMassFromShapes();

      

      //Shapeはあとでいじるので配列にいれとく

      bs.m_userData = Number(0);

      circles.push( b2CircleShape(bs) );

    }

    

    private function onClick( e:MouseEvent ):void

    {

      addCircle(mouseX/WORLD_SCALE, mouseY/WORLD_SCALE);

    }

    

    private function onEnterFrame( e:Event ):void

    {

      if ( world )

      {

        //マウス位置で重加速度変更

        world.m_gravity.x = -2 * (half_width - mouseX) / half_width;

        world.m_gravity.y = -2 * (half_height - mouseY) / half_height;

        

        //円をうにょうにょ

        for (var i:int = 0; i < circles.length ; i++) 

        {

          var bs:b2CircleShape = circles[i];

          bs.m_radius = 0.2 + Math.sin( bs.m_userData ) * 0.1;

          bs.m_userData += 0.05;

        }

        

        //計算 Step(計算時間,計算精度) きびっとしたいので計算時間を長めにとる

        world.Step(1/15, 4);

      }

    }

  }

}

Forked