Box2DFlashAS3 Study#2 「よく揺れる観覧車」

| コメント(0) | トラックバック(0)

このコンテンツをご覧いただくには「javascriptをON」「flash player9以上」が必須環境となります。 / RSSリーダーで読んでいる方は、本記事に移動してごらんください

Box2DFlashAS3 Study#1 「ぽとぽと落ちてくる」の続き。今回は「JOINT」の学習。とりいそぎ、デバッグモードで公開。Box2DFlashAS3をダウンロードするとおまけで付いてくるサンプルを参考にした。

ゴンドラの数に合わせて、ゴンドラの位置が自動的に決まるよう三角関数を使った。数学を学んでおいて、楽ができた。よかった。

package {

  import Box2D.Dynamics.*;
  import Box2D.Collision.*;
  import Box2D.Collision.Shapes.*;
  import Box2D.Dynamics.Joints.*;
  import Box2D.Dynamics.Contacts.*;
  import Box2D.Common.*;
  import Box2D.Common.Math.*;
  import General.Input;

  import flash.display.*;
  import flash.events.Event;

  public class FerrisWheel extends Sprite {

    //Box2D variables
    public var m_sprite:Sprite;
    public var m_world:b2World;
    public var m_iterations:int;
    public var m_timeStep:Number;
    public var m_physScale:Number;
    public var m_mouseJoint:b2MouseJoint;
    // world mouse position
    static public  var mouseXWorldPhys:Number;
    static public  var mouseYWorldPhys:Number;
    static public  var mouseXWorld:Number;
    static public  var mouseYWorld:Number;
    private var mousePVec:b2Vec2;
    // input
    public var m_input:Input;

    //constructor
    public function FerrisWheel() {

      {
        m_sprite = new Sprite();
        addChild(m_sprite);
        m_iterations=10;//計算精度
        m_timeStep=1 / 30;//1meter=30pixels
        m_physScale=30;
        m_input = new Input(m_sprite);
        mousePVec = new b2Vec2();
      };

      // make base world
      {
        var worldAABB:b2AABB = new b2AABB();
        worldAABB.lowerBound.Set(-1000.0, -1000.0);
        worldAABB.upperBound.Set(1000.0, 1000.0);
        var gravity:b2Vec2 = new b2Vec2(0.0, 10.0);//重力(x方向,y方向)
        var doSleep:Boolean = true;
        m_world = new b2World(worldAABB, gravity, doSleep);
      };

      // Def
      var bd:b2BodyDef;
      var circ:b2CircleDef = new b2CircleDef();
      var box:b2PolygonDef = new b2PolygonDef();
      var Djd:b2DistanceJointDef = new b2DistanceJointDef();
      var Rjd:b2RevoluteJointDef = new b2RevoluteJointDef();

      //------------------------------------------------------------
      // 観覧車
      //------------------------------------------------------------
      //回転軸
      var RotationAxisX:Number = 250;//回転軸のx座標
      var RotationAxisY:Number = 220;//回転軸のy座標
      circ.radius = 10.0 / m_physScale;
      circ.density = 1.0;
      circ.friction = 0.4;
      circ.restitution = 0.3;
      bd = new b2BodyDef();
      bd.position.Set(RotationAxisX / m_physScale, RotationAxisY / m_physScale);
      var RotationAxis:b2Body = m_world.CreateStaticBody(bd);
      RotationAxis.CreateShape(circ);
      RotationAxis.SetMassFromShapes();
      //ゴンドラまとめて生成
      var gNum:int=16;//ゴンドラの数
      for (var i:int = 0; i < gNum; i++) {
        //ぷらんぷらん点(ゴンドラをつり下げる点)
        circ.radius = 10.0 / m_physScale;
        circ.density = 0.2;
        bd = new b2BodyDef();
        var gR:Number=180;//回転軸からぷらんぷらん点までの距離
        var gX:Number=gR*Math.cos(i*360/gNum*Math.PI/180);//ぷらんぷらん点のx座標
        var gY:Number=-1*gR*Math.sin(i*360/gNum*Math.PI/180);//ぷらんぷらん点のy座標
        bd.position.Set((gX+RotationAxisX) / m_physScale, (gY+RotationAxisY) / m_physScale);
        var connect:b2Body = m_world.CreateDynamicBody(bd);
        connect.CreateShape(circ);
        connect.SetMassFromShapes();
        // ゴンドラ
        box.SetAsBox(15/ m_physScale, 20 / m_physScale);
        box.density = 0.01;
        box.friction = 0.4;
        box.restitution = 0.9;
        bd = new b2BodyDef();
        bd.position.Set((gX+RotationAxisX) / m_physScale, (gY+RotationAxisY+30) / m_physScale);
        var gondola:b2Body = m_world.CreateDynamicBody(bd);
        gondola.CreateShape(box);
        gondola.SetMassFromShapes();
        //------------------------------------------------------------
        // JOINT
        //------------------------------------------------------------
        //回転軸とぷらんぷらん点
        Rjd.enableMotor = true;
        Rjd.motorSpeed = 0.2;
        Rjd.maxMotorTorque = 10000;
        Rjd.Initialize(RotationAxis,connect,RotationAxis.GetPosition());
        m_world.CreateJoint(Rjd);
        //ぷらんぷらん点とゴンドラ
        Djd.Initialize(connect, gondola, connect.GetPosition(),new b2Vec2((gX+RotationAxisX) / m_physScale, (gY+RotationAxisY+30-20) / m_physScale));
        m_world.CreateJoint(Djd);
      }
      setDebug();
      this.addEventListener(Event.ENTER_FRAME, Update, false, 0, true);
    }
    //------------------------------------------------------------
    // debug mode
    //------------------------------------------------------------
    public function setDebug():void {

      var dbgDraw:b2DebugDraw = new b2DebugDraw();//デバッグオブジェクトを生成
      var dbgSprite:Sprite = new Sprite();//デバッグ用オブジェクトの表示用sprite
      addChild(dbgSprite);//表示用スプライトを表示
      dbgDraw.m_sprite = dbgSprite;//これはお決まり。
      dbgDraw.m_drawScale = m_physScale;//ここでm_physScaleと違う値を入れると思わぬ表示になってしまう。
      dbgDraw.m_fillAlpha = 0.5;//デバッグ用オブジェクトの透明度。表示されるオブジェクト全体に設定される。
      dbgDraw.m_lineThickness = 1;//デバッグ用オブジェクトのライン。
      dbgDraw.m_drawFlags = 0xFFFFFFFF;//デバッグ用オブジェクトの色指定。
      m_world.SetDebugDraw(dbgDraw);//Box2Dのworldに追加。

    }
    //------------------------------------------------------------
    //                                        update every frame
    //------------------------------------------------------------
    public function Update(e:Event):void {
      m_world.Step(m_timeStep,m_iterations);
      UpdateMouseWorld();
      MouseDrag();
      Input.update();
    }
    //------------------------------------------------------------
    //                                        Update mouseWorld
    //------------------------------------------------------------
    public function UpdateMouseWorld():void {

      mouseXWorldPhys = (Input.mouseX)/m_physScale;
      mouseYWorldPhys = (Input.mouseY)/m_physScale;

      mouseXWorld = (Input.mouseX);
      mouseYWorld = (Input.mouseY);

    }
    //------------------------------------------------------------
    //                                        Mouse Drag 
    //------------------------------------------------------------
    public function MouseDrag():void {
      // mouse press
      if (Input.mouseDown && !m_mouseJoint) {
        buttonMode = true;
        var body:b2Body = GetBodyAtMouse();

        if (body) {
          var md:b2MouseJointDef = new b2MouseJointDef();
          md.body1 = m_world.m_groundBody;
          md.body2 = body;
          md.target.Set(mouseXWorldPhys, mouseYWorldPhys);
          md.maxForce = 300.0 * body.m_mass;
          md.timeStep = m_timeStep;
          m_mouseJoint = m_world.CreateJoint(md) as b2MouseJoint;
          body.WakeUp();
        }
      }
      // mouse release
      if (!Input.mouseDown) {
        if (m_mouseJoint) {
          m_world.DestroyJoint(m_mouseJoint);
          m_mouseJoint = null;
        }
      }
      // mouse move
      if (m_mouseJoint) {
        var p2:b2Vec2 = new b2Vec2(mouseXWorldPhys, mouseYWorldPhys);
        m_mouseJoint.SetTarget(p2);
      }
    }
    //------------------------------------------------------------
    //                                        GetBodyAtMouse
    //------------------------------------------------------------

    public function GetBodyAtMouse(includeStatic:Boolean=false):b2Body {
      // Make a small box.
      mousePVec.Set(mouseXWorldPhys, mouseYWorldPhys);
      var aabb:b2AABB = new b2AABB();
      aabb.lowerBound.Set(mouseXWorldPhys - 0.001, mouseYWorldPhys - 0.001);
      aabb.upperBound.Set(mouseXWorldPhys + 0.001, mouseYWorldPhys + 0.001);

      // Query the world for overlapping shapes.
      var k_maxCount:int = 10;
      var shapes:Array = new Array();
      var count:int = m_world.Query(aabb, shapes, k_maxCount);
      var body:b2Body = null;
      for (var i:int = 0; i < count; ++i) {
        if (shapes[i].m_body.IsStatic() == false || includeStatic) {
          var tShape:b2Shape = shapes[i] as b2Shape;
          var inside:Boolean = tShape.TestPoint(tShape.m_body.GetXForm(), mousePVec);
          if (inside) {
            body = tShape.m_body;
            break;
          }
        }
      }
      return body;
    }
  }
}

トラックバック(0)

トラックバックURL: http://www.mathatelle.com/mt4/mt-tb.cgi/29

コメントする

最近のブログ記事

終わらない夏野菜2008
茄子 ピーマン パプリカ トウガラシ …
t=t%60; //OrdinaryDays
2002年に金津創作の森(メディアの森…
センサー
ちょうどぴったり3年前に、Yuちゃん…
メタマジックゲーム
メタマジック・ゲーム―科学と芸術のジグソ…
はんぺんが膨らむ、はんぺんキャンペーン!
土曜日。キム兄がベランダでBBQしたい…

twitter / mathatelle

ブログパーツ

人気のブログ記事