0
\$\begingroup\$

I have a class named Meteor and I created a function that create Meteors all the time, and I have a Player class.

The collision between the Player and Meteor works fine, but the game crashes when a collision between two meteors occurs.

I don't know why the crash occurs and I want to fix it.

Meteor Class

public class Meteor  {

String[] meteorNames = new String[]{"meteorBrown_big1", "meteorBrown_big2", "meteorBrown_big3",
        "meteorBrown_big4", "meteorBrown_med3", "meteorGrey_big1", "meteorGrey_big2",
        "meteorGrey_big3", "meteorGrey_big4", "meteorGrey_med2"};

HashMap<String, Sprite> map;
    World world;
    public Body body;
    public Sprite meteorSprite;
    String name;
    public Boolean destroyed = false;

public Meteor(World world, HashMap<String, Sprite> map){

    this.world = world;
    this.map = map;
    Random random = new Random();
    name = meteorNames[random.nextInt(meteorNames.length)];
    meteorSprite = map.get(name);
    defineMeteor();

}

public void drawMeteor(SpriteBatch batch){
    if(!isDestroyed()){
        meteorSprite.setPosition(body.getPosition().x, body.getPosition().y);
        meteorSprite.setRotation((float) Math.toDegrees(body.getAngle()));
        meteorSprite.setOrigin(0, 0);
        meteorSprite.draw(batch);
    }

}

private void defineMeteor(){

    BodyEditorLoader loader = new BodyEditorLoader(Gdx.files.internal("data/meteors/meteors.json"));
    //Create the body
    BodyDef bodyDef =  new BodyDef();

    bodyDef.type = BodyDef.BodyType.DynamicBody;

    bodyDef.position.set(100, 200);

    //Set the physics properties
    FixtureDef fixtureDef = new FixtureDef();
    fixtureDef.density = 4 * meteorSprite.getWidth();
    fixtureDef.restitution = 0.6f;
    fixtureDef.friction = 0.2f;

    body = world.createBody(bodyDef);

    //Random location to create a meteor in x axis
    Random r1 = new Random();

    int High = (int) ( Gdx.graphics.getWidth() * 0.5);
    int Low = (int) (-Gdx.graphics.getWidth() * 0.5);
    int r2 = r1.nextInt(High - Low) + Low;
    //body.setTransform(r2, Gdx.graphics.getHeight() * 0.5f, 0);
    body.setTransform(0, 50 * 0.5f, 0);
    body.setUserData(Meteor.this);

    //Random Vx and Vy
    r1 = new Random();
    r2 = r1.nextInt(3);
    r1 = new Random();
    int r3 = r1.nextInt(40);
    body.setLinearVelocity(0, -r3);
    body.setAngularVelocity(-r2);

    loader.attachFixture(body, name + ".png", fixtureDef, meteorSprite.getWidth());

    //Create sensor
    fixtureDef.isSensor = true;
    FixtureDef fDef = fixtureDef;
    fDef.isSensor = true;
    fDef.filter.categoryBits = MyGdxGame.METEOR_BIT;
    fDef.filter.maskBits = MyGdxGame.SHIP_BIT | MyGdxGame.METEOR_BIT;
    loader.attachFixture(body, name + ".png", fDef, meteorSprite.getWidth());
    //body.getFixtureList().get(body.getFixtureList().size-1).setUserData("meteorSensor");


}

public void setToDestroy(){
    destroyed = true;
}

public Boolean isDestroyed(){
    return destroyed;
}

ContactLisneter Class

public class ContactGameListener implements com.badlogic.gdx.physics.box2d.ContactListener {

@Override
public void beginContact(Contact contact) {

    Fixture fixA = contact.getFixtureA();
    Fixture fixB = contact.getFixtureB();

    int cDef = fixA.getFilterData().categoryBits | fixB.getFilterData().categoryBits;


    switch (cDef){
        case MyGdxGame.SHIP_BIT | MyGdxGame.METEOR_BIT:
            if(fixA.getFilterData().categoryBits == MyGdxGame.SHIP_BIT){
                ((Player)fixA.getBody().getUserData()).life -=1;
                ((Player)fixA.getBody().getUserData()).score +=1;
            }

            else {
                ((Player)fixB.getBody().getUserData()).life -=1;
                ((Player)fixB.getBody().getUserData()).score +=1;
            }
            break;
        case MyGdxGame.METEOR_BIT | MyGdxGame.METEOR_BIT:
            Gdx.app.log("Meteoro", "meteoro");
            fixA.getBody().setTransform(fixA.getBody().getPosition().x, fixA.getBody().getPosition().y, fixA.getBody().getAngle());
            fixB.getBody().setTransform(fixB.getBody().getPosition().x, fixB.getBody().getPosition().y, fixB.getBody().getAngle());
            break;

    }

Error found

A/art: art/runtime/check_jni.cc:70] JNI DETECTED ERROR IN APPLICATION: JNI CallVoidMethodV called with pending exception 'java.lang.ClassCastException' thrown in unknown throw location
A/art: art/runtime/check_jni.cc:70]     in call to CallVoidMethodV
A/art: art/runtime/check_jni.cc:70]     from void com.badlogic.gdx.physics.box2d.World.jniStep(long, float, int, int)
A/art: art/runtime/check_jni.cc:70] "GLThread 67293" prio=5 tid=14 Runnable
A/art: art/runtime/check_jni.cc:70]   at com.badlogic.gdx.physics.box2d.World.step(World.java:689)
A/art: art/runtime/check_jni.cc:70]   at com.mygdx.game.libgdx.Screens.GameScreen.stepWorld(GameScreen.java:248)
A/art: art/runtime/check_jni.cc:70]   at com.mygdx.game.libgdx.Screens.GameScreen.render(GameScreen.java:139)
A/art: art/runtime/check_jni.cc:70]   at com.badlogic.gdx.Game.render(Game.java:46)
A/art: art/runtime/check_jni.cc:70]   at com.mygdx.game.libgdx.Screens.MyGdxGame.render(MyGdxGame.java:101)

MyGdxGame.java:101:

@Override
    public void render() {
        super.render(); //101
    }

GameScreen.java:248:

world.step(STEP_TIME, VELOCITY_ITERATIONS, POSITION_ITERATIONS); // 248
\$\endgroup\$
0
\$\begingroup\$

When two meteors collide you set the transform of each body to the transform of the colliding fixtures, I am not sure why you would want to do that or what you hope to achieve.

Regardless, you're not allowed to mutate the state of the bodies or fixtures while the World step is being executed, which it still is when the contact listener call-back fires. You need to perform such actions outside the call to step.

\$\endgroup\$
  • \$\begingroup\$ Thanks to your response I could fix it, I remove all the .setTransform from the code, even in the Meteor.class.I added the follow if statment to check twice my fixtures objects if(ship.getBody().getUserData().getClass().equals(Player.class)) and works fine \$\endgroup\$ – Yan Henning Feb 18 '17 at 19:49

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.