物理エンジンbox2dのjs版はいろいろあるみたいだけれどbox2dwebを使ってみます。
hecht-software/box2dweb · GitHub
flash用のものをjsに置き換えたものだそうで、基本的な使い方はbox2dと同じみたいです。ドキュメントはこれを見ています。
Adobe Flex 2 Language Reference
box2dの使い方
物体の位置はbox2dに問い合わせて管理します。その位置を元に描写の部分を書いていきます。 今回はcanvasを使って描写するのを想定しているので、こんな感じの処理が必要になるかと思います。
初期化
- 描写に使用するオブジェクトをすべて作成する。
- 作成したオブジェクトをBox2dワールドに変換する。
描写(requestAnimationFrameなどでループさせる部分)
- Box2dにすべての位置を問い合わせる。
- Box2dが返してくれた位置をcanvas描写用に変換
- 描写
という感じで使っていきます。
box2dワールドの世界観
box2Dに描写したい物体をすべて配置するために、box2dの世界観を理解しておく必要がありそうです。
box2dワールドには以下6つの核になる要素があります。
- World
座標空間のすべてを把握している。ワールド内のすべての要素のリストも格納している。 - Body
位置や速度を持ったもの。ここはいろいろ設定項目があるので後述。 - Shape
ボディに付着された衝突ジオメトリをすべて管理します(?まだ勉強していないので詳細はわかっていません) - Fixture
密度、摩擦、反発などの特性を設定。(?まだ勉強していないので詳細はわかっていません) - Joint
2つのボディの接続部として機能。(?まだ勉強していないので詳細はわかっていません) - Vec2
Box2dワールドのベクトルを表す。
Box2dワールド生成の前に
上の要素はたびたび出てくるので変数に入れておきます。
var b2Vec2 = Box2D.Common.Math.b2Vec2; var b2BodyDef = Box2D.Dynamics.b2BodyDef; var b2Body = Box2D.Dynamics.b2Body; var b2FixtureDef = Box2D.Dynamics.b2FixtureDef; var b2Fixture = Box2D.Dynamics.b2Fixture; var b2World = Box2D.Dynamics.b2World; var b2PolygonShape = Box2D.Collision.Shapes.b2PolygonShape;
という感じで長くなってしまうので、よく使うオブジェクトは変数に格納しておいたほうがスッキリしそうです。
Box2dワールドの作成
new Box2D.Dynamics.b2World(gravity:b2Vec2, doSleep:Boolean);
で生成。第一引数は重力の設定。第二引数のdosleepはtureにしておくと動きが止まったものの計算をしなくなります。
var worldScale = 120;
スケールの定義をします。 box2dはメートル法なので、描写するときに1メートルを何pxに変換するか定義しておいて描写のときに使います。
Bodyを作る
bodyを作るには、以下の手続きをします。
- bodyDefオブジェクトを使用してbodyを定義する
- body定義からbodyオブジェクトを作成する。
- シェイプクラスを使用してShapeオブジェクトを作成する。
- fixtureDefを使用してfixtureを定義し、fixtureにShapeを割り当てる。
- bodyにshapeをアタッチする。
順番に見ていきます。
bodyを定義する
bodyを生成する前にbodyを定義します。
var bodyDef = new b2BodyDef; //bodyの種類を決める bodyDef.type = b2Body.b2_dynamicBody; //座標をセット bodyDef.position.Set(x, y);
bodyにはタイプが3つあります。
1. Dynamic
動く物体
2. Static
動かない物体。境界や固定されたものに使う
3. Kinematic
速度を直接指定できる。動的のbodyにしか衝突しない。
他に設定できること
回転させたくない...fixedRotation
摩擦をかけたい...inearDamping ,angularDamping
速度をもたせたい...linearVelocity,angularVelocity
高速で移動するものにはbulletをtrueに設定すると衝突判定を慎重にしてくれるようになる。
Bodyを生成する
world.CreateBody(さっき定義したbody);
でボディを生成する。
Bodyにその他の状態を設定する
b2Body.SetAngularVelocity();で最初の角速度を設定したり
b2Body.SetLinearVelocity(vec2);で初速度を設定したりできる。
BodyにShape Fixtureをつける
Shapeを定義する
//シェイプを定義 var polygonShape = new b2PolygonShape; //シェイプを長方形として定義 polygonShape.SetAsBox(width, height);
Fixtureを定義してshapeに割り当てる
//fixtureを定義 var fixtureDef = new b2FixtureDef; //密度(単位はkg毎平方メートル) fixtureDef.density = 1.0; //摩擦係数 fixtureDef.friction = 0.5; //弾性力 fixtureDef.restitution = 0.5; //fixtureに先に定義したpolygonshapeを割り当てる fixtureDef.shape = polygonShape;
ボディにシェイプをアタッチする
body.CreateFixture(fixtureDef);
これでbodyの完成!