『 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による衝突判定3 – QuickBox2D Contacts Part 3
執筆中
26. QuickBox2D 1.0の特長 – QuickBox2D 1.0 Features
執筆中
25. QuickBox2Dによる衝突判定2 – QuickBox2D Contacts Part 2
執筆中
24. QuickBox2Dによる衝突判定1 – QuickBox2D 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