4.Libgdx扩展学习之Box2D_创建多边形刚体和圆角矩形

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/zqiang_55/article/details/53465321

主要是根据这2篇博客来写的
1. http://bbs.9ria.com/thread-136661-1-1.html
2. http://bbs.9ria.com/thread-136794-1-1.html

前面的博客主要介绍了Box2D的主要概念,让我们熟悉了Box2D的主要框架。但是在现实生活中我们的遇到的物体时各种各样的,需要创造更复杂的刚体。
下面主要介绍了2中方法来创建:
1. 组合法。
前面的Shape形状比较简单(其实PolygonShape本身也可以很复杂,但是我们一般用其创建矩形,第二种方法就是用它画的),但是复杂的形状其实就是用简单的形状组合完成的,具体可以看下面的图片展示:
圆角矩形其实就是2个矩形和4个圆形组成的组合,实现原理可以看代码的注释
2. 原生法
上面也介绍到了Polygon本身可以指定不同的顶点来创造不同的凸多边形。代码中我们展示了怎样创造一个三角形。

方法比较

组合法创建的刚体中有多个图形,所以在Box2D模拟碰撞检测时,就会对图形进行逐个检测计算。而原生法的刚体只有一个图形,所以只需要一次碰撞检测计算,计算效率相对更高一些。

public class ComplexBody extends ApplicationAdapter {

    World world;
    Box2DDebugRenderer box2DDebugRenderer;

    OrthographicCamera camera;

    float scene_width = 12.8f;
    float scene_height = 7.2f;

    @Override
    public void create() {
        world = new World(new Vector2(0.0f, -9.8f), true);
        box2DDebugRenderer = new Box2DDebugRenderer();

        createGround();
        createTriangle();
        createComplexBody(2.0f, 2.0f);
        createRoundBody();

        camera = new OrthographicCamera(scene_width, scene_height);
        camera.position.set(scene_width / 2, scene_height / 2, 0);
        camera.update();

        Gdx.input.setInputProcessor(new InputHandA());
    }

    @Override
    public void dispose() {
        world.dispose();
        box2DDebugRenderer.dispose();
    }

    @Override
    public void render() {
        world.step( 1/ 60f, 6, 2);

        Gdx.gl.glClearColor(0.39f, 0.58f, 0.92f, 1.0f);
        Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);

        box2DDebugRenderer.render(world, camera.combined);
    }

    private void createComplexBody(float px, float py) {
        BodyDef bodyDef = new BodyDef();
        bodyDef.type = BodyDef.BodyType.DynamicBody;
        bodyDef.position.set(px, py);

        Body body = world.createBody(bodyDef);

        PolygonShape polygonShape = new PolygonShape();
        polygonShape.setAsBox(0.5f, 0.5f);

        FixtureDef fixtureDef = new FixtureDef();
        fixtureDef.shape = polygonShape;
        fixtureDef.density = 3.0f;
        fixtureDef.restitution = 0.4f;

        body.createFixture(fixtureDef);

        polygonShape.setAsBox(0.5f, 0.5f, new Vector2(0.0f, 1.0f), 0.0f);
        fixtureDef.shape = polygonShape;
        body.createFixture(fixtureDef);

        polygonShape.setAsBox(0.5f, 0.5f, new Vector2(1.0f, 0.0f), 0.0f);
        fixtureDef.shape = polygonShape;
        body.createFixture(fixtureDef);

        polygonShape.dispose();
    }

    private void createGround() {
        BodyDef goundBodyDef = new BodyDef();
        goundBodyDef.position.set(scene_width * 0.5f, 0.5f);

        Body groundBody = world.createBody(goundBodyDef);

        PolygonShape groundBox = new PolygonShape();
        groundBox.setAsBox(scene_width * 0.5f, 0.5f);

        groundBody.createFixture(groundBox, 0);
        groundBox.dispose();
    }

    private void createTriangle() {
        BodyDef bodyDef = new BodyDef();
        bodyDef.type = BodyDef.BodyType.DynamicBody;
        bodyDef.position.set(7, 5);
        Body body = world.createBody(bodyDef);

        PolygonShape polygonShape = new PolygonShape();
        Vector2[] vertices = new Vector2[3];
        vertices[0] = new Vector2(0, 0);
        vertices[1] = new Vector2(1, 1);
        vertices[2] = new Vector2(2, 0);
        polygonShape.set(vertices);

        FixtureDef fixtureDef = new FixtureDef();
        fixtureDef.shape = polygonShape;
        fixtureDef.density = 1.0f;
        fixtureDef.restitution = 1.0f;
        body.createFixture(fixtureDef);
        polygonShape.dispose();
    }

    private void createRoundBody() {
        BodyDef bodyDef = new BodyDef();
        bodyDef.type = BodyDef.BodyType.DynamicBody;
        bodyDef.position.set(5, 3);
        Body body = world.createBody(bodyDef);

        // 创建2个矩形,分别把它们的高和宽减去radius, 留给圆角用
        PolygonShape polygonShape = new PolygonShape();
        polygonShape.setAsBox(0.5f, 0.5f - 0.1f);

        FixtureDef fixtureDef = new FixtureDef();
        fixtureDef.shape = polygonShape;
        fixtureDef.density = 1.0f;
        fixtureDef.restitution = 0.8f;
        body.createFixture(fixtureDef);

        polygonShape.setAsBox(0.5f - 0.1f, 0.5f);
        body.createFixture(fixtureDef);

        // 分别在4个角上创建四个圆形实现圆角效果
        CircleShape circleShape = new CircleShape();
        fixtureDef.shape = circleShape;
        fixtureDef.density = 1.0f;
        fixtureDef.restitution = 1.0f;
        circleShape.setRadius(0.1f);
        circleShape.setPosition(new Vector2(0.4f, 0.4f));
        body.createFixture(fixtureDef);

        circleShape.setPosition(new Vector2(0.4f, -0.4f));
        body.createFixture(fixtureDef);

        circleShape.setPosition(new Vector2(-0.4f, -0.4f));
        body.createFixture(fixtureDef);

        circleShape.setPosition(new Vector2(-0.4f, 0.4f));
        body.createFixture(fixtureDef);
    }

    private  class InputHandA extends InputAdapter {
        @Override
        public boolean touchDown(int screenX, int screenY, int pointer, int button) {
            // 在屏幕点击出创建响应的组合Body
            Vector3 vector3 = new Vector3(screenX, screenY, 0);
            camera.unproject(vector3);
            createComplexBody(vector3.x, vector3.y);
            return true;
        }
    }
}

这里写图片描述

猜你喜欢

转载自blog.csdn.net/zqiang_55/article/details/53465321
今日推荐