Java 从libGDX中的世界中删除所有长方体二维实体

Java 从libGDX中的世界中删除所有长方体二维实体,java,libgdx,box2d,Java,Libgdx,Box2d,最近,我一直试图从Box 2D world中删除我所有的身体,但我遇到了一点小麻烦 以下是我删除所有实体的代码: @Override public boolean keyDown(int keycode) { if(keycode==Keys.R){ LevelHolder.clearLevel(); } } ... public static void clearLevel(){ System.out.println("deleting bodies"

最近,我一直试图从Box 2D world中删除我所有的身体,但我遇到了一点小麻烦

以下是我删除所有实体的代码:

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

}  
当我删除我刚从世界上得到的所有尸体时,我不知何故删除了比世界上更多的尸体。而且,这种情况并非总是发生

这段代码是完全隔离的,我的游戏没有多线程。所以当我在世界上所有的身体中穿行时,没有什么可以删除身体

这里会发生什么?也许这不是删除所有尸体的正确方法,有人能告诉我如何做得更好?多谢各位


在这里使用libgdx1.5.2。

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

问题在于,您试图在keydown事件中删除实体,以便锁定世界。 您应该做的是在render方法中删除它们

    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;
            }
        }
布尔clearLevel=false;
@凌驾
公共布尔键关闭(int-keycode){
if(keycode==Keys.R){
clearLevel=true;
}
}
...
公共布尔渲染(浮点增量){
世界级台阶(delta,8,4);
如果(clearLevel){
System.out.println(“删除实体”);
数组体=新数组();
世界卫生组织(机构);
适用于(机构董事会:机构){
世界卫生组织(bod);
}
System.out.println(“删除的实体”);
clearLevel=false;
}
}

我使用与您相同的代码销毁所有尸体,并遇到了类似的问题。我认为问题在于,当您的box2d.World被锁定时,您试图销毁尸体(您可以使用World.isLocked()进行检查)。在您的world.step()期间,您的box2d.world被锁定。这是我的问题,因为我正试图由于beginContact()事件而销毁尸体,但无法,因为这是在world.step()中处理的

我的解决方案是在执行world.step()之前为true指定一个布尔标志。我会检查它是否为true,如果为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);

    ...
}
所有主体的私有布尔值;
公共机构()
{
销毁所有实体=真;
}
公共无效更新()
{
如果(销毁所有实体)
{
数组体=新数组();
世界卫生组织(机构);
对于(int i=0;i

我希望这有帮助。干杯

您的对象名为world的引用类型是什么?如果是你写的,请贴出来让我看看。我没有写。这是box2d的世界级(来自libgdx端口)您可以发布一个而不是断开连接的代码段吗?我们能看看是什么调用这个函数吗?你看了没有?凯文,这是怎么断开的?它从世界上获取尸体,然后一个接一个地摧毁它们。没有对我编写的类的引用。为什么调用这个方法很重要?这是一段完全独立的代码。在打印消息“删除实体”之后和消息“已删除实体”之前发生崩溃。User2016436,我查看了链接,但它们与我的问题无关。从世界中删除身体不会从数组中删除身体。因此,该集合没有以任何方式进行编辑。这是错误的。渲染和输入事件是同步的。我以前做过一些游戏,你这样做也会产生同样的错误。上面的代码是我解决任何问题的方法。您必须在world.step()之后运行代码。我在发布注释之前测试了您的代码,但它不起作用。
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);

    ...
}