2013-08-05 63 views
1

謝謝你的時間。libGDX Box2D:碰撞後如何摧毀身體?

我使用Box2D通過libGDX創建Pong克隆。由於球體與兩個球門傳感器機構之一接觸而導致刪除球體(下圖)時,我遇到了一個導致空指針異常的粘滯點。

我想添加聯繫球體到一個列表中,以便我稍後可以遍歷列表以刪除球體(以及將來的多個球體)。

enter image description here

堆棧跟蹤:

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) 

線484在我GameScreen類是駐留下面所示的方法public void render(float delta){stuff}if(scoredGoal1 == true){stuff}條件語句中的線world.destroyBody(circleBody);

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*/ 
      } 
     }     

     }); 

我的邏輯是一個球體和目標傳感器主體之間的接觸,如下所示:

  1. 從ContactListener的beginContact()方法內,球體與EdgeShape傳感器接觸身體將是添加到ArrayList<Body> ballDeletionList = new ArrayList<Body>();scoredGoal1 = true;布爾標誌將被設置爲true。
  2. render();檢查scoredGoal1 = truescoredGoal2 = true然後刪除相應的身體/的world.step()方法後機構。

我在整個網絡中搜索了其他代碼示例和教程,只是爲了找到含糊不清的答案,因爲代碼是案例專業化的,或者我目前只理解Java。

如果可以發佈Java/libGDX代碼示例解決方案,那將會很棒。

回答