『 QuickBox2D はじめの第一歩 』
2009 年 6 月 28 日
Zevan Rosser氏が作ってる、簡単にBox2DAS3を使うためのライブラリ「QuickBox2D」のチュートリアル。
第一回は、僕の勉強も兼ねて、QuickBox2Dの導入方法と簡単なサンプルの説明です。
メニューはこちら
QuickBox2Dの導入
サンプルファイルのダウンロード
Sample 01 「四角形と円を作ってみる」
Sample 02 「高精度な衝突判定を使う」
Sample 03 「オブジェクトの色や透明度を変える」
Sample 04 「パラメータのデフォルト値を設定する」
Sample 05 「静的オブジェクトを作る」
Sample 06 「多角形を作る」
Sample 07 「複雑な多角形を作る」
Sample 08 「Box2Dのデバッグ表示を使う」
導入
まず、QuickBox2Dライブラリを使うには手元にQuickBox2DライブラリとBox2DFlashAS3ライブラリが必要なので、以下のページからそれぞれダウンロードします。
QuickBox2D – Downloadsにある最新版をダウンロード(6月27日現在でQuickBox2D alpha 107)
Box2DFlashAS3 – 緑色のDownloadボタンからダウンロード
ダウンロードしたファイルを解凍し、クラスパスを通します。
めんどうならflaファイルが置いてあるところにBox2Dフォルダとcomフォルダを置けばOK。
導入はこれで完了。
サンプル
今回紹介するサンプルのFlashDevelop用プロジェクトファイル一式をダウンロードできます。
Download
以下では,QuickBox2Dのスタートページに載っている8個のサンプルコードを上から順番に説明していきます。
基本的には本家のソースコードそのままですが、とても簡単に物理シミュレーションを実現できる事が分かると思います。
コードはタイムラインに書いてもクラスのコンストラクタに書いてもOK。
赤文字はそのサンプルで大事な部分です。ではどうぞ。
Sample 01 「四角形と円を作ってみる」
import com.actionsnippet.qbox.*; // (1)
var sim:QuickBox2D = new QuickBox2D(this); // (2)
sim.createStageWalls(); // (3)
sim.addBox( { x:5, y:5, width:1, height:1 } ); // (4)
sim.addCircle( { x:4, y:8, radius:2 } ); // (5)
sim.start(); // (6)
sim.mouseDrag(); // (7)
真っ赤っか(笑) はい、ひとつずついきまーす。
import com.actionsnippet.qbox.*;
(1) QuickBox2Dのインポート。これがないと始まらない。Box2DFlashAS3はインポートしなくてもQuickBox2Dが勝手にやってくれるのでOK。
var sim:QuickBox2D = new QuickBox2D(this);
(2) QuickBox2Dインスタンスを作る。こいつの中で物理シミュレーションする。引数として渡したMovieClipにシミュレーション結果をバリバリ描画していく。クラスベースでやるときはついついSprite型を渡してしまわないように注意(笑)
sim.createStageWalls();
(3) とても便利なメソッド。こいつを呼び出せばステージ四方に壁を作ってくれる。ブラウザリサイズに対応してなかったり厚みをコントロールできなかったりするのがあれだけど、とりあえず実験するぶんにはかなり重宝。
sim.addBox( { x:5, y:5, width:1, height:1 } );
(4) 四角形のオブジェクトを作る。Box2DFlashAS3でなにか作るには、まず形状の定義をして、それから実体化する手順がいるけどQuickBox2DではこれひとつでOK。パラメータとしていろんな値を渡せるけど、ひとまず幅1m、高さ1mの四角形をx座標5m、y座標5mの地点に置いてます。
QuickBox2Dでは1mを30ピクセル固定で表現しているので、1ピクセルが1mだと思ってパラメータを指定するとバカでかいオブジェクトが出現してしまいます。なので例えばオブジェクトをx座標90ピクセルに置きたいときは、xのパラメータを3にすればよいです。
sim.addCircle( { x:4, y:8, radius:2 } );
(5) 同じようにして円形のオブジェクトを作る。radiusは半径。要は半径2mの円をx座標4m、y座標8mの地点に置いてます。
sim.start();
(6) シミュレーションを開始する。これを書いとけば毎フレーム自動でオブジェクトを更新してくれる。Papervision3DでいうところのstartRenderingみたいなもん。
sim.mouseDrag();
(7) これも便利。壁みたいな固定オブジェクト以外のオブジェクトをマウスでドラッグできるようになる。
Sample 02 「高精度な衝突判定を使う」
import com.actionsnippet.qbox.*;
var sim:QuickBox2D = new QuickBox2D(this);
sim.createStageWalls();
sim.addBox( { x:5, y:5, width:1, height:1, isBullet:true } );
sim.addCircle( { x:4, y:8, radius:2 } );
sim.start();
sim.mouseDrag();
前回との違いはisBulletパラメータをtrueにして渡すだけ。これだけで、この四角形に対しては精度の高い(でも負荷の高い)衝突判定アルゴリズムに切り替わる。試してみると確かにfalseの場合に比べて衝突後の慣性が自然に表現されてて気持ちいいなー。ポイントとなる部分で使うと良いかも。ちなみにBulletは弾丸という意味。
Sample 03 「オブジェクトの色や透明度を変える」
import com.actionsnippet.qbox.*;
var sim:QuickBox2D = new QuickBox2D(this);
sim.createStageWalls();
sim.addBox( { x:5, y:5, width:1, height:1, lineColor:0xFF0000, fillColor:0xFFFF00 } );
sim.addCircle( { x:4, y:8, radius:2, fillColor:0xCC0000, fillAlpha:.5, lineThickness:3, lineAlpha:.5 } );
sim.start();
sim.mouseDrag();
lineColorで線の色、lineAlphaで線の透明度、lineThicknessで線の太さ、fillColorで塗り色、fillAlphaで塗りの透明度をそれぞれ変更できる。サンプルでは四角形の線の色を赤、塗りの色を黄色、円の塗りの色をグレー、線と塗りの透明度を0.5、線の太さを3に変更してる。
Sample 04 「パラメータのデフォルト値を設定する」
import com.actionsnippet.qbox.*;
var sim:QuickBox2D = new QuickBox2D(this);
sim.setDefault( { fillColor:0x00CC22, lineAlpha:0, radius:1.5 } ); // (1)
sim.createStageWalls();
sim.addBox( { x:5, y:5, width:1, height:1, lineColor:0xFF0000, lineAlpha:1 } );
sim.addCircle( { x:4, y:8, radius:2 } );
sim.addCircle( { x:10, y:4, fillColor:0x666666 } ); // (2)
sim.start();
sim.mouseDrag();
ほい解説。
sim.setDefault( { fillColor:0x00CC22, lineAlpha:0, radius:1.5 } );
(1) setDefaultメソッドを使えば全オブジェクトに対するデフォルト値を設定できる。ここでは塗りの色を緑、線の透明度を0(表示しない)、半径を1.5mに設定してる。ただしオブジェクトをaddするときのパラメータとデフォルト値では、addするときのパラメータの方が優先される。
sim.addBox( { x:5, y:5, width:1, height:1, lineColor:0xFF0000, lineAlpha:1 } );
sim.addCircle( { x:4, y:8, radius:2 } );
sim.addCircle( { x:10, y:4, fillColor:0x666666 } );
(2) それぞれのオブジェクトをaddするときに、未指定パラメータに関してだけデフォルト値が設定されている。
Sample 05 「静的オブジェクトを作る」
import com.actionsnippet.qbox.*;
var sim:QuickBox2D = new QuickBox2D(this);
sim.setDefault( { fillColor:0x00CC22, lineAlpha:0, radius:1.5 } );
sim.createStageWalls();
sim.addBox( { x:5, y:5, width:1, height:1, lineColor:0xFF0000, lineAlpha:1 } );
sim.addCircle( { x:4, y:8, radius:2 } );
sim.addCircle( { x:10, y:4, fillColor:0x666666 } );
sim.addBox( { x:5, y:6, width:4, height:.3, angle:0.3, density:0, fillColor:0xCC0000 } );
sim.start();
sim.mouseDrag();
壁のような動かないオブジェクトを作るにはdensityを0にしてあげればOK。densityが0のオブジェクトはmouseDragを実行してもマウスでドラッグできなくなる。ここでは赤いバーを設置。
Sample 06 「多角形を作る」
import com.actionsnippet.qbox.*;
var sim:QuickBox2D = new QuickBox2D(this);
sim.setDefault( { fillColor:0x00CC22, lineAlpha:0, radius:1.5 } );
sim.createStageWalls();
sim.addBox( { x:5, y:5, width:1, height:1, lineColor:0xFF0000, lineAlpha:1 } );
sim.addCircle( { x:4, y:8, radius:2 } );
sim.addCircle( { x:10, y:4, fillColor:0x666666 } );
sim.addBox( { x:5, y:16, width:4, height:.3, angle:0.3, density:0, fillColor:0xCC0000 } );
sim.addPoly( { x:15, y:8, verts:[[0, 0, 2, 2, 0, 2]], fillColor:0x0000FF } );
sim.start();
sim.mouseDrag();
ちょい複雑なので詳しく解説。
好きな形の多角形を作るにはaddPolyを使い、頂点配列をvertsに渡すことで作れる。(x1, y1)、(x2, y2)、(x3, y3)の3点で定義される頂点配列は[x1, y1, x2, y2, x3, y3]となる。3点は最上部の点から書き始めて,時計回りになる順番で書いていく。
ここで書く頂点座標はステージ座標ではなく、オブジェクトを定義するための頂点間の関係を示す座標なので、(0, 0)と書いたからといってステージの(0, 0)に置かれるわけではない。分かりづらければ(0, 0)に最初の点があると思って座標を書いていけばOK。
サンプルでは(0, 0)、(2, 2)、(0, 2)の3点で定義される三角形を作ってx=15、y=8の位置に置いている。vertsが2重配列になっているのは複数の頂点配列を渡せるようにするため(次のサンプルで解説)。
サンプルでは頂点数が3個だけど、頂点数は8個まで増やせる。ただし,凹な形にすると衝突判定がおかしくなるので注意が必要。
もっと複雑な形のオブジェクトを作る場合は,Sample7で解説する3角形の組み合わせで表現する方法や、vertsではなくpointsを用いる方法(後で解説)を使いましょう.
Sample 07 「複雑な多角形を作る」
import com.actionsnippet.qbox.*;
var sim:QuickBox2D = new QuickBox2D(this);
sim.setDefault( { fillColor:0x00CC22, lineAlpha:0, radius:1.5 } );
sim.createStageWalls();
sim.addBox( { x:5, y:5, width:1, height:1, lineColor:0xFF0000, lineAlpha:1 } );
sim.addCircle( { x:4, y:8, radius:2 } );
sim.addCircle( { x:10, y:4, fillColor:0x666666 } );
sim.addBox( { x:5, y:16, width:4, height:.3, angle:0.3, density:0, fillColor:0xCC0000 } );
sim.addPoly( { x:15, y:8, verts:[[0, 0, 2, 2, 0, 2], [0, 0, 0, 1, -2, -0.2]], fillColor:0x0000FF } );
sim.start();
sim.mouseDrag();
addPolyのvertsに複数の頂点配列を渡せば、複数のポリゴン組み合わさったがオブジェクトを作れる。
サンプルでは(0, 0)、(2, 2)、(0, 2)からなる三角形と、(0, 0)、(0, 1)、(-2, -0.2)からなる三角形を組み合わせたオブジェクトを作ってる。サンプルでは2個のオブジェクトを組み合わせているが,何個でも組み合わせることができる。
Sample 08 「Box2Dのデバッグ表示を使う」
import com.actionsnippet.qbox.*;
var sim:QuickBox2D = new QuickBox2D(this, { debug:true } );
sim.setDefault( { fillColor:0x00CC22, lineAlpha:0, radius:1.5 } );
sim.createStageWalls();
sim.addBox( { x:5, y:5, width:1, height:1, lineColor:0xFF0000, lineAlpha:1 } );
sim.addCircle( { x:4, y:8, radius:2 } );
sim.addCircle( { x:10, y:4, fillColor:0x666666 } );
sim.addBox( { x:5, y:16, width:4, height:.3, angle:0.3, density:0, fillColor:0xCC0000 } );
sim.addPoly( { x:15, y:8, verts:[[0, 0, 2, 2, 0, 2], [0, 0, 0, 1, -2, -0.2]], fillColor:0x0000FF } );
sim.start();
sim.mouseDrag();
今回最後の解説。
QuickBox2Dのコンストラクタの第2引数にdebug:trueを含むオブジェクト渡せば、Box2Dのデバッグ表示に切り替わる。
おつかれさまでした。
以上が、QuickBox2Dをとりあえず使ってみたい人のための導入方法と簡単なサンプルの説明でした。
QuickBox2Dは現在どんどん機能拡張されていたり、おもしろいサンプルが本家でどんどん紹介されているので(GroupとJointの使い方とかFRIM、任意の形を三角ポリゴンに分けてオブジェクトを作る、表示オブジェクトを切り替えるなどなど)、本家に書いてあることはできるだけ紹介していきたいです。あと僕がライブラリのソースコードを読んでて気づいた点やライブラリ拡張の方法とか。
本家のドキュメントも充実していますので、読んでみると良いかも。
他のQuickBox2Dネタ一覧もどうぞ » tag : QuickBox2D