[AndEngine Box2d] 簡単なBody、複雑な形態のBodyをつくる その2

(2)複数のVector2[]配列からBody.を作りSpriteと関連付ける(複雑な形態のBody)

まず、どうやって複数のVector2[]をBodyに渡すのかが、意外に情報がない。初めはBodyをjointでつなごうと思ったが、どうもちがうらしい。同じ悩みをもつサイトにいきついた。

http://morishin127.tumblr.com/post/46425988233/ioscocos2d-box2d%E8%A4%87%E6%95%B0%E3%81%AE%E5%9B%B3%E5%BD%A2%E3%82%92%E7%B5%84%E3%81%BF%E5%90%88%E3%82%8F%E3%81%9B%E3%82%8B

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)の回転許可や、静止物体なのか、動的物体なのかを定義する。 名称未設定-1

以上で、複数の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.