Pergunta

I have written the following code to destroy a particular object after collision by calculating its impulse force but the game crashes whenever it tries to destroy the object showing an error : Assertion failed: (IsLocked() == false), function DestroyBody, file /Users/badlogic/jenkins/workspace/libgdx-mac/gdx/jni/Box2D/Dynamics/b2World.cpp, line 134.

Kindly Help. Thanks in advance.

package com.me.mygdxgame;

import com.badlogic.gdx.ApplicationListener;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.GL30;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.Sprite;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.physics.box2d.Box2DDebugRenderer;
import com.badlogic.gdx.physics.box2d.Contact;
import com.badlogic.gdx.physics.box2d.ContactImpulse;
import com.badlogic.gdx.physics.box2d.ContactListener;
import com.badlogic.gdx.physics.box2d.Manifold;

public class MyGdxGame implements ApplicationListener {

private Levels level1;
private Box2DDebugRenderer renderer;
private Vector2 groundPositionLeft, groundPositionRight;
private SpriteBatch batch;
private Sprite sprite;
private boolean[] a;
private Input input;
private ContactListener conlis;

@Override
public void create() {
    contactlistener();
    level1 = new Levels();
    renderer = new Box2DDebugRenderer();
    batch = new SpriteBatch();
    input = new Input() {
    };
    groundPositionLeft = new Vector2(
            (-0.04f * Gdx.graphics.getWidth() / 2f), -28 / 720f
                    * Gdx.graphics.getHeight() / 2f * (6 / 7f));
    groundPositionRight = new Vector2(0.04f * Gdx.graphics.getWidth() / 2f,
            -28 / 720f * Gdx.graphics.getHeight() / 2f * (6 / 7f));
    level1.createIceHor(0, groundPositionLeft.y + 11.25f);
    sprite = new Sprite(new Texture("img/Metal.jpg"));
    sprite.setSize(4.5f, 2f);
    sprite.setOrigin(sprite.getWidth() / 2f, sprite.getHeight() / 2f);

}

@Override
public void dispose() {
}

@Override
public void render() {
    Gdx.gl.glClearColor(1, 1, 1, 1);
    Gdx.gl.glClear(GL30.GL_COLOR_BUFFER_BIT);
    level1.worldStep();

    batch.setProjectionMatrix(level1.getCamera().combined);
    batch.begin();
    batch.end();
    renderer.render(level1.getLevel(), level1.getCamera().combined);
    level1.getLevel().setContactListener(conlis);
    Gdx.input.setInputProcessor(input);

}

@Override
public void resize(int width, int height) {
}

@Override
public void pause() {
}

@Override
public void resume() {
}

private void contactlistener() {
    conlis = new ContactListener() {

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

        }

        @Override
        public void postSolve(Contact contact, ContactImpulse impulse) {
            // System.out.println(impulse.getNormalImpulses()[0]);
            if (impulse.getNormalImpulses()[0] >= 22.648895f) {
                if (contact.getFixtureA().getFriction() == 0.1f) {
                    level1.getLevel().destroyBody(
                            contact.getFixtureA().getBody());
                } else {
                    level1.getLevel().destroyBody(
                            contact.getFixtureB().getBody());
                }

            }
        }

        @Override
        public void endContact(Contact contact) {

        }

        @Override
        public void beginContact(Contact contact) {
        }
    };
}

}

Foi útil?

Solução

Have a look at this. It's written for C++ but the general concept still applies.

You aren't allowed to destroy anything while Box2D is doing the simulation step. Your ContactListener is called while this simulation is happening and you instantly destroy the body. That's not allowed. You have to store the bodies to be destroyed and do that right after world.step.

Here you can see how it is done as a quick solution in the tests, but it might not be the best solution.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top