[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 件のコメント:
コメントを投稿