『 QuickBox2D 1.0 正式版リリース 』

2009 年 9 月 30 日

今までアルファ版だったのに、いつの間にかQuickBox2D 1.0がリリースされていました。QuickBox2DっていうのはActionSnippetのZevan氏が作ってる、Box2DFlashAS3を簡単に扱えるようにするライブラリです。このブログでも何度か紹介させていただいてます。超オススメ。

なので久々にQuickBox2Dネタを書こうとActionSnippetを見てみると、僕の知らないサンプルが30個以上。凄い、どれを紹介しようか迷う。というか機能が増えすぎてよくわからん、やばい!というわけで何日かに分けてこのエントリに、サンプルがどんなことをやっているのか、どこの部分がキモなのかだけ勉強がてら書いてみます。間違っていればどうぞ突っ込みお願いします。

QuickBox2Dのメソッドは引数にObject型を渡すことが多いです(Tweenerみたいに)。このObjectでメソッド特有の色々パラメータを指定します。例えば多角形を作成するaddPolyなど、剛体を作り出すaddXXX系のメソッドではx座標やy座標や角度などを標準で指定できます。今回このようなパラメータについて記述するとき、これらの標準プロパティについては省略して、addPolyならaddPolyでしか指定できない引数だけを記述していきます。addXXX系のメソッドで指定できる標準パラメータに関してはこちらのエントリの下の方にまとまっていますので参照してください。

コード中に出てくるsimはQuickBox2Dのインスタンスを表しています。

 var sim:QuickBox2D = new QuickBox2D(this, {オプション});

 
追記 09.10.04
とりあえずタイトルだけ書いた、先に。
 

32. setGroupIndexによる衝突判定有無の切り替えQuickBox2D Mini-Machine
執筆中

31. テクスチャをジョイントに適用するQuickBox2D Joint Skinning
執筆中

30. テクスチャサイズの自動調整QuickBox2D Skinning Examples
執筆中

29. 指定したgroupIndex同士の衝突を検出するQuickBox2D Contact Filtering
執筆中

28. FlashPlayer10の3D表現QuickBox2D 3D
執筆中

27. QuickBox2Dによる衝突判定3QuickBox2D Contacts Part 3
執筆中

26. QuickBox2D 1.0の特長QuickBox2D 1.0 Features
執筆中

25. QuickBox2Dによる衝突判定2QuickBox2D Contacts Part 2
執筆中

24. QuickBox2Dによる衝突判定1QuickBox2D Contacts Part 1
執筆中

23. QuickBox2D 1.0リリースQuickBox2D 1.0
執筆中

22. 指定時間後に関数を呼び出すQuickBox2D addTimeStepSequence() Preview

sim.addTimeStepSequence(
  { time:時間, callback:呼び出す関数, args:[呼び出し時の引数配列] },
  { time:時間, callback:呼び出す関数, args:[呼び出し時の引数配列] },
  { time:時間, callback:呼び出す関数, args:[呼び出し時の引数配列] },
  ...
  { time:時間, callback:呼び出す関数, args:[呼び出し時の引数配列] }
);

addTimeStepSequenceにあらかじめ登録しておくことで、指定した時間ステップが経過すると指定し関数を指定した引数と共に呼び出すことができる。呼び出しのタイミングはFRIM(フレームレートに依存しない)ので、オブジェクトの状態とずれることがない。デモではオブジェクトの動きやタイミングに合わせての視点移動やズームをおこなっている。addTimeStepSequenceには一度にいくらでも登録可能。timeに指定する数値の計算方法を後で確認する。

21. ピタゴラスイッチ的なサンプルQuickBox2D Vaguely Goldberg-esque
シーソー機構や、反発係数(restitution)を1以上にすることで打ち返す機構をつかったピタゴラスイッチのようなサンプル。おもしろい。

20. createメソッドによるオブジェクトの生成QuickBox2D create() Method

sim.create(生成するオブジェクトの種類, {オプション});

これまでaddCircle、addBox、addPolyなどメソッドそのものを使い分けることで様々なオブジェクトを生成したが、実はcreateメソッドだけで任意のオブジェクトを生成できる。第1引数に”circle”、”box”、”poly”などオブジェクトの種類を文字列で指定すればOK。第2引数はオブジェクトの生成パラメータ。

19. 衝突判定の有無をを動的に切り替えるQuickBox2D groupIndex Platforms

var object:QuickObject = ...
var filter:b2FilterData = object.shape.GetFilterData();
filter.groupIndex = 1;
object.shape.SetFilterData(filter);

Box2DFlashAS3の衝突判定フィルタであるb2FilterDataのgroupIndexを動的に書き換えることで、上方向からの衝突判定だけを持っているオブジェクトを生成するサンプル。
また、sim.w.GetContactCount() メソッドにより現在衝突が起こっているオブジェクトの数を知ることができる。

18. 人体と一輪車の連動サンプルQuickBox2D Unicycler
一輪車でバランスを取りながら前後に移動する人間を模したデモ。一見リアルな動きに、バランスと取るための凄いアルゴリズムが組まれていそうに感じるが、実は転けないように毎フレーム上体の角度をコントロールしている。
バランスを取っているように見せるために腕の動きをフリーにしていること、上体を三角関数で揺らしていること、車輪と足の繋ぎの見せ方が秀逸。上体と車輪の接続部分にどうもテクニックを使ってるっぽいので後で調べないと。あと、QuickBox2DのコンストラクタパラメータとしてrenderJointsを指定するとジョイントを表示するかどうか切り替えられる。

17. 足の動きを作るサンプルQuickBox2D Floating Walker
原始的な二足歩行ロボットのスケッチらしい。ジョイントを使って足の動きを作ってる。ジョイント生成用のconnect関数が便利そう。あと、QuickBox2DのコンストラクタパラメータにgravityX、gravityYを指定すれば重力を簡単に設定できる。

16. プリズムジョイント(PrismaticJoint)を作るQuickBox2D Prismatic Joint

var object:QuickObject = sim.addJoint({
  type:"prismatic",
  a:オブジェクトAのbody,
  b:オブジェクトBのbody,
  anchor:オブジェクトAとジョイントの接続点(b2Vec2),
  axis:ジョイントの駆動方向を表すベクトル(b2Vec2)
});

DistanceJoint以外のジョイントを作ろう第四弾はプリズムジョイント。このジョイントはピストンの動きを実現する。anchorを軸として、axisの方向に向かってピストン運動をするっぽいな。
ピストンの移動幅はupperTranslationやlowerTranslationで制御できる。こういう、サンプルで使われてないけど指定できるパラメータに関しても後で追記しときます。
あまり関係ないけどオブジェクトのbody.GetWorldCenter()でそのオブジェクトのグローバル座標をb2Vecインスタンスで取得できるのか、なるほど。
QuickBox2Dクラスによく使いそうな文字列は定数化されてるのを発見したのでメモ。

QuickBox2D.STEP      // "step"
QuickBox2D.DISTANCE  // "distance"
QuickBox2D.REVOLUTE  // "revolute"
QuickBox2D.PRISMATIC // "prismatic"
QuickBox2D.GEAR      // "gear"
QuickBox2D.PULLEY    // "pulley"

これでジョイントの指定にスペルミスが減る、よかった。

15. ギアジョイント(GearJoint)を作るQuickBox2D Gear Joint

var object:QuickObject = sim.addJoint({
  type:"gear",
  a:接続するオブジェクトAのbody,
  b:接続するオブジェクトBのbody,
  joint1:影響するジョイント1,
  joint2:影響するジョイント2
});

DistanceJoint以外のジョイントを作ろう第三弾はギアジョイント。このジョイントは2つのジョイントの動きの大きさの和を保存するように働く。
デモでは、joint1としてプリズムジョイント(次のサンプルで解説)、joint2として回転ジョイントを指定してる。このとき、joint1の伸びとjoint2の回転角の和はいつも等しくなる。また、joint1とjoint2の接続オブジェクトaはどちらも空間(sim.w.GetGroundBody())である必要がある。これは使ってみて慣れるしかない。難しいねー。

14. ジョイントを空間中の1点と接続するQuickBox2D Connect to GroundBody

var object:QuickObject = sim.addJoint({
  type:"revolute",
  a:接続するオブジェクトのbody,
  b:sim.w.GetGroundBody()
});

QuickObjectインスタンスのwプロパティ(b2World)のGetGroundBodyメソッドで取得したb2bodyを、ジョイントの片方の接続オブジェクトとして設定すると、空間にジョイントを接続することができる。上手くいえないけど空中に固定する感じ。

13. 回転ジョイントに角速度を加えるQuickBox2D Revolute Walker

var joint:b2RevoluteJoint = revJointA.joint as b2RevoluteJoint
joint.SetMotorSpeed(1.0);

3つのオブジェクトを回転ジョイントで接続し、角速度を与えることでモーターの役割をさせるデモ。QuickObjectからb2RevoluteJointを取り出し、Box2DFlashAS3のSetMotorSpeedメソッドを呼び出して回転させている。

12. 滑車ジョイント(PulleyJoint)を作るQuickBox2D Pulley Joint

var object:QuickObject = sim.addJoint({
  type:"pulley",
  a:接続するオブジェクトAのbody,
  b:接続するオブジェクトBのbody,
  groundAnchor1:オブジェクトA側の固定接続点(b2Vec2),
  groundAnchor2:オブジェクトB側の固定接続点(b2Vec2)
});

DistanceJoint以外のジョイントを作ろう第二弾は滑車ジョイント。固定接続点は2次元ベクトル(b2Vec2)で渡すこと。そうするとオブジェクトA-groundAnchor1-groundAnchor2-オブジェクトBという関係で結ばれる。

11. 回転ジョイント(RevoluteJoint)を作るQuickBox2D Revolute Ragdoll

var object:QuickObject = sim.addJoint({
  type:"revolute",
  a:接続するオブジェクトAのbody,
  b:接続するオブジェクトAのbody,
  enableLimit:回転角度を制限する場合はtrue、360度ぐるぐる回す場合はfalse,
  lowerAngle:最小の回転角度,
  upperAngle:最大の回転角度
});

DistanceJoint以外のジョイントを作ろう第一弾は回転ジョイント。enableLimitで回転角度を制限する場合はlowerAngle、upperAngleで回転範囲を指定する(ラジアン角)。

10. リンケージされているテクスチャを貼るQuickBox2D Skinning

var object:QuickObject = sim.addXXX({
  skin:リンケージクラス名
});

QuickObjectを生成するときにオブジェクトに貼り付けるテクスチャを指定できる。貼り付けるテクスチャはflaファイルのライブラリにリンケージされている必要がある。Bitmapじゃなくても大丈夫。

9. groupIndexによる衝突判定の制御QuickBox2D groupIndex

var object:QuickObject = sim.addXXX({
  groupIndex:衝突グループインデックス(符号付き整数)
});

QuickObjectを生成するときにgroupIndexを整数で指定できる(負の値も可)。同じ正の数でグループ付けされたオブジェクトは必ず衝突し、同じ負の数でグループ付けされたオブジェクトは必ず衝突しない。デモがとても楽しいので是非見るべし!QuickBox2Dにおける衝突判定の制御については『QuickBox2DやBox2DFlashAS3での衝突判定をグループ分け』参照。

8. 外部XMLにASを記述して動的に実行するXML to ActionScript #3 (AsXML)
ちょっとこれはよく読んでないのでわかんない。どうやらASを記述した外部XML(AsXML形式?)をswfに読み込んでスクリプトを実行する様子。デモでは、QuickBox2D、Papervision3D、TweenLiteのスクリプトをAsXMLに記述して連携させている。勉強しとこう。

7. フレームレートに依存しないシミュレーションQuickBox2D FRIM

var sim:QuickBox2D = new QuickBox2D(this, {
  frim:FRIMを使用する場合はtrue、そうでない場合はfalse
});

QuickBox2D初期化時に、frimプロパティをtrueにするとFRIM(frame rate independent motion)モードとなる。通常フレームレートが低いとモーションは遅く、逆にフレームレートが高いと速くなる。FRIMモードではフレームレートに関わらない時間ベースでのシミュレーションが可能となる。そのかわり、フレームレートが低いとそれだけ粗いモーションとなることに注意。とっても便利な機能。

6. オブジェクトに速度を加えるQuickBox2D w/ Key Controls

var object:QuickObject = ...
var vec2:b2Vec2 = object.body.GetLinearVelocity();
var scalar:Number = object.body.GetAngularVelocity();
object.body.SetLinearVelocity(vec2);
object.body.SetAngularVelocity(scalar);

キー操作によってオブジェクトに力を加えるデモ。GetLinearVelocityで現在の速度、GetAngularVelocityで現在の角速度をそれぞれ取得できる。また、SetLinearVelocityとSetAngularVelocityで速度、角速度を設定できる。この辺はQuickBox2Dから、直接Box2DFlashAS3のメソッドを呼び出している感じ。

5. addGroupによるテトリスのブロック生成QuickBox2D Tetris Pieces
addBoxで生成したたくさんの正方形をaddGroupで結合し、テトリスのブロックを形作るデモ。

4. addGroupによるオブジェクトのグループ化QuickBox2D Groups

var object:QuickObject = sim.addGroup({
  objects:[オブジェクトA, オブジェクトB, オブジェクトC, ... , オブジェクトZ]
});

objects配列で渡したオブジェクトをひとまとめにしたQuickObjectを生成する。frequencyHzとdampingRatioを適度に設定したバネっぽいジョイントの動きにも注目。

3. addPolyによる多角形の生成(凹面も可能)QuickBox2D Polys

var object:QuickObject = sim.addPoly({
  points:[x1, y1, x2, y2, x3, y3, ... , xn, yn],
  wireframe:全ポリゴンのワイヤーフレームを表示する場合はtrue、輪郭のみを表示する場合はfalse
});

addPolyによる複雑なポリゴン生成のデモ。頂点を格納する順番はどうすればいいのか要確認。

2. addJointによるジョイントの生成QuickBox2D Chain

var object:QuickObject = sim.addJoint({
  a:接続するオブジェクトAのbody,
  b:接続するオブジェクトBのbody,
  x1:Aとジョイントの接続点のx座標,
  y1:Aとジョイントの接続点のy座標,
  x2:Bとジョイントの接続点のx座標,
  y2:Bとジョイントの接続点のy座標,
  length:ジョイントの長さ,
  frequencyHz:ジョイントの伸びやすさ,
  dampingRatio:ジョイントの元の長さへの戻りやすさ,
  collideConnected:AとBの間に衝突判定を持たせる場合はtrue、そうでない場合はfalse
});

addJointでオブジェクトAとオブジェクトBをつなぐジョイントを生成できる。このサンプルが投稿されたときはまだDistanceJointしか実装されていなかった。それ以外の、ギアや滑車などのジョイント生成のサンプルは後述。
x1,y1,x2,y2はオブジェクトAやオブジェクトBのローカル座標系でなく、QuickBox2Dのグローバル座標系で指定することに注意。省略するとそれぞれのオブジェクトの基準点が接続点となる。
lengthプロパティはジョイントの長さ。デフォルトではジョイント生成時のオブジェクト同士の距離となるが、別の値を指定する場合は設定する。
frequencyHzはジョイントの柔らかさ。0に近い数値ほどよく伸びるジョイントになり、大きな数値ほど固いジョイントとなる。また、0で完全に剛体となる。
dampingRatioは弾性。0に近い数値ほど伸びた状態から元の長さに戻る力が強まり、大きな数値ほど元の長さへ戻ろうとしなくなる。frequencyHzとdampingRatioでバネのようなジョイントを実現できる。

1. x、y、angleプロパティによるオブジェクトの移動と回転QuickBox2D Play

var object:QuickObject = ...
object.x = 10;
object.x = 5;
object.angle = 1;

addBoxやaddCircleなどで作成できるQuickObjectはx,y,angleプロパティの変更で簡単に移動や回転が可能。『QuickBox2D オブジェクトの平行移動と回転』参照。
 

他のQuickBox2Dネタ一覧もどうぞ » tag : QuickBox2D

« 
» 

Leave a Reply