2013-07-27 35 views
0

發生什麼事每個人,如何處理libGDX的Box2D ContactListener中的空指針異常?

我通過libGDX在Box2D啓發式地生產Pong克隆。空指針異常來自ContactListener的beginContact()方法,我試圖實現評分邏輯。

Box2D世界使用兩個獨立的EdgeShapes作爲傳感器,用於在與球碰撞時遞增得分變量(查看附加圖像)。 Ball和兩個EdgeShapes之間的碰撞邏輯工作正常,但Ball2和Box2D世界中的任何其他碰撞都會使程序崩潰。

enter image description here

堆棧跟蹤:

Exception in thread "LWJGL Application" java.lang.NullPointerException 
at com.ckq3r.Pong.screens.GameScreen$2.beginContact(GameScreen.java:491) 
at com.badlogic.gdx.physics.box2d.World.beginContact(World.java:876) 
at com.badlogic.gdx.physics.box2d.World.jniStep(Native Method) 
at com.badlogic.gdx.physics.box2d.World.step(World.java:602) 
at com.ckq3r.Pong.screens.GameScreen.render(GameScreen.java:99) 
at com.badlogic.gdx.Game.render(Game.java:46) 
at com.ckq3r.Pong.PongGame.render(PongGame.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) 

有問題的代碼:

/**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"); 
       score1++; 
       score1String = score1 + ""; 
      } 

      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"); 
       score2++; 
       score2String = score2 + ""; 
      } 
     } 

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

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

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

     }); 
} 

注:

  1. 當我註釋掉beginContact中的兩個條件語句() 我代碼運行。未註釋時,錯誤被重現。
  2. Ball userData是circleBody.setUserData(1);
  3. goal1 userData是goalBody.setUserData(2);
  4. goal2 userData是goalBody.setUserData(3);
+0

這是行491? – JBuenoJr

+1

下面的一個或多個函數返回'null':fixtureA.getBody()或fixtureA.getBody()。getUserData()或等效的fixtureB方法。應該getBody()或getUserData()總是返回一個值?如果他們返回null,這意味着什麼? – HeatfanJohn

+0

@JosephBueno第491行是beginContact()方法中的第一條if語句。謝謝回覆。 – HACKQ3R

回答

1

爲Box2D世界中的每個實體設置userdata,以便您可以使用ContactListener中的條件邏輯來評估是否應該處理碰撞。

重點在下面的行paddleBody.setUserData(4);。您可以選擇任意數字來設置單個對象的用戶數據,只要該數字與您的世界中其他對象的用戶數據相同即可。

例如:

/**paddle1**/ 
    BodyDef paddleDef = new BodyDef(); 
    paddleDef.type = BodyType.DynamicBody; 
    paddleDef.position.set(width * 0.2f, height/2); 
    paddleDef.fixedRotation = true; 

    Body paddleBody = world.createBody(paddleDef); 
    paddleBody.setUserData(4); 

    PolygonShape paddleShape = new PolygonShape(); 
    paddleShape.setAsBox(3.0f, 15.0f); //half-width and half-height 

    FixtureDef paddleFD = new FixtureDef(); 
    paddleFD.shape = paddleShape; 
    paddleFD.density = 10.0f; 
    paddleFD.friction = 0.0f; 
    paddleFD.restitution = 0.1f; 

    paddleBody.createFixture(paddleFD); 

    paddleShape.dispose(); 

    paddleBody.setLinearVelocity(0.0f, 0.0f); 
    /**end paddle1**/ 

    /**paddle2**/ 
    BodyDef paddleDef2 = new BodyDef(); 
    paddleDef2.type = BodyType.DynamicBody; 
    paddleDef2.position.set(width * 0.8f, height/2); 
    paddleDef2.fixedRotation = true;   

    Body paddleBody2 = world.createBody(paddleDef2); 
    paddleBody2.setUserData(5);    

    PolygonShape paddleShape2 = new PolygonShape(); 
    paddleShape2.setAsBox(3.0f, 15.0f); //half-width and half-height 

    FixtureDef paddleFD2 = new FixtureDef(); 
    paddleFD2.shape = paddleShape2; 
    paddleFD2.density = 10.0f; 
    paddleFD2.friction = 0.0f; 
    paddleFD2.restitution = 0.1f; 

    paddleBody2.createFixture(paddleFD2); 

    paddleShape2.dispose(); 

    paddleBody2.setLinearVelocity(0.0f, 0.0f); // Move nowhere at a rate of x = 0.0f, y = 0.0f meters per second 
    /**end paddle2**/