読者です 読者をやめる 読者になる 読者になる

kkana's blog

新米コーダーの忘れそうなことメモ

Box2dWebを使ってみる(1)

Box2D

物理エンジン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つの核になる要素があります。

  1. World
    座標空間のすべてを把握している。ワールド内のすべての要素のリストも格納している。
  2. Body
    位置や速度を持ったもの。ここはいろいろ設定項目があるので後述。
  3. Shape
    ボディに付着された衝突ジオメトリをすべて管理します(?まだ勉強していないので詳細はわかっていません)
  4. Fixture
    密度、摩擦、反発などの特性を設定。(?まだ勉強していないので詳細はわかっていません)
  5. Joint
    2つのボディの接続部として機能。(?まだ勉強していないので詳細はわかっていません)
  6. 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を作るには、以下の手続きをします。

  1. bodyDefオブジェクトを使用してbodyを定義する
  2. body定義からbodyオブジェクトを作成する。
  3. シェイプクラスを使用してShapeオブジェクトを作成する。
  4. fixtureDefを使用してfixtureを定義し、fixtureにShapeを割り当てる。
  5. 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の完成!

tuitui.hatenablog.com