◆へこんだ図形の作成
へこんだ図形は、複数のb2ShapeDefオブジェクトを作成しそれぞれをb2Body.CreateShape()メソッドでb2Bodyオブジェクトの子として適用することで作れます。
この場合の注意点としては、b2BodyDef.positionプロパティによる座標位置とb2PolygonDef.verticesプロパティの頂点の座標位置は相対的に維持される、ということです。
つまり、5角形のサンプルのようにb2BodyDef.positionプロパティの座標とb2PolygonDef.verticesプロパティの頂点座標が離れたところにあると、「基準点が離れたところにあるムービークリップ」のようになってしまいます。そうなると、物体を制御する際に分かりにくくなるのであまりよくありません。
今回は三角形を2つくっつけてやじり型を作ってみようと思いますが、b2BodyDef.positionプロパティを(x = 0, y = 0)に設定し、複数のb2ShapeDefオブジェクトの頂点座標の位置も(x = 0, y = 0)を基準とした位置で指定します。
物体は当然(x = 0, y = 0)に作成され、画面上左上に配置されます。それをb2Body.SetXForm()メソッドで移動させようと思います。
b2Body.SetXForm()メソッドは物体の位置と回転角度を変更できます。
【M】b2Body.SetXForm(position:b2Vec2, angle:Number) : Boolean-b2Bodyオブジェクトの位置と回転角度を設定する。
引数-position:b2Bodyオブジェクトの新たな座標位置を表すb2Vec2オブジェクト/angle:回転角度(ラジアン)を表す数値。
戻り値-移動先が物理ワールド外だった場合にはfalseを返し、凍結状態となる。
以下、スクリプトコードです。やはり動体の生成のセクションが主な相違点です。
3角形のb2PolygonDefオブジェクトを2つ作成し、それらをb2Bodyオブジェクトの子として適用している部分を青の太字で表示しておきます。
スクリプト:5-4 |
package {
import flash.display.Sprite;
import Box2D.Collision.b2AABB;
import Box2D.Common.Math.b2Vec2;
import Box2D.Dynamics.b2World;
import Box2D.Dynamics.b2BodyDef;
import Box2D.Collision.Shapes.b2PolygonDef;
import Box2D.Dynamics.b2Body;
import Box2D.Dynamics.b2DebugDraw;
import flash.events.Event;
public class Box2D_05_03 extends Sprite {
private static const DRAW_SCALE:Number = 100;
private var _world:b2World;
private var _bArrow:b2Body;
public function Box2D_05_03() {
var worldRegion:b2AABB = new b2AABB();
worldRegion.lowerBound.Set(-1, -1);
worldRegion.upperBound.Set(6.5, 5);
var gravity:b2Vec2 = new b2Vec2(0, 9.8);
_world = new b2World(worldRegion, gravity, true);
var bdFloor:b2BodyDef = new b2BodyDef();
bdFloor.position.Set(5.5 / 2, 3);
var pdFloor:b2PolygonDef = new b2PolygonDef();
pdFloor.SetAsBox(2, 0.15);
var bFloor:b2Body = _world.CreateBody(bdFloor);
bFloor.CreateShape(pdFloor);
var bdArrow:b2BodyDef = new b2BodyDef();
bdArrow.position.Set(0, 0);
var shape1:b2PolygonDef = new b2PolygonDef();
shape1.vertexCount = 3;
shape1.vertices[0].Set(0, -0.25);
shape1.vertices[1].Set(0,0);
shape1.vertices[2].Set(-0.25, 0.25);
shape1.density = 1;
shape1.restitution = 0.5;
var shape2:b2PolygonDef = new b2PolygonDef();
shape2.vertexCount = 3;
shape2.vertices[0].Set(0, -0.25);
shape2.vertices[1].Set(0.25, 0.25);
shape2.vertices[2].Set(0, 0);
shape1.density = 1;
shape2.restitution = 0.5;
_bArrow = _world.CreateBody(bdArrow);
_bArrow.CreateShape(shape1);
_bArrow.CreateShape(shape2);
_bArrow.SetXForm(new b2Vec2(5.5 / 2, 1), 0);
_bArrow.SetMassFromShapes();
var dd:b2DebugDraw = new b2DebugDraw();
dd.m_sprite = this;
dd.m_drawScale = DRAW_SCALE;
dd.m_fillAlpha = 0.3;
dd.SetFlags(b2DebugDraw.e_shapeBit);
_world.SetDebugDraw(dd);
addEventListener(Event.ENTER_FRAME, _enterFrameHandler);
}
private function _enterFrameHandler(eventObj:Event):void {
_world.Step(1 / 24, 10);
}
}
}
|
↑グラフィックイメージをクリックすると、swfファイルが別ウィンドウで開きます。
さて、これでやじりのようなへこんだ形も作成できました。
→サンプルファイル【Box2D_05_03.zip】
ところで…b2ShapeDefオブジェクトとして作成した2つの三角形はx軸を中心に左右対称にしたつもりです。
しかし、動作を見るとはずんで左にずれるのが分かります↓。
これは「重心」が関係しています。物体には基準点のほかに重心の概念があります。
次回は、重心に関する話や物体の制御に関する内容を扱おうと思います。もしかしたら何回かに分けて扱うかもしれません。
今回もb2Body.SetXForm()メソッドで位置を変更してみましたが、Box2Dには他にも様々な面白いメソッドがあります。次回の更新までは少々時間をいただくかもしれませんがお楽しみに。