◆「物体」について
Box2Dでシミュレーションに使用するオブジェクトを、本記事では「物体」と呼びます。
物体には、動くことのない固定されたものと何らかの力を受けて動くものがあります。本記事では固定された物体を「静体」、動ける物体を「動体」と呼びます。
物体は静体・動体ともb2Bodyクラスのオブジェクトです。
b2Bodyオブジェクトを生成するには、b2BodyDefオブジェクトが必要になります。加えて、形状を定義するためにb2ShapeDefオブジェクト(※1)も必要になります。
これらのオブジェクトでは次のような設定を行えます。
b2BodyDefオブジェクト:
- 物体の初期位置
- 初期回転角度
- 速度の減衰率
- 回転速度の減衰率ほか
b2ShapeDefオブジェクト:
- 形状(※2)
- 密度(質量に関係)
- 摩擦係数
- 反発係数ほか
b2BodyDefオブジェクトを元に物体を表すb2Bodyオブジェクトを作成し、その後b2ShapeDefオブジェクトから形状を表すb2Shapeオブジェクトを作成します。
今回は先にb2BodyDefオブジェクトとb2ShapeDefオブジェクトを生成し、その後b2Bodyオブジェクトの生成と形状の作成を行っていきます。
以下、実際に長方形の静体を作成してみます。この長方形は他の物体を乗せる床にあたるものになります。
◆静体の作成
後述しますが、Box2Dの2.0.2では物体はデフォルトでは静体として作成されます。そして静体にプラスαの情報を加えたものが動体となります。なのでまず静体の作成方法をしっかり理解しておく必要があります。
・b2BodyDefオブジェクトの生成
b2BodyDefオブジェクトの生成にはb2BodyDefコンストラクタを実行します。b2BodyDefオブジェクトには静体の座標位置を指定します。
座標位置の指定にはb2BodyDef.positionプロパティを使用します。
【コンストラクタ】b2BodyDef()-b2BodyDefオブジェクトの生成
【P】b2BodyDef.position:b2Vec2-物体の初期座標位置
位置を指定するにあたって、ムービークリップインスタンスであればシンボルに設定した基準点の座標を指定することになりますが、Box2Dで扱う物体の場合はどの位置を基準とするのでしょうか。
基本的にはその物体の形状の中心になります。つまり、円や長方形であれば明白に中心の位置が基準となり、その他の多角形の場合は頂点のX、Y各座標位置の平均の位置が基準となります。
今回のスクリプトは、前回のファイル(Box2D_02_01.as)に追加する形になります。まずは追加するスクリプトコードのみ記載して、後で必要に応じて全体を掲載します。
スクリプト:3-1 |
・インポートのセクションに追加 |
import Box2D.Dynamics.b2BodyDef; |
・コンストラクタの最後尾に追加 |
//▼床(静体)の生成 |
b2BodyDef.positionプロパティはデフォルトでx=0、y=0のb2Vec2オブジェクトが割り当てられるので、b2Vec2.Set()メソッドで設定しています。ピクセル位置で考えるとX座標はステージ幅(550)の中間位置、Y座標は300でステージの下方となります。
・b2ShapeDefオブジェクトの生成
長方形を作るにはb2ShapeDefクラスのサブクラスであるb2PolygonDefクラスを使います。
形状はb2PolygonDef.SetAsBox()メソッドで指定します。
【コンストラクタ】b2PolygonDef()-b2PolygonDefオブジェクトの生成
【M】b2PolygonDef.SetAsBox(hx:Number, hy:Number) : void-物体としての長方形を定義
引数-hx:横サイズの半分(メートル)/hy:縦サイズの半分(メートル)
戻り値-なし
b2PolygonDef.SetAsBox()メソッドでは横縦サイズの半分のサイズを指定します。今回は幅4m高さ0.3mの板を作ろうと思うので、次のスクリプトを追加します。
スクリプト:3-2 |
・インポートのセクションに追加 |
import Box2D.Collision.Shapes.b2PolygonDef; |
・コンストラクタの最後尾に追加 |
//ShapeDefの設定 |
これで次の画像のような静体を作る設定ができました。
・b2Bodyオブジェクトの生成
b2BodyDefオブジェクトとb2ShapeDefオブジェクト(今回はb2PolygonDefオブジェクト)を用意できたのでb2Bodyオブジェクトを生成します。
b2Bodyオブジェクトの生成はコンストラクタではなくb2WorldクラスのCreateBody()メソッドで行います。これは、b2Worldオブジェクトがその物理ワールド内に作成された全てのb2Bodyオブジェクトを子として管理するためです。
形状を作成しb2Bodyオブジェクトに適用するにはb2BodyクラスのCreateShape()メソッドを使います。
【M】b2World.CreateBody(def:b2BodyDef) : b2Body
引数-def:物体に反映する情報を持ったb2BodyDefオブジェクト
戻り値-生成されたb2Bodyオブジェクト
【M】b2Body.CreateShape(def:b2ShapeDef) : b2Shape
引数-物体に適用するb2ShapeDefオブジェクト
戻り値-生成されたb2Shapeオブジェクト
全ての物体(b2Bodyオブジェクト)が物理ワールド(b2Worldオブジェクト)に子として管理されるのと同様に、ある物体に適用された形状(b2Shapeオブジェクト)もその物体の子として管理されます。
Box2Dの2.0.0では静物のb2Bodyオブジェクトを生成するためにb2World.CreateStaticBody()メソッドが、動体のb2Bodyオブジェクトを生成するためにb2World.CreateDynamicBody()メソッドが用意されていました。これが2.0.2ではCreateBody()メソッドに統一されています。
物体の生成については他の部分はあまり大きな変更は無いようなので、2.0.0のサンプルコードを2.0.2で使う場合、物体の生成に関してはCreateStaticBody()メソッド/CreateDynamicBody()メソッドをCreateBody()メソッドに書き換えれば動作すると思います。
スクリプト:3-3 |
・インポートのセクションに追加 |
import Box2D.Dynamics.b2Body; |
・コンストラクタの最後尾に追加 |
//ボディの生成 |
床の静体は基本的に他所から参照する予定は無いのでローカル変数で扱います。
今回は形状(b2Shapeオブジェクト)をプログラム上で特に扱う予定は無いのでCreateShape()メソッドで返された値は参照を保持しません。
ここまでのスクリプト全体は次のようになります。なお、前回のスクリプト【スクリプト:2-2】(Box2D_02_01.as)からの追加部分は青く表示してあります。また、ドキュメントクラス名の変更に伴い修正してある部分を赤く表示してあります。
スクリプト:3-4 |
//Box2D_03_01.as |
このスクリプトでは表示に関する設定がないので、生成した床はまだ表示されません。
次は動体を作成します。その後に表示に関する設定を行っていこうと思います。
→今回のファイル【Box2D_03_01.zip】