(2)複数のVector2[]配列からBody.を作りSpriteと関連付ける(複雑な形態のBody)
まず、どうやって複数のVector2[]をBodyに渡すのかが、意外に情報がない。初めはBodyをjointでつなごうと思ったが、どうもちがうらしい。同じ悩みをもつサイトにいきついた。
iOSとCocos2d-xだがBox2dであるため、概念的には一緒であろう。このサイトのコードによるとBody.CreateFixtureでshapeを複数追加していくことができるらしい。 ここで、shapeとは?など色々疑問があったが、PhysicsFactory.createPolygonBodyのソース(下コード)を見てみるとなんとなく理解できた。
public static Body createPolygonBody(final PhysicsWorld pPhysicsWorld, final IShape pShape, final Vector2[] pVertices, final BodyType pBodyType, final FixtureDef pFixtureDef, final float pPixelToMeterRatio) { final BodyDef boxBodyDef = new BodyDef(); boxBodyDef.type = pBodyType; final float[] sceneCenterCoordinates = pShape.getSceneCenterCoordinates(); boxBodyDef.position.x = sceneCenterCoordinates[Constants.VERTEX_INDEX_X] / pPixelToMeterRatio; boxBodyDef.position.y = sceneCenterCoordinates[Constants.VERTEX_INDEX_Y] / pPixelToMeterRatio; final Body boxBody = pPhysicsWorld.createBody(boxBodyDef); final PolygonShape boxPoly = new PolygonShape(); boxPoly.set(pVertices); pFixtureDef.shape = boxPoly; boxBody.createFixture(pFixtureDef); boxPoly.dispose(); return boxBody; }
2-3行目はBody自体の設定(BodyDef定義)、引数より行う。staticBody(重力の影響を受けない)、DynamicBody(重力の影響を受ける)など後ほどコードを載せる。
5-7行目は座標系の変換。Bodyと実座標は違うとのこと。おまじないと思っておいてよいとのこと。
9行目でBodyDefからBodyを生成する
11行目でShpaeクラスのサブクラスのPolygonShapeを生成。
13行目でPolygonShapeのshapeにpVerticesのVector2[]配列を渡す
14行目で引数で渡されたFIXTURE_DEF(その1参照)のshapeにPolygonShapeを渡す
16行目でBodyにpFixtureDef(FIXTURE_DEF)を登録する
18行目でPolygonShapeの解放 という手続きが行われている。
先のサイトの情報より11行~18行をVector2[]配列数だけループさせればよいことが分かった。 準備として、その1で、作成した10個のVector2[]配列を定義部を記載しておく。ちょっとスマートな方法が思いかなかったが、ArrayListに10個のVector2[]を突っ込んだ。 ループで回そうと思ったがAndEngine Vertex Helperで直接定義文が出来るので、そんなめんどくさくはないが、やたらと長くなる。
ArrayList<Vector2[]> vertices_list = new ArrayList<Vector2[]>(); final Vector2[] vertices1 = { new Vector2(-0.46000f*width, -0.11579f*height), new Vector2(-0.19000f*width, -0.23684f*height), new Vector2(+0.00000f*width, -0.00000f*height), }; vertices_list.add(vertices1); final Vector2[] vertices2 = { new Vector2(-0.19000f*width, -0.23684f*height), new Vector2(-0.00500f*width, -0.46316f*height), new Vector2(+0.00000f*width, -0.00000f*height), }; vertices_list.add(vertices2); final Vector2[] vertices3 = { new Vector2(-0.00500f*width, -0.46316f*height), new Vector2(+0.19000f*width, -0.26842f*height), new Vector2(+0.00000f*width, -0.00000f*height), }; vertices_list.add(vertices3); final Vector2[] vertices4 = { new Vector2(+0.19000f*width, -0.26842f*height), new Vector2(+0.45500f*width, -0.11579f*height), new Vector2(+0.00000f*width, -0.00000f*height), }; vertices_list.add(vertices4); final Vector2[] vertices5 = { new Vector2(+0.00000f*width, -0.00000f*height), new Vector2(+0.45500f*width, -0.11579f*height), new Vector2(+0.32000f*width, +0.14737f*height), }; vertices_list.add(vertices5); final Vector2[] vertices6 = { new Vector2(+0.00000f*width, -0.00000f*height), new Vector2(+0.32000f*width, +0.14737f*height), new Vector2(+0.30000f*width, +0.47368f*height), }; vertices_list.add(vertices6); final Vector2[] vertices7 = { new Vector2(+0.00000f*width, -0.00000f*height), new Vector2(+0.30000f*width, +0.47368f*height), new Vector2(-0.00500f*width, +0.41053f*height), }; vertices_list.add(vertices7); final Vector2[] vertices8 = { new Vector2(+0.00000f*width, -0.00000f*height), new Vector2(-0.00500f*width, +0.41053f*height), new Vector2(-0.28500f*width, +0.45789f*height), }; vertices_list.add(vertices8); final Vector2[] vertices9 = { new Vector2(-0.31500f*width, +0.14211f*height), new Vector2(+0.00000f*width, -0.00000f*height), new Vector2(-0.28500f*width, +0.45789f*height), }; vertices_list.add(vertices9); final Vector2[] vertices10 = { new Vector2(-0.46000f*width, -0.11579f*height), new Vector2(+0.00000f*width, -0.00000f*height), new Vector2(-0.31500f*width, +0.14211f*height), }; vertices_list.add(vertices10);
ここから、複数のVector2[]配列をshapeにしてBodyに登録していく部である。
BodyDef bDef = new BodyDef(); bDef.type = BodyType.DynamicBody; bDef.fixedRotation = false; //回転許可 bDef.position.x = sp.getX() / PIXEL_TO_METER_RATIO_DEFAULT; bDef.position.y = sp.getY() / PIXEL_TO_METER_RATIO_DEFAULT; Body body = this.mPhysicsWorld.createBody(bDef); for(Vector2[] v : vertices_list){ PolygonShape shape = new PolygonShape(); shape.set(v); FIXTURE_DEF.shape = shape; body.createFixture(FIXTURE_DEF); shape.dispose(); } attachChild(sp); this.mPhysicsWorld.registerPhysicsConnector(new PhysicsConnector(sp, body, true, true));
BodyDefでBody(Sprite)の回転許可や、静止物体なのか、動的物体なのかを定義する。
以上で、複数のVector2[]配列をBodyに登録し物理シミュレーションができる状態となるはずです。 補足
//複数のVertices[]配列のリストからBodyを生成 public static Body createVerticesListBody(final PhysicsWorld pPhysicsWorld, final IShape pShape, final ArrayList<Vector2[]> vertices_list , final BodyType pBodyType, final FixtureDef pFixtureDef) { final BodyDef boxBodyDef = new BodyDef(); boxBodyDef.type = pBodyType; final float[] sceneCenterCoordinates = pShape.getSceneCenterCoordinates(); boxBodyDef.position.x = sceneCenterCoordinates[Constants.VERTEX_INDEX_X] / PIXEL_TO_METER_RATIO_DEFAULT; boxBodyDef.position.y = sceneCenterCoordinates[Constants.VERTEX_INDEX_Y] / PIXEL_TO_METER_RATIO_DEFAULT; final Body boxBody = pPhysicsWorld.createBody(boxBodyDef); for(Vector2[] v : vertices_list){ final PolygonShape boxPoly = new PolygonShape(); boxPoly.set(v); pFixtureDef.shape = boxPoly; boxBody.createFixture(pFixtureDef); boxPoly.dispose(); } return boxBody; }
このクラスメソッドをPhysicsFactoryに追加し、定義クラスでも作って、スプライトごとのArrayListを吐き出して、このメソッドに投げてやれば、使いやすくなるんではないかと思います
One thought on “[AndEngine Box2d] 簡単なBody、複雑な形態のBodyをつくる その2”
Comments are closed.