謝謝你的時間。libGDX Box2D:碰撞後如何摧毀身體?
我使用Box2D通過libGDX創建Pong克隆。由於球體與兩個球門傳感器機構之一接觸而導致刪除球體(下圖)時,我遇到了一個導致空指針異常的粘滯點。
我想添加聯繫球體到一個列表中,以便我稍後可以遍歷列表以刪除球體(以及將來的多個球體)。
堆棧跟蹤:
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*/
}
}
});
我的邏輯是一個球體和目標傳感器主體之間的接觸,如下所示:
- 從ContactListener的beginContact()方法內,球體與EdgeShape傳感器接觸身體將是添加到
ArrayList<Body> ballDeletionList = new ArrayList<Body>();
和scoredGoal1 = true;
布爾標誌將被設置爲true。 - 在
render();
檢查scoredGoal1 = true
或scoredGoal2 = true
然後刪除相應的身體/的world.step()
方法後機構。
我在整個網絡中搜索了其他代碼示例和教程,只是爲了找到含糊不清的答案,因爲代碼是案例專業化的,或者我目前只理解Java。
如果可以發佈Java/libGDX代碼示例解決方案,那將會很棒。