kkana's blog

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

Box2dWebを使ってみる(3)

前回

tuitui.hatenablog.com

四角じゃないものを作ってみます。

See the Pen Box2DWebを使ってみる(3) by kana (@kanaparty) on CodePen.

頂点が何個かある物体をつくる

前回はPolygonShapeのSetAsBoxメソッドを使って四角をつくりました。 四角以外のものは b2PolygonShapeのSetAsArrayを使って作ります。 第一引数に頂点の座標をBox2D.Common.Math.b2Vec2オブジェクトの配列にして渡します。 第二引数は頂点の数です。

//シェイプを定義
this.polygonshape = new b2PolygonShape;
//シェイプに頂点を定義(頂点の座標b2Vec2の配列, 頂点の数)
this.polygonshape.SetAsArray(this.verticesForBox2dworld , this.verticesLength);

四角のときと同じく、box2Dワールドの座標とcanvasで書くときの座標が合うように適宜変換しながら作ります。

凹んだ形は作れないので注意

凹んだ形は衝突判定がうまくできないようです。
凹んだ形が作りたいときは、凸の形を複数組み合わせて作ります。(できたら後述します)

canvasで書く

draw() {
  //canvasを保存
  ctx.save();
  //座標を移動
  ctx.translate(this.centerX, this.centerY);
  //傾ける
  ctx.rotate(this.angle);
  //パスを引く
  ctx.beginPath();
  ctx.moveTo(this.vertices[0][0], this.vertices[0][1]);
  for (var i = 0; i < this.verticesLength; i++) {
    ctx.lineTo(this.vertices[i][0], this.vertices[i][1]);
  };
  ctx.closePath();
  ctx.fillStyle = this.fillColor;
  //塗りつぶし
  ctx.fill();
  //保存したcanvasの状態に戻す
  ctx.restore();
}

四角のときと基本的には一緒です。 今回はfillRectではなくて、パスを書いて、塗りつぶすというやり方にしています。
座標はbodyを作成するときに保存してしておいたものを使うのが楽ですが(パスを書く前に座標を毎フレームごとに新しい中心の位置にずらしているので)中心点からの頂点の位置をb2PolygonShapeのGetVerticesメソッドで知ることもできます。


余談 b2EdgeChainDef

四角以外のシェイプを作る前に、本当はb2EdgeChainDefを使って谷型になっている境界を作ってみたかったのですが
box2Dwebではまだ実装途中なのでしょうか・・リファレンスにも3つしかメソッドが載っていなかったし

Google グループ

でも今回の5角形の作り方で谷のような床も作成できそうなので、あんまり問題はないかもしれないです。