ここまでの連載で、
そういった動きを実現するためには、
ジョイントの役割と種類
ジョイントは、
なお、
ディスタンスジョイント
ディスタンスジョイントは、
回転ジョイント
回転ジョイントは、
直動ジョイント
直動ジョイントは、
プーリージョイント
プーリージョイントは、
ギアジョイント
ギアジョイントは、
マウスジョイント
マウスジョイントは、
今回取り上げるジョイント
6種類もあるジョイントを全て説明すると紙面が足りなくなってしまうので、
まずは長方形と円を回転ジョイントで組み合わせて車を作ります。そして、
車のパーツを作る
車は、
ActionScriptのほうは起動直後にパーツが現れるようになっていますが、
まずは車体から
物理エンジンや床の設置についてはいつも通りなので、
車体を作る場所は、
前輪を作る
次は前輪
形については、
後輪を作る
最後は後輪
車体と車輪をジョイントでつなぐ
ここまででCarParts. なお、 ジョイントを作るには、 という順番で作業を進めます。車体と車輪をつなぐには、 jointDef変数を作ったら、 3番目の引数は、 次に、 motorSpeedは、 maxMotorTorqueは、 ここまで設定してきた値は、 ジョイントの定義が終わったので、 ここの書き方はCreateDynamicBodyなどを使って物体を作るときとほぼ同じですが、 後輪のジョイントを作るときには、 後輪の中心を軸に車体と後輪をつなぐように設定し、 ここまで書いてきたプログラムに必要なimport文を書き加えてコンパイルすると、 ちゃんと車ができましたね。四角や円だけでもそこそこ使えるBox2Dですが、 ただ車が走っているだけではつまらないので、 まず準備段階として、 このうち、 mouseJointDefとmouseJointは、 車を作り終わった直後のところに、 回転ジョイントのときと同じように、 targetには、 maxForceとtimeStepは、 ここまで書いて気づいたかもしれませんが、 マウス操作が絡んでくるので、 マウスボタンが押されたときに、 重要なのはマウスボタンが離されたときで、 最後に、 これで完成です。コンパイルすると以下のようなFlashができると思います。画面上部でマウスを適当にドラッグすると、 ここまで編集してきたソースを、 6種類あるジョイントの中から回転ジョイントとマウスジョイントを使い、 次回は脱DebugDrawをテーマに、b2RevolutionJointDefでつなぐ場所を決める
// ジョイントを定義するjointDef変数
var jointDef:b2RevoluteJointDef = new b2RevoluteJointDef();
// つながれる2つの物体と、つなぐ位置(前輪の中央)を使って、定義を初期化する
jointDef.Initialize(body, frontWheel, frontWheel.GetWorldCenter());
ジョイントの細かい設定
// 回転速度の設定(6秒で1回転ぐらい)
jointDef.motorSpeed = 1;
// トルクの設定(大きいほど坂道に強くなる)
jointDef.maxMotorTorque = 1;
// 車輪を回すようにする
jointDef.enableMotor = true;
定義からジョイントを作る
// 回転ジョイントを作る
var frontJoint:b2RevoluteJoint = b2RevoluteJoint(world.CreateJoint(jointDef));
後輪のジョイントを作る
// つながれる2つの物体と、つなぐ位置(後輪の中央)を使って、定義を初期化する
jointDef.Initialize(body, rearWheel, rearWheel.GetWorldCenter());
// 回転ジョイントを作る
var rearJoint:b2RevoluteJoint = b2RevoluteJoint(world.CreateJoint(jointDef));
マウスジョイントを使って車を持ち運ぶ
クラスにプロパティを追加する
// 物理エンジンの管理クラス
private var world:b2World; // ← この行までは最初からある
// 車体
private var body:b2Body;
// マウスジョイントの定義
private var mouseJointDef:b2MouseJointDef;
// マウスジョイント
private var mouseJoint:b2MouseJoint;
var body:b2BodyDef = world.CreateDynamicBody(bodyDef);
↓ 書き換える
body = world.CreateDynamicBody(bodyDef);
マウスジョイントを定義する
// マウスジョイントを定義する
mouseJointDef = new b2MouseJointDef();
// 片方のbodyにはワールド全体を設定する
mouseJointDef.body1 = world.GetGroundBody();
// もう片方には移動させたい物体(=車体)を設定する
mouseJointDef.body2 = body;
// 車体の中心座標を設定する
mouseJointDef.target = body.GetWorldCenter();
// マウスで引っ張られるときの力
mouseJointDef.maxForce = 5;
// シミュレーションの間隔
mouseJointDef.timeStep = 1 / 24;
マウスイベントのハンドラを追加する
stage.addEventListener(MouseEvent.MOUSE_MOVE, mouseMoveHandler);
stage.addEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler);
stage.addEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);
マウスジョイントを作る
private function mouseDownHandler(event:MouseEvent):void {
// マウスボタンが押されたら、マウスジョイントを作る
mouseJoint = b2MouseJoint(world.CreateJoint(mouseJointDef));
}
マウスジョイントを切り離す
private function mouseUpHandler(event:MouseEvent):void {
// マウスボタンが離されたら、マウスボタンを切り離す
world.DestroyJoint(mouseJoint);
mouseJoint = null;
}
マウスジョイントの位置を更新する
private function mouseMoveHandler(event:MouseEvent):void {
// mouseJointがnullでないときだけ処理を実行する
if (mouseJoint) {
// マウスが押された場所を物理エンジン内の座標系に変換する
var x:Number = event.stageX / DRAW_SCALE;
var y:Number = event.stageY / DRAW_SCALE;
// マウスジョイントのカーソル位置を更新
mouseJoint.SetTarget(new b2Vec2(x, y));
}
}
まとめ