🐦
[phina.js]phina.jsからBox2dを使う
Box2dとは
Box2dはゲーム用の2d物理エンジンで、元々は C++で作られたものですが、Box2dWebという名前でjavascriptにも移植されています。 Box2d自体は有名なライブラリであり、Web上での解説記事も多いので、ここでの詳細な説明は割愛します。 Angry Birdに使われているとか良く触れられていますね。
Box2dWebとphina.jsの連携について
有名なBox2dではありますが、いざ使おうとすると、結構面倒な前処理を自前で書く必要があります。
phina.jsには、このような処理を書かずにBox2dWebをより簡単に使うことができるクラスが用意されています。
クラス名 | 役割 |
---|---|
phina.box2d.Box2dLayer | 主にBox2dを使用するための前処理を行います。 |
phina.box2d.Box2dBody | 物体の定義やBox2dとphina.jsとの間の座標及びスケールの調整などを行います。 |
ライブラリの読み込み
Box2dWebをhtmlで読み込みます。本家のものだと何故か上手く読み込まれなかったので、今回は@phiさんがforkしてbugfixしたバージョンを使用します。
<script src="https://rawgit.com/phi-jp/box2dweb/master/Box2D.js"></script>
<script src="http://cdn.rawgit.com/phi-jp/phina.js/v0.2.1/build/phina.js"></script>
レイヤーの作成
最初にBox2d表示用のレイヤーを作ってSceneに追加します。
// グローバルに展開
phina.globalize();
// 定数
var SCREEN_WIDTH = 640;
var SCREEN_HEIGHT = 960;
/*
* メインシーン
*/
phina.define("MainScene", {
// 継承
superClass: 'DisplayScene',
// 初期化
init: function() {
// 親クラス初期化
this.superInit();
// 背景色
this.backgroundColor = 'black';
// Box2d用レイヤー作成
var layer = Box2dLayer({
width: SCREEN_WIDTH,
height: SCREEN_HEIGHT,
}).addChildTo(this);
}
});
レイヤーは、画面サイズと同じサイズにしないと位置がずれるので注意しましょう。
物体を追加する(落下するボール)
簡単な例として、落下するボールを追加してみます。
// Box2d用レイヤー作成
var layer = Box2dLayer({
width: SCREEN_WIDTH,
height: SCREEN_HEIGHT,
}).addChildTo(this);
// ボール
var ball = CircleShape().addChildTo(this);
ball.setPosition(this.gridX.center(), this.gridY.center());
// Box2dのデバッグ表示が見えるようにする
ball.alpha = 0.5;
// Box2dオブジェクトを作成してballにアタッチ
layer.createBody({
type: 'dynamic',
shape: 'circle',
}).attachTo(ball);
- 先にphina.jsのオブジェクトであるCircleShapeを作成して、 Sceneに追加しています。
- その後、 Box2dLayerのメソッドであるcreateBodyでBox2dオブジェクトを作成して、 CircleShapeにアタッチしています。
- createBodyのパラメータのうち、 typeには重力などが適用されるdynamicを指定し、形状を表すshapeにはcircleを指定しています。
- アタッチすると、以後Box2d側の動きとphina.js側の動きが同期するようになります。
固定の床
このままではボールが落ちるだけなので、障害物となる床を配置します。
// 床
var floor = RectangleShape({
width: SCREEN_WIDTH,
height: 32,
}).addChildTo(this);
floor.setPosition(this.gridX.center(), this.gridY.span(15));
// Box2dのデバッグ表示が見えるようにする
ball.alpha = 0.5;
// Box2dオブジェクトを作成してfloorにアタッチ
layer.createBody({
type: 'static',
shape: 'box',
}).attachTo(floor);
- 床はphina.js側ではRectangleShapeで表示します。
- 床は固定で動かないのでtypeをstaticにします。
- 形状を表すshapeはboxにします。
これで、ボールが床に当たり跳ねるようになりました。
床に角度をつける
ここまでだと余りBox2dの恩恵に預かっていないので、より物理的な動きを確認するために床を傾けてみます。
// Box2dオブジェクトを作成してfloorにアタッチ
layer.createBody({
type: 'static',
shape: 'box',
}).attachTo(floor).body.SetAngle(Math.degToRad(10));
- phina.jsに慣れているとshapeにrotationを設定したくなりますが、 phina.js側はBox2dの動きを追従しているだけなので、 Box2dのメソッドを使う必要があります。
- Box2dBodyクラスのプロパティbodyでBox2dのオブジェクトを参照できるので、 SetAngleメソッドで角度(radian)を設定しています。
これで、ボールが床に落ちて転がっていきます。
おわりに
以上がphina.jsからBox2dを使う簡単な方法です。まだ紹介出来ていない部分も多くあると思いますし、私自身もまだまだ勉強中てす。
- Shapeではなくスプライトを使う
- Box2dのデバック描画をしないようにする
などが次にトライできるテーマでしょう。
結構簡単に連携できることがお分かり頂けたと思いますので、皆さんの方でも色々と試して遊んでみて下さい。
Discussion