最近我一直试图从Box2D世界中删除我的所有身体,但遇到了一点麻烦。
这是我删除所有主体的代码:
@Override
public boolean keyDown(int keycode) {
if(keycode==Keys.R){
LevelHolder.clearLevel();
}
}
...
public static void clearLevel(){
System.out.println("deleting bodies");
Array<Body> bodies = new Array<Body>();
world.getBodies(bodies);
for(Body bod: bodies){
world.destroyBody(bod);
}
System.out.println("deleted bodies");
}
对我来说,这似乎是一个合理的代码平静,但有时会崩溃(消息"删除的主体"永远不会打印出来),并显示来自本地代码的错误消息:
Assertion failed: (m_bodyCount > 0), function DestroyBody, file /Users/badlogic/jenkins/workspace/libgdx-mac/extensions/gdx-box2d/gdx-box2d/jni/Box2D/Dynamics/b2World.cpp, line 133.
当删除我刚从这个世界上得到的所有尸体时,我不知何故删除了比世界上更多的尸体。而且这种情况并不是一直都发生的。
这段代码是完全隔离的,我的游戏没有多线程。所以当我穿过世界上所有的尸体时,没有什么能删除尸体。
这里会发生什么?也许这不是删除所有尸体的正确方式,有人可以告诉我如何做得更好?非常感谢。
在此处使用libGDX 1.5.2。
我使用了与您相同的代码来销毁所有实体,并遇到了类似的问题。我认为问题是,当你的box2d.世界被锁定时,你试图摧毁尸体(你可以用World.isLocked()检查)。在你的World.step()期间,你的box2d。世界被锁定。这是我的问题,因为我试图摧毁尸体,这是beginContact()事件的结果,但不能,因为这是在world.step().中处理的
我的解决方案是给true分配一个布尔标志,就在执行world.step()之前,我会检查它是否为true,如果是,然后我使用与上面相同的代码销毁所有实体。
下面是我测试的一个例子:
private boolean destroyAllBodies;
public void clearBodies()
{
destroyAllBodies = true;
}
public void update()
{
if(destroyAllBodies)
{
Array<Body> bodies = new Array<Body>();
world.getBodies(bodies);
for(int i = 0; i < bodies.size; i++)
{
if(!world.isLocked())
world.destroyBody(bodies.get(i));
}
destroyAllBodies = false;
}
...
world.step(1/60f, 6, 2);
...
}
我希望这能有所帮助。干杯
首先尝试获取实体的计数,然后使用该计数而不是枚举器编写一个遍历数组的for循环。在枚举集合时对其进行编辑可能会导致问题。
问题是您正试图删除keydown事件中的主体,因此世界可能会被锁定。您应该做的是在渲染方法中删除它们。
boolean clearLevel=false;
@Override
public boolean keyDown(int keycode) {
if(keycode==Keys.R){
clearLevel=true;
}
}
...
public boolean render(float delta){
world.step(delta, 8, 4);
if(clearLevel){
System.out.println("deleting bodies");
Array<Body> bodies = new Array<Body>();
world.getBodies(bodies);
for(Body bod: bodies){
world.destroyBody(bod);
}
System.out.println("deleted bodies");
clearLevel=false;
}
}