从libGDX中的世界中删除所有长方体2D



最近我一直试图从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;
            }
        }

最新更新