2019-07-08

[Flash] Box2DFlashAS3 (3)

[Flash] Box2DFlashAS3 を学習 (3)

Environment:

  • Adobe AIR SDK 22
  • Box2DFlashAS3 v2.0.2
  • FlashDevelop 5.2
  • Windows 7 64bit

[話者] 『Box2DでActionScript物理プログラミング 技術評論社』の記事を引き続き学ぶぞ。

Learn

  • 第2回 物理エンジンをセットアップし,箱を落とすFlashを作る
  • 第3回 マウスのドラッグ&ドロップで,好きなサイズの箱を作る
  • 第4回 いろいろな形の物体を作る
  • 第5回 ジョイントで物をつなぐ

をまとめてみた。

実Flash。操作可。マウスドラッグで出現物体の大きさを決める。シフトキーでスロー(5分の1)になる。Ctrlキーを押しているときはマウスで車を引き寄せる操作できる(車がステージ外の遠くに落下すると車は消滅し、Ctrlキー無効になる)

SourceCode

前回との差分。

@@ -5,2 +5,6 @@
    import Box2D.Common.Math.b2Vec2;
+   import Box2D.Dynamics.Joints.b2MouseJoint;
+   import Box2D.Dynamics.Joints.b2MouseJointDef;
+   import Box2D.Dynamics.Joints.b2RevoluteJoint;
+   import Box2D.Dynamics.Joints.b2RevoluteJointDef;
    import Box2D.Dynamics.b2Body;
@@ -17,2 +21,3 @@
    import flash.text.TextFormat;
+   import flash.ui.Keyboard;
     
@@ -32,2 +37,4 @@
        private var shp:Array = ['box', 'circle', 'triangle'];
+       private var mJntOpt:b2MouseJointDef = null;
+       private var mJnt:b2MouseJoint = null;
     
@@ -43,2 +50,3 @@
            stage.addEventListener(MouseEvent.MOUSE_UP, onMouseUp);
+           stage.addEventListener(MouseEvent.MOUSE_MOVE, onMouseMove);
            stage.addEventListener(KeyboardEvent.KEY_DOWN, onKeyDown);
@@ -55,8 +63,13 @@
            // remove objects out of world
-           var obj:b2Body = wld.GetBodyList();
-           while (obj) {
-               if (obj.GetWorldCenter().y * PIXELS_PER_METER > 1000) {
-                   wld.DestroyBody(obj);
+           for (var i:int = 0; i < items.length; i++) {
+               if ( ! items[i]) continue;
+               if (items[i].GetWorldCenter().y * PIXELS_PER_METER > 1000) {
+                   wld.DestroyBody(items[i]);
+                   items[i] = null;
+                   if (i >= 0 && i <= 2) {
+                       // destory car
+                       mJntOpt = null;
+                       mJnt = null;
+                   }
                }
-               obj = obj.GetNext();
            }
@@ -81,4 +94,21 @@
        
+       private function workMouseJoint():void {
+           if ( ! mJnt) return;
+           mJnt.SetTarget(new b2Vec2(
+               stage.mouseX / PIXELS_PER_METER,
+               stage.mouseY / PIXELS_PER_METER
+           ));
+       }
+       
+       private function onMouseMove(e:MouseEvent):void {
+           if (mJnt) workMouseJoint();
+       }
+       
        private function onKeyUP(e:KeyboardEvent):void {
            wldfps = 30;
+           if (e.keyCode == Keyboard.SHIFT && mJntOpt) mJntOpt.timeStep = 1 / wldfps;
+           if (e.keyCode == Keyboard.CONTROL && mJnt) {
+               wld.DestroyJoint(mJnt);
+               mJnt = null;
+           }
        }
@@ -86,3 +116,12 @@
        private function onKeyDown(e:KeyboardEvent):void {
-           if (e.shiftKey) wldfps = 150;  // 5 times slower
+           if (e.shiftKey) {
+               wldfps = 150;  // 5 times slower
+               if (mJntOpt) mJntOpt.timeStep = 1 / wldfps;
+           }
+           if (e.ctrlKey) {
+               if ( ! mJntOpt) return; // <- car is destroyed
+               if ( ! mJnt) mJnt = b2MouseJoint(wld.CreateJoint(mJntOpt));
+                   // when just pushing [Ctrl], mouse joint exists
+               workMouseJoint();
+           }
        }
@@ -178,2 +217,49 @@
 
+           // setup car
+           //car body
+           var objPos_m:b2BodyDef = new b2BodyDef();
+           objPos_m.position.Set(1.0, 2);          //object position (unit:meter)
+               //1.0m from top, 2m from left
+           items.push(wld.CreateBody(objPos_m));
+           var objShp_m:b2PolygonDef = new b2PolygonDef(); //object shape
+           objShp_m.SetAsBox(0.4, 0.1);            // width 40cm*2, height 10cm*2
+           objShp_m.density = 1.0;
+           var cur:int = 0;                        // current item
+           cur = items.length - 1;
+           items[cur].CreateShape(objShp_m);
+           items[cur].SetMassFromShapes();         // set weight
+           //car wheel front
+           objPos_m.position.Set(1.3, 2);
+           items.push(wld.CreateBody(objPos_m));
+           var ccShp_m:b2CircleDef = new b2CircleDef();  // circle shape
+           ccShp_m.radius = 0.15;
+           ccShp_m.density = 1.0;
+           cur = items.length - 1;                 // current item
+           items[cur].CreateShape(ccShp_m);
+           items[cur].SetMassFromShapes();         // set weight
+           //car wheel rear
+           objPos_m.position.Set(0.7, 2);
+           items.push(wld.CreateBody(objPos_m));
+           cur = items.length - 1;                 // current item
+           items[cur].CreateShape(ccShp_m);
+           items[cur].SetMassFromShapes();         // set weight
+           var jntOpt:b2RevoluteJointDef = new b2RevoluteJointDef();
+           jntOpt.Initialize(items[0], items[1], items[1].GetWorldCenter());
+               // items[0] -> car, items[1] -> wheel front
+           jntOpt.motorSpeed = 3.14 * 2 / 6;       // 360degree -> 6sec
+           jntOpt.maxMotorTorque = 2.0;            // (unit:newton meter)
+           jntOpt.enableMotor = true;
+           var jntFnt:b2RevoluteJoint = b2RevoluteJoint(wld.CreateJoint(jntOpt));
+               //joint front : type cast b2Joint -> b2RevoluteJoint
+           jntOpt.Initialize(items[0], items[2], items[2].GetWorldCenter());
+           var jntRr:b2RevoluteJoint = b2RevoluteJoint(wld.CreateJoint(jntOpt));  //joint rear
+
+           // mouse joint
+           mJntOpt = new b2MouseJointDef();  // mouse joint option
+           mJntOpt.body1 = wld.GetGroundBody();
+           mJntOpt.body2 = items[0];         //car
+           mJntOpt.target = items[0].GetWorldCenter();
+           mJntOpt.maxForce = 5;
+           mJntOpt.timeStep = 1 / wldfps;
+           
            // box2d draw
@@ -184,3 +270,3 @@
            dd_m.m_lineThickness = 1;           // line width 1pixel
-           dd_m.m_drawFlags = b2DebugDraw.e_shapeBit;
+           dd_m.m_drawFlags = b2DebugDraw.e_shapeBit | b2DebugDraw.e_jointBit;
            wld.SetDebugDraw(dd_m);

0 件のコメント:

コメントを投稿

人気記事