java - Android LibGDX 2d 在碰撞、崩溃时删除项目

标签 java android libgdx

我尝试在与 StaticBody 的射击碰撞时删除/移除这个物体

        if ((fixtureB == obstacleFixture) && (fixtureA == shootFixture)) {
           // destroy();
            obstacleBody.destroyFixture(obstacleFixture);

        }

但是在这部分代码中,当有联系时,所有应用程序都崩溃了,不知道为什么。

File: /var/lib/jenkins/workspace/libgdx/extensions/gdx-box2d/gdx-box2d/jni/Box2D/Dynamics/b2Body.cpp, Line 216

Expression: m_world->IsLocked() == false

实际上,我对这个库有点迷茫,它基本上创建了一个三角形和一个矩形,当你点击时,射击,现在当射击与三角形碰撞时,三角形必须消失。而是直接跨过APP crash

public class Box2DScreen extends MyScreenAdapter {
    private World world;
    private Box2DDebugRenderer renderer;
    private OrthographicCamera camara;

    private Body playerBody;
    private Fixture playerFixture;

    private Body shootBody;
    private Fixture shootFixture;
    private Body floorBody;
    private Fixture floorFixture;
    private Body obstacleBody;
    private Fixture obstacleFixture;

    private boolean mustJump = false;
    private boolean isShooting = false;
    private boolean jumping = false;
    private boolean shooting = false;
    private boolean playerLive = true;

    public Box2DScreen(MainGame game) {
        super(game);
    }

    @Override
    public void show() {
        world = new World(new Vector2(0, -10), true);
        renderer = new Box2DDebugRenderer();
        camara = new OrthographicCamera(16.00f, 9.00f);
        camara.translate(0, 1);
        world.setContactListener(new ContactListener() {
            @Override
            public void beginContact(Contact contact) {
                Fixture fixtureA = contact.getFixtureA();
                Fixture fixtureB = contact.getFixtureB();

                if ((fixtureA.getUserData().equals("player")) && (fixtureB.getUserData().equals("floor"))) {
                    if (Gdx.input.isTouched()) {
                        mustJump = true;
                    }
                    jumping = false;
                }

                if ((fixtureA.getUserData().equals("floor")) && (fixtureB.getUserData().equals("player"))) {
                    if (Gdx.input.isTouched()) {
                        mustJump = true;
                    }
                    jumping = false;
                }
                if ((fixtureA.getUserData().equals("player")) && (fixtureB.getUserData().equals("obstacle"))) {
                    if (Gdx.input.isTouched()) {
                        playerLive = false;
                    }
                }
                if ((fixtureA.getUserData().equals("obstacle")) && (fixtureB.getUserData().equals("player"))) {
                    if (Gdx.input.isTouched()) {
                        playerLive = false;
                    }
                }

                if ((fixtureA.getUserData().equals("obstacle")) && (fixtureB.getUserData().equals("shoot"))) {
                    //destroy();
                        obstacleBody.destroyFixture(obstacleFixture);

                }
            }

            @Override
            public void endContact(Contact contact) {
                Fixture fixtureA = contact.getFixtureA();
                Fixture fixtureB = contact.getFixtureB();

                if ((fixtureA == playerFixture) && (fixtureB == floorFixture)) {
                    jumping = true;
                }
                if ((fixtureB == playerFixture) && (fixtureA == floorFixture)) {
                    jumping = true;
                }

                if ((fixtureA == shootFixture) && (fixtureB == obstacleFixture)) {
                  //  destroy();

                }
                if ((fixtureB == obstacleFixture) && (fixtureA == shootFixture)) {
                   // destroy();

                }

            }

            @Override
            public void preSolve(Contact contact, Manifold oldManifold) {

            }

            @Override
            public void postSolve(Contact contact, ContactImpulse impulse) {

            }
        });
        BodyDef playerBodyDef;
        playerBodyDef = createPlayerBodyDef();
        playerBody = world.createBody(playerBodyDef);
        PolygonShape playerShape = new PolygonShape();
        playerShape.setAsBox(0.5f, 0.5f);
        playerFixture = playerBody.createFixture(playerShape, 1);
        playerShape.dispose();

        BodyDef floorBodyDef;
        floorBodyDef = createFloorBodyDef();
        floorBody = world.createBody(floorBodyDef);
        PolygonShape floorShape = new PolygonShape();
        floorShape.setAsBox(500.00f, 1.00f);
        floorFixture = floorBody.createFixture(floorShape, 1);
        floorShape.dispose();

        BodyDef obstacleBodyDef;
        obstacleBodyDef = createObstacleBodyDef(6f);
        obstacleBody = world.createBody(obstacleBodyDef);
        obstacleFixture = createObstacleFixture(obstacleBody);


        playerFixture.setUserData("player");
        floorFixture.setUserData("floor");
        obstacleFixture.setUserData("obstacle");
    }


    private BodyDef createShootBodyDef() {
        BodyDef def = new BodyDef();
        def.position.set(playerBody.getPosition().x + 1f, playerBody.getPosition().y);
        def.type = BodyDef.BodyType.DynamicBody;
        def.gravityScale = 0;
        return def;
    }

    private Fixture createObstacleFixture(Body obstacle) {
        Vector2[] vertices = new Vector2[3];
        vertices[0] = new Vector2(-0.5f, -0.5f);
        vertices[1] = new Vector2(0.5f, -0.5f);
        vertices[2] = new Vector2(0, 0.5f);

        PolygonShape shape = new PolygonShape();
        shape.set(vertices);

        Fixture fix = obstacle.createFixture(shape, 1);
        shape.dispose();
        return fix;
    }

    private BodyDef createObstacleBodyDef(float x) {
        BodyDef def = new BodyDef();
        def.position.set(x, 0.5f);
        def.type = BodyDef.BodyType.StaticBody;

        return def;
    }

    private BodyDef createPlayerBodyDef() {
        BodyDef def = new BodyDef();
        def.position.set(0, 0.5f);
        def.type = BodyDef.BodyType.DynamicBody;
        return def;
    }

    private BodyDef createFloorBodyDef() {
        BodyDef def = new BodyDef();
        def.position.set(0, -1);
        def.type = BodyDef.BodyType.StaticBody;
        return def;
    }

    @Override
    public void dispose() {
        playerBody.destroyFixture(playerFixture);
        floorBody.destroyFixture(floorFixture);
        obstacleBody.destroyFixture(obstacleFixture);
        shootBody.destroyFixture(shootFixture);

        world.destroyBody(playerBody);
        world.destroyBody(floorBody);
        world.destroyBody(obstacleBody);
        world.destroyBody(shootBody);

        world.dispose();
        renderer.dispose();

    }

    @Override
    public void render(float delta) {
        Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);

        if (mustJump) {
            mustJump = false;
            saltar();
        }
        if (Gdx.input.justTouched() && !jumping) {
            mustJump = true;
        }
        if (Gdx.input.justTouched() && shooting) {
            destroy();
        }

        if (Gdx.input.justTouched() && !shooting) {
            BodyDef shootBodyDef;
            shootBodyDef = createShootBodyDef();
            shootBody = world.createBody(shootBodyDef);
            PolygonShape shootShape = new PolygonShape();
            shootShape.setAsBox(0.3f, 0.09f);
            shootFixture = shootBody.createFixture(shootShape, 1);
            shootShape.dispose();
            shootFixture.setUserData("shoot");
            shooting = true;
        }


        if (shooting) {
            float velocidadY = shootBody.getLinearVelocity().y;
            shootBody.setLinearVelocity(6, velocidadY);
        }
        if (playerLive) {
            float velocidadY = playerBody.getLinearVelocity().y;
            playerBody.setLinearVelocity((float) 0.7, velocidadY);
        }


        world.step(delta, 6, 2);
        camara.update();
        renderer.render(world, camara.combined);
    }

    private void saltar() {
        Vector2 position = playerBody.getPosition();
        playerBody.applyLinearImpulse(0, 6, position.x, position.y, true);
    }
    private void destroy(){
        shooting = false;
        shootBody.destroyFixture(shootFixture);
        world.destroyBody(shootBody);
    }
}

最佳答案

你不能在碰撞时移除物体,box2d 正在做数学运算,如果你移除它会发疯,最好的方法是设置 setActive(false) 并在稍后的迭代中移除它你的渲染方法,像这样:

            [...]
private List<Fixture> lstRemoveFixture = new ArrayList<>();
            [...]
            @Override
            public void beginContact(Contact contact) {
                Fixture fixtureA = contact.getFixtureA();
                Fixture fixtureB = contact.getFixtureB();

               if(fixtureA != null and fixtureB != null){
                     [...]
                     if ((fixtureA.getUserData().equals("obstacle")) && (fixtureB.getUserData().equals("shoot"))) {
                         //destroy();
                        obstacleBody.setActive(false);
                        lstRemoveFixture.add(obstacleFixture);
                      }
               }
            }

在你的渲染方法上:

public void render(float delta) {
      [...]
         world.step(delta, 6, 2);
         for(Fixture fixture : lstRemoveFixture){
             obstacleBody.destroyFixture(fixture);
             lstRemoveFixture.remove(fixture);
         }
         obstacleBody.setActive(true);
      [...]
  }

关于java - Android LibGDX 2d 在碰撞、崩溃时删除项目,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35339875/

相关文章:

java - Android编程使用旧变量定义新变量?

android - 音频过滤安卓

java - 使用 libgdx 和 mt4j 在 Java 中跨平台多点触控和图形

android - 如何使用 libgdx 显示矢量化文本?

java - 使用静态 block 打印一些东西

java - 如何从 mongodb 或 java 查询 prolog 中的文件

java - 基本 libGDX 项目运行速度为 47-48 fps

php - 我如何实现在我的应用程序上选择图像并将其发送到远程数据库(JSON+PHP)的可能性?

android - 将 ImageView 与布局中心向左对齐 10dp

java - LIBGDX - 碰撞问题和滑动效果问题