物理演算をしてくれるライブラリにBox2DWebというのがあります。Box2DFlashというASライブラリのJavaScript版です。
こいつを使って物理演算をすると、表現の幅が広がりそうなので、試してみたいと思います。
とりあえず最初なので、簡単なのを作ってみました。
わりと事前準備が大変なので、Box2DWeb jsを使って物理演算をする上で、大切な所を解説しておきます。
Box2DWeb jsを使って物理演算をする方法
1. スケールを定義しておこう
// 17行目付近
var WORLDSCALE = 30;
Box2DWebはメートル方を採用しているらしいので、共通のスケールを定義しておきます。
今回は1メートル=30pxでいきます。
2. 重力を計算する世界を作ろう
// 20行目
var world = new b2World(
new b2Vec2(0, 9.8) , // 重力の設定 横,縦の重力を指定する。今回は縦に9.8
true // trueだと止まったオブジェクトは計算対象からはずすので軽くなる
);
ここでは重力が有効な世界を生成しています。
1つ目の引数は重力の、2つ目の引数は動かなくなったオブジェクトを計算対象からはずすかどうかの設定です。
なにか理由がない限り、true推奨です。
3. 定義をまとめた入れ物を宣言しよう
// 25行目
var fixDef = new b2FixtureDef; // 入れ物生成
fixDef.density = 1.0; // 密度
fixDef.friction = 0.5; // 摩擦係数
fixDef.restitution = 0.2; // 反発係数
フィクスチャーという入れ物をつくって、もろもろ定義しておきます。
4. いよいよ物体を作ろう
// 30行目から一番下のラインを引きます
var bodyDef = new b2BodyDef; // 物体を宣言
// これは一番下のラインなので動かない
bodyDef.type = b2Body.b2_staticBody; // 動くやつはb2_dynamicBody
fixDef.shape = new b2PolygonShape; // 今回は四角形
// 縦1pxのラインを引く
fixDef.shape.SetAsBox(600 / WORLDSCALE , 1 / WORLDSCALE); // widthとheight(共通のスケールで割る)
bodyDef.position.Set(0 , 400 / WORLDSCALE); // xとy
world.CreateBody(bodyDef).CreateFixture(fixDef); // 世界に突っ込む
ここでやっと物体を作っています。
今回用意したcanvasに合わせて、一番下に線を引いております。
5. 落とすボールを作ろう
// 42行目
bodyDef.type = b2Body.b2_dynamicBody; // 今回は動く物体
fixDef.shape = new b2CircleShape(30 / WORLDSCALE); // 適当な半径をもつ丸にする
bodyDef.position.x = 300 / WORLDSCALE; // 横300の位置に置く
bodyDef.position.y = 0 / WORLDSCALE; // 高さは0の場所から
world.CreateBody(bodyDef).CreateFixture(fixDef); // 世界に突っ込む
これで落とす物体となるボールができました。
横300px、高さ0pxから落下していく動的な物体です。
6. 画面にデバッグ表示させる処理をしよう
// 43行目
var debugDraw = new b2DebugDraw(); // debug用オブジェクト
debugDraw.SetSprite(document.getElementById("canvas").getContext("2d")); // 描画するcanvasを設定
debugDraw.SetDrawScale(WORLDSCALE); // この世界のスケールを設定
debugDraw.SetFillAlpha(0.5); // 要素の透過度を設定
debugDraw.SetFlags(b2DebugDraw.e_shapeBit | b2DebugDraw.e_jointBit); // 表示する内容を定数で指定
world.SetDebugDraw(debugDraw); // 世界にdebug要素を突っ込む
Box2DWebはあくまで計算してくれるだけなので、画面には何も表示されません。
ただデバッグモード的なものがありまして、canvasに現在の世界の状態を反映できます。
今回はデモなのでそれを定義しています。
7. 更新するイベントを設定しよう
// 画面を定期的に更新していく
window.setInterval(update, 1000 / 60);
function update() {
// 世界を少しずつ進めていく
world.Step(1 / 60, 10, 10);
// デバッグ描画の書き直し
world.DrawDebugData();
world.ClearForces();
};
setIntervalで定期的に、ちょっとずつ描画を更新していってます。
まとめ
けっこうあっさりとですが、こんな風に物理演算をしてくれる便利なライブラリなので、いい感じに使っていきたいもんです。
Box2DWeb js自体のドキュメントは見つけられなかったのですが、Box2Dと基本的に一緒のようなので、そちらのリファレンスを読むといんじゃないかと思います。
LIGはWebサイト制作を支援しています。ご興味のある方は事業ぺージをぜひご覧ください。