libGDX Box2D: Wie zerstören Körper nach dem Stoß?

Vielen Dank für Ihre Zeit.

Erstelle ich ein Pong-Klon mit Box2D über libGDX. Wenn Sie versuchen, löschen Sie den Ball-Körper als Ergebnis des Ball-Körper-Kontakt mit einer der beiden Ziel-Sensor-Körper (Bild unten), ich habe ein Knackpunkt, dass die Ergebnisse in eine Null-Zeiger-Ausnahme.

Möchte ich hinzufügen, dass die Kontaktaufnahme mit dem Ball Körper zu einer Liste, so dass ich später die Liste Durchlaufen, um zu löschen den Ball (Körper und Ball mehrere stellen in der Zukunft).

libGDX Box2D: Wie zerstören Körper nach dem Stoß?

Den stack-trace:

Exception in thread "LWJGL Application" java.lang.NullPointerException
at com.badlogic.gdx.physics.box2d.World.destroyBody(World.java:311)
at com.ckq3r.Ponger.screens.GameScreen.update(GameScreen.java:484)
at com.ckq3r.Ponger.screens.GameScreen.render(GameScreen.java:114)
at com.badlogic.gdx.Game.render(Game.java:46)
at com.ckq3r.Ponger.PongerGame.render(PongerGame.java:236)
at com.badlogic.gdx.backends.lwjgl.LwjglApplication.mainLoop(LwjglApplication.java:204)
at com.badlogic.gdx.backends.lwjgl.LwjglApplication$1.run(LwjglApplication.java:112)

Line 484, in meinem GameScreen-Klasse ist die Linie world.destroyBody(circleBody); befindet sich innerhalb der if(scoredGoal1 == true){stuff} bedingte Anweisung des public void render(float delta){stuff} Methode unten dargestellt.

public class GameScreen implements Screen, InputProcessor{

/*----methods and variables omitted for readability------*/

private boolean scoredGoal1 = false, scoredGoal2 = false;
ArrayList<Body> ballDeletionList = new ArrayList<Body>();

/*==============Screen implementation methods============*/
    @Override
    public void show(){
        /*ball*/
        BodyDef circleDef = new BodyDef();      
        Body circleBody = world.createBody(circleDef);
        circleBody.setUserData(1);              
        CircleShape circleShape = new CircleShape();                
        FixtureDef circleFixture = new FixtureDef();
        circleFixture.shape = circleShape;              
        circleBody.createFixture(circleFixture);        
        circleShape.dispose();
    }

    @Override
    public void render(float delta) {           
        world.step(Gdx.app.getGraphics().getDeltaTime(), 8, 3);
        Gdx.gl.glClearColor(0, 0, 0, 1); 
        Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
        camera.update();
        debugRenderer.render(world, camera.combined);

        /*-------ball deletion experiment-------*/          
        if(scoredGoal1 == true){

            //iterate through ballDeletionList somehow?

            world.destroyBody(circleBody);                            
            circleBody.setUserData(null);
            circleBody = null;                              
            scoredGoal1 = false;
            //clear ballDeletionList

        }else if(scoredGoal2 == true){

            //iterate through ballDeletionList somehow?

            world.destroyBody(circleBody);
            circleBody.setUserData(null);
            circleBody = null;              
            scoredGoal2 = false;
            //clear ballDeletionList
        }
        /*-----end ball deletion experiment------*/
}   

/*===========Box2D contact listener=============*/
    private void createContactListener() {
        world.setContactListener(new ContactListener() {

        @Override
        public void beginContact(Contact contact) {
            Fixture fixtureA = contact.getFixtureA();
            Fixture fixtureB = contact.getFixtureB();
            Gdx.app.log("beginContact", "between " + fixtureA.toString() + " and " + fixtureB.toString());

            if(fixtureA.getBody().getUserData().equals(1) && fixtureB.getBody().getUserData().equals(2) || fixtureA.getBody().getUserData().equals(2) && fixtureB.getBody().getUserData().equals(1)){
                Gdx.app.log("HIT", "goal1 contact");

                /*ball deletion experiment*/
                ballDeletionList.add(circleBody);
                Gdx.app.log("Ball", "circleBody added to deletion list");
                scoredGoal1 = true;
                /*ball deletion experiment*/
            }         

            if(fixtureA.getBody().getUserData().equals(1) && fixtureB.getBody().getUserData().equals(3) || fixtureA.getBody().getUserData().equals(3) && fixtureB.getBody().getUserData().equals(1)){
                Gdx.app.log("HIT", "goal2 contact");

                /*ball deletion experiment*/
                ballDeletionList.add(circleBody);
                Gdx.app.log("Ball", "circleBody added to deletion list");
                scoredGoal2 = true;
                /*ball deletion experiment*/
            }
        }                

        });

Meine Logik ist wie folgt auf den Kontakt zwischen einer Kugel-Körper und einen Ziel-Sensor-Körper:

  1. Innerhalb der ContactListener ist beginContact () - Methode, die Ball-Körper-Kontaktaufnahme mit dem EdgeShape Sensor-Körper Hinzugefügt werden, um die ArrayList<Body> ballDeletionList = new ArrayList<Body>(); und die scoredGoal1 = true; boolean-flag wird auf true gesetzt werden.
  2. In der render(); check für scoredGoal1 = true oder scoredGoal2 = true dann löschen Sie die geltenden Body/Körper nach der world.step() Methode.

Gesucht hab ich in anderen code-Beispiele und tutorials im web nur, um Antworten zu finden, die mehrdeutig sind, weil entweder das war der code für den Fall spezielle oder ich verstehe nur Java, zumindest im moment.

Wäre es toll, wenn ein Java/libGDX-code-Beispiel-Lösung veröffentlicht werden.

InformationsquelleAutor HACKQ3R | 2013-08-05

Schreibe einen Kommentar