我正在使用Libgdx的box2d实现。
我从世界中删除了一个正文后遇到空指针错误。我已将问题跟踪到我的联系人监听器,我正在测试夹具的过滤器与另一个夹具,以查看是否应该处理碰撞。问题是其中一个灯具是空的。最初你会想,好吧所以只处理非空夹具的碰撞,但是如果我不知道夹具是什么结束了接触,就不可能知道什么是和非接触非空夹具。
在我进入代码之前,我保证通过将主体添加到稍后要处理的队列中来使实际的world.destroyBody(body)调用物理步骤之外。此外,主体在更新循环中排队,这发生在world.step()
之前(注意:实体基本上是主体的包装器)
这是主要的更新循环
@Override
public void render() {
processDestroyQueue();
sm.update(); //Calls entity update functions, where the entity is added to the q
camera.update();
//Step
world.step(STEP, 6, 2); //Step == 1/60f
//... removed rendering stuff
}
这是add to queue function和processDestroyQueue()
public void destroy(Entity ent){
destroyQueue.add(ent);
}
private void processDestroyQueue(){
Entity ent;
while((ent = destroyQueue.poll()) != null){
world.destroyBody(ent.body());
ent.dispose();
entities.remove(ent);
}
}
最后这里是联系处理程序
public class ContactHandler implements ContactListener {
@Override
public void beginContact(Contact contact) {
Fixture fixA = contact.getFixtureA();
Fixture fixB = contact.getFixtureB();
parseContact(true, fixA, fixB, contact);
}
@Override
public void endContact(Contact contact) {
Fixture fixA = contact.getFixtureA();
Fixture fixB = contact.getFixtureB();
parseContact(false, fixA, fixB, contact);
}
@Override
public void preSolve(Contact contact, Manifold oldManifold) {
// TODO Auto-generated method stub
}
@Override
public void postSolve(Contact contact, ContactImpulse impulse) {
// TODO Auto-generated method stub
}
public void parseContact(boolean begin, Fixture fixA, Fixture fixB, Contact contact){
System.out.println("FixtureA: " + fixA);
System.out.println("FixtureB: " + fixB);
if( (fixA.getFilterData().categoryBits & fixB.getFilterData().maskBits) != 0 ){
sendContact(begin, fixA, fixB, contact);
sendContact(begin, fixB, fixA, contact);
}else if( (fixB.getFilterData().categoryBits & fixA.getFilterData().maskBits) != 0 ){
sendContact(begin, fixA, fixB, contact);
sendContact(begin, fixB, fixA, contact);
}
}
public void sendContact(boolean begin, Fixture fixA, Fixture fixB, Contact contact){
Object dataA = fixA.getUserData();
Object dataB = fixB.getUserData();
if(dataA instanceof FixtureData && dataB instanceof FixtureData){
FixtureData fixtureDataB = (FixtureData)dataB;
FixtureData fixtureDataA = (FixtureData)dataA;
fixtureDataA.contact(fixB, contact, begin);
fixtureDataB.contact(fixA, contact, begin);
}
}
}
最后是错误:
Exception in thread "LWJGL Application" java.lang.NullPointerException
at com.gearworks.game.ContactHandler.parseContact(ContactHandler.java:42)
at com.gearworks.game.ContactHandler.endContact(ContactHandler.java:24)
at com.badlogic.gdx.physics.box2d.World.endContact(World.java:903)
at com.badlogic.gdx.physics.box2d.World.jniDestroyBody(Native Method)
at com.badlogic.gdx.physics.box2d.World.destroyBody(World.java:322)
at com.gearworks.Client.processDestroyQueue(Client.java:189)
at com.gearworks.Client.render(Client.java:118)
at com.badlogic.gdx.backends.lwjgl.LwjglApplication.mainLoop(LwjglApplication.java:206)
at com.badlogic.gdx.backends.lwjgl.LwjglApplication$1.run(LwjglApplication.java:114)
从它的外观来看,Box2D只是擦除了夹具,然后调度它的结束接触事件。我需要该夹具才能最终接触,以便我知道哪个夹具已完成其接触。我的实施错了吗?或者这就是box2D如何工作,我需要弄清楚其他一些方法?
答案 0 :(得分:1)
这确实是libgdx中的一个错误:
https://github.com/libgdx/libgdx/issues/1381
https://github.com/libgdx/libgdx/pull/1837
我认为您只需要更新版本的源代码。