在libGDX中从世界中删除所有框2D主体

时间:2015-06-23 20:02:13

标签: java libgdx box2d

最近我一直试图从Box 2D世界中删除我的所有身体,但我遇到了一些麻烦。

以下是我删除所有正文的代码:

@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");

}  

对我而言,这似乎是一个合理的代码和平,但有时会崩溃(消息&#34;已删除的主体&#34;永远不会被打印),并带有来自本机代码的错误消息:

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。

3 个答案:

答案 0 :(得分:0)

首先尝试获取实体的数量,然后使用该计数编写一个遍历数组的for循环,而不是枚举器。在枚举时编辑集合可能会导致问题。

答案 1 :(得分:0)

我使用与你相同的代码来销毁所有的身体并遇到类似的问题。我相信问题是你在box2d.World被锁定时试图摧毁尸体(你可以用world.isLocked()来检查)。在你的world.step()期间,你的box2d.World被锁定了。这是我的问题,因为我试图通过beginContact()事件来破坏物体而不能因为这是在world.step()中处理的。

我的解决方案是将一个布尔标志分配给true,然后在做world.step()之前我会检查它是否为真,如果是,那么我会使用与上面相同的代码销毁所有实体。 / p>

这是我测试的一个例子:

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);

    ...
}

我希望有所帮助。干杯!

答案 2 :(得分:-1)

The problem is that you are trying to delete the bodies in the keydown event so the world may be locked. What you should do is delete them in the render method.

    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;
            }
        }