Box2DFlashAS3 Study#1 「ぽとぽと落ちてくる」

Box2DFlashAS3学習中の続き。

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

内容的にはいつもの内輪ネタです。すいません!

以下のブログ記事を参考にしました。

ソース

at sonicさんのソースをベースに、FICCさんのソースをv2.0.0に対応させながら追記したという感じです。3人の写真はFlashのライブラリに入れて、先日のProgressionワークショップで教えてもらった技(→リンケージ一括設定を使ってみる | ra66it.net)で設定しておきます。

Tora&Demuが落ちてくる間隔の設定はTimerクラスを使うのがAS3っぽいのかなと思ったけど、それを学習してる時間がなかったのでとりあえずエンターフレーム毎に数える方法でやりきってしまいました。ほかにもツッコミどころ満載だと思いますが・・・、改善点があったらご指摘いただけるとうれしいです!

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 ShinqooBox2D 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 ShinqooBox2D() {
      // set variables
      {
        m_sprite = new Sprite();
        addChild(m_sprite);
        m_iterations=10;
        m_timeStep=1 / 30;
        m_physScale=30;// =1m (1meter=30pixels)
        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 g:Number=9.80665;//標準重力加速度g = 9.80665 m/s2
        var gravity:b2Vec2 = new b2Vec2(0.0, g);
        var doSleep:Boolean = true;
        m_world = new b2World(worldAABB, gravity, doSleep);
      };

      // floor
      {
        var floorWidth:Number=500;
        var floorHeight:Number=40;
        var floorDef:b2PolygonDef = new b2PolygonDef();
        floorDef.SetAsBox(floorWidth/2/m_physScale,floorHeight/2/m_physScale);
        floorDef.density = 100.0;
        floorDef.friction = 1.0/m_physScale;

        var floorBD:b2BodyDef = new b2BodyDef();
        floorBD.position.Set(stage.stageWidth/2/m_physScale, (stage.stageHeight+20)/m_physScale);

        var floor = m_world.CreateStaticBody(floorBD);
        floor.CreateShape(floorDef);
        floor.SetMassFromShapes();
      };
      //setDebug();
      this.addEventListener(Event.ENTER_FRAME, Update, false, 0, true);
    }
    //add Hasecame
    private function addHasecame():void {
      //幅と高さ
      var hasecameWidth:Number=415;
      var hasecameHeight:Number=260;
      //顔と体
      var polygonDef1:b2PolygonDef = new b2PolygonDef();
      polygonDef1.vertexCount = 4;
      polygonDef1.vertices[0].Set(-150/m_physScale, -35/m_physScale);
      polygonDef1.vertices[1].Set(165/m_physScale, -35/m_physScale);
      polygonDef1.vertices[2].Set(220/m_physScale, 115/m_physScale);
      polygonDef1.vertices[3].Set(-230/m_physScale, 115/m_physScale);
      polygonDef1.density = 80.0/m_physScale;
      polygonDef1.friction = 28.0/m_physScale;
      polygonDef1.restitution = 1.0/m_physScale;
      //UFO部分
      var polygonDef2:b2PolygonDef = new b2PolygonDef();
      polygonDef2.vertexCount = 4;
      polygonDef2.vertices[0].Set(-30/m_physScale, -120/m_physScale);
      polygonDef2.vertices[1].Set(10/m_physScale, -130/m_physScale);
      polygonDef2.vertices[2].Set(85/m_physScale, -35/m_physScale);
      polygonDef2.vertices[3].Set(-40/m_physScale, -35/m_physScale);
      polygonDef2.density = 80.0/m_physScale;
      polygonDef2.friction = 10.0/m_physScale;
      polygonDef2.restitution = 1.0/m_physScale;

      var polygonBD:b2BodyDef = new b2BodyDef();
      polygonBD.position.Set(250/m_physScale,-800/m_physScale);

      polygonBD.userData = new Hasecame();
      polygonBD.userData.width = hasecameWidth;
      polygonBD.userData.height = hasecameHeight;

      m_sprite.addChild(polygonBD.userData);

      var hasecame:b2Body = m_world.CreateDynamicBody(polygonBD);
      hasecame.CreateShape(polygonDef1);
      hasecame.CreateShape(polygonDef2);
      hasecame.SetMassFromShapes();

    }
    //add Tora
    private function addTora():void {
      var CircleRadius:Number=35;
      var circleDef:b2CircleDef = new b2CircleDef();
      circleDef.radius = CircleRadius/m_physScale;
      circleDef.density = 15.0/m_physScale;
      circleDef.friction = 15.0/m_physScale;
      circleDef.restitution = 25.0/m_physScale;//Toraはよく跳ねる

      var circleBD:b2BodyDef = new b2BodyDef();
      circleBD.position.Set((Math.random()*100+300)/m_physScale,-100/m_physScale);

      circleBD.userData = new Tora();
      circleBD.userData.width = CircleRadius*2;
      circleBD.userData.height = CircleRadius*2;

      m_sprite.addChild(circleBD.userData);

      var circle:b2Body = m_world.CreateDynamicBody(circleBD);
      circle.CreateShape(circleDef);
      circle.SetMassFromShapes();
    }
    //add Demu
    private function addDemu():void {
      var CircleRadius:Number=35;
      var circleDef:b2CircleDef = new b2CircleDef();
      circleDef.radius = CircleRadius/m_physScale;
      circleDef.density = 20.0/m_physScale;
      circleDef.friction = 20.0/m_physScale;
      circleDef.restitution = 5.0/m_physScale;//Demuはあまり跳ねない

      var circleBD:b2BodyDef = new b2BodyDef();
      circleBD.position.Set((Math.random()*100+100)/m_physScale,-100/m_physScale);

      circleBD.userData = new Demu();
      circleBD.userData.width = CircleRadius*2+10;
      circleBD.userData.height = CircleRadius*2+10;

      m_sprite.addChild(circleBD.userData);

      var circle:b2Body = m_world.CreateDynamicBody(circleBD);
      circle.CreateShape(circleDef);
      circle.SetMassFromShapes();
    }
    //------------------------------------------------------------
    // debug mode
    //------------------------------------------------------------
    public function setDebug():void {

      var dbgDraw:b2DebugDraw = new b2DebugDraw();
      var dbgSprite:Sprite = new Sprite();
      addChild(dbgSprite);
      dbgDraw.m_sprite = dbgSprite;
      dbgDraw.m_drawScale = m_physScale;
      dbgDraw.m_fillAlpha = 0.5;
      dbgDraw.m_lineThickness = 1;
      dbgDraw.m_drawFlags = 0xFFFFFFFF;
      m_world.SetDebugDraw(dbgDraw);

    }
    //------------------------------------------------------------
    //                                        update every frame
    //------------------------------------------------------------
    private var count1:int=0;//ToraとDemu用カウンター
    private var count2:int=0;//Hasecame用カンター
    public function Update(e:Event):void {
      m_world.Step(m_timeStep,m_iterations);
      UpdateMouseWorld();
      MouseDrag();
      Input.update();

      count1++;
      count2++;
      if (count1>=10) {//カウント10毎にToraとDemuを振らせる
        count1=0;
        addTora();
        addDemu();
      }
      if (count2>=300) {//カウント300でHasecame降臨
        addHasecame();
        count2=-3000;//忘れたころに振ってくるように
      }
      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 * m_physScale;
          bb.m_userData.y = bb.GetPosition().y * m_physScale;
          bb.m_userData.rotation = bb.GetAngle() * (180/Math.PI);
          if (bb.m_userData.x<-250 || bb.m_userData.x>750) {//画面外に出たら削除(このような処理でいいのか自信がない・・・)
            m_world.DestroyBody(bb);
            m_sprite.removeChild(bb.m_userData);
          }
        }
      }
    }
    //------------------------------------------------------------
    //                                        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;
    }
  }
}

trackback

trackback URI: http://www.mathatelle.com/mt/mt-tb.cgi/795

comment(6)

おもしろすぎなんですけど・・・

おおーっ、これって決まったパターンの繰り返しってわけじゃないのね。

へぇ~っ、面白れ~な~って見てたら突然ハセカメが!

その後かなり見てたけどハセカメは出てこない。

レアキャラなんだね、ハセカメは。

めっちゃおもろいやないかぁ〜〜(チン!)

今時ブラクラかと思いました…

あ、次は俺も使ってほしいっす!

すごい!

って、うちの椅子やんw

post comment

(いままで、ここでコメントしたことがないときは、コメントを表示する前にこのブログのオーナーの承認が必要になることがあります。承認されるまではコメントは表示されません。そのときはしばらく待ってください。)

about

mathatelle
図書館の本の質感が好きです。時間の経過による黄ばみや不特定多数の人たちが触ることによる破れ・汚れ・シミなど…。

» profile

» twitter

feed

  • Mathatelle.comのFeed
  • Add to livedoor
  • Add to google

analysis

  • 携帯アクセス解析

あわせて読みたいブログパーツ

Apple iPod nano 8GB シルバー MA980J/A