Box2Dで作れる物体の形は,長方形だけではありません。他にも,円や多角形を作ることができます。また,それらを組み合わせた複雑な形も作ることができます。今回は,それらの形の作り方について説明します。
円を作るには
まずは円の作り方です。前回と似たような形で,マウスボタンを押した場所から離した場所までを半径とする円を作れるようなFlashを作ります。詳しくはサンプルをご覧ください。
これをいつも通り以下のコマンドでコンパイルします。
mxmlc -source-path=C:\lib\Box2DFlashAS3_2.0.0 DrawingCircle.as
生成されるFlashは以下のようなものになります。
全体の流れについて
基本的な流れは長方形を作るときと変わりません。マウスのボタンが押されてmouseDownHandlerが呼ばれたら,その場所をプロパティcircleCenterに記憶します。これは円の中心となります。
マウスのボタンが離されてmouseUpHandlerが呼ばれたら,まず円の中心からマウスボタンが離された場所までの距離,つまり円の半径を計算します。円の半径がある程度以上なら,その場所に円を作ります。作られた円は,長方形のときと同様に重力に従って落下します。
円を見ると,直感的にゴムボールなどをイメージする場合が多いと思います。そういった物体を落としたときにバウンドしないと少し違和感があるので,今回は反発係数を0.5に設定しました。
プログラムは,前回のTsumiki.asをベースに書き換えています。変更があるのはほとんどmouseUpHandlerの部分なので,そこに的を絞って説明します。
円の中心と半径を計算する
マウスのボタンが押されたら,その場所を円の中心とします。長方形のときと同様に,マウスボタンが押された座標の値をDRAW_SCALEで割って計算します。
var x:Number = circleCenter.x / DRAW_SCALE;
var y:Number = circleCenter.y / DRAW_SCALE;
円の半径については,図を参照しながら説明します。
円の中心(circleCenter.x,circleCenter.y)とマウスボタンが離された場所(event.stageX,event.stageY)の差をdx,dyとします。この値は,引き算をすることで簡単に求まります。引き算の結果はDRAW_SCALEで割り,物理エンジン内の単位に直しておきます。なおdxやdyがプラスかマイナスかはここでは問題になりません。
var dx:Number = (event.stageX - circleCenter.x) / DRAW_SCALE;
var dy:Number = (event.stageY - circleCenter.y) / DRAW_SCALE;
そして,これらの値から円の半径radiusを計算します。dxの二乗とdyの二乗を足し合わせ,Math.sqrtを使って平方根を計算しています。
var radius:Number = Math.sqrt(dx * dx + dy * dy);
b2CircleDefで円を作る
円の中心と半径が求まったので,物理エンジン内に円形の物体を作ります。今まではb2BodyDefとb2PolygonDefを使って物体を定義してきましたが,円の場合は後者のb2PolygonDefがb2CircleDefになります。
var bodyDef:b2BodyDef = new b2BodyDef();
bodyDef.position.Set(x, y);
var shapeDef:b2CircleDef = new b2CircleDef();
shapeDef.radius = radius;
shapeDef.density = 1; // 密度 [kg/m^2]
shapeDef.restitution = 0.5; // 反発係数、通常は0~1
b2CircleDefにはradiusというプロパティがあります。これは名前のとおり円の半径を表すプロパティです。その他のdensityやrestitutionはb2PolygonDefのときと同じです。
ちなみに,b2PolygonDefとb2CircleDefはb2ShapeDefクラスの派生クラスになっています。densityやrestitutionなどの基本的なパラメータは,b2ShapeDefクラスのプロパティになっています。
ちょっと早足でしたが,以上で円の作り方の説明を終わります。ポイントは,b2CircleDefクラスを使うということぐらいです。円は中心と半径を設定すればいいので,長方形のときよりも計算が簡単かと思います。


