java - 从组中删除和添加参与者 - libgdx

标签 java libgdx

我有一个组,它有一个将每个实体与一个 Actor 相关联的 map ;它具有 addEntityremoveEntity 方法,用于在映射中添加和删除实体以及在组中添加和删除其各自的参与者。

public final void addEntity(final Entity entity) {
    EntityActor entityActor = new EntityActor(entity, shapeRenderer);
    this.addActor(entityActor); //adding the actor to the group
    this.entitesActors.put(entity, entityActor); //adding the actor to the map
}

public final void addEntities(final Collection<Entity> entities) {
    entities.stream().forEach(this::addEntity);
}

public final void removeEntity(final Entity entity) {
    entitesActors.get(entity).addAction(Actions.removeActor()); //removes actor from group
    this.entitesActors.remove(entity); //removes actor from map
}

public final void removeEntities(final Collection<Entity> entities) {
    entities.forEach(this::removeEntity);
}

该组还有一个 reset 方法,可以删除其所有子项并添加新的子项。

 public final void reset(final Collection<Entity> entities) {
    Gdx.app.postRunnable(() -> {
        removeEntities(entitesActors.keySet());
        this.addEntities(entities);
    });
}

第一次调用reset(Map和group为空)一切都很好,但是第二次调用它(Map和Group包含第一次调用的实体)时,我从removeEntity方法中得到了cuncurrentModificationException。

我尝试像这样编辑它:

public final void removeEntities(final Collection<Entity> entities) {
    entitesActors.entrySet().stream().filter(e -> entities.contains(e.getKey())).map(e -> e.getValue())
            .forEach(a -> a.addAction(Actions.removeActor()));
    entitesActors.keySet().removeAll(entities);
}

或者绕过removeEntities方法并直接调用:

this.clearChildren();
this.entitesActors.clear();

在这两种情况下都没有引发异常, Actor 被成功删除并添加到 map 和组中,但他们没有被绘制到舞台上。 (每个 Actor 中的绘制方法都被调用,但我在屏幕上看不到它们,我得到的只是黑屏)。

有人知道正确的方法,或者告诉我哪里出错了?非常感谢您的帮助。

编辑:我尝试了@luis-fernando-frontanilla 解决方案,但没有成功。现在我的重置方法如下所示

public final void reset(final Collection<Entity> entities) {
    this.clearChildren();
    this.entitesActors.clear();
    this.addEntities(entities);
}

我尝试将整个重置方法包装在 Gdx.app.postRunnable 中

//EntityCrew is my Group object which has the reset method
Gdx.app.postRunnable(() -> this.entityCrew.reset(level.getEntities()));

我注意到,第一次使用这种设置时,我看不到该组的 Actor 。它们在组中,它们是由渲染线程绘制的,但它们没有显示在屏幕上,这让我发疯。

最佳答案

The first time reset is called (Map and group are empty) everything's fine, but the second time I call it (with Map and Group containing the entities of the first call) I got a cuncurrentModificationException from the removeEntity method.

发生此异常的原因是,当您在 render() 方法中迭代集合时,该集合中的一个元素被删除,从而使迭代器混淆了它应该执行的操作。

幸运的是,LibGDX 有一个 DelayedRemovalArray正是针对此类情况而设计的类。它的工作原理如下:

  • 告诉DelayedRemovalArray您要删除其一个或多个元素
  • 在要删除的元素上放置一个标记
  • 告诉DelayedRemovalArray您已完成标志设置
  • DelayedRemovalArray 等待迭代完成并删除标记的元素
DelayedRemovalArray<Entity> array;
// Prepare to flag elements
array.begin();
// Flag some elements
array.removeIndex(index);
// Finished flagging elements
array.end();

From the LibGDX API:
DelayedRemovalArray is an array that queues removal during iteration until the iteration has completed.

关于java - 从组中删除和添加参与者 - libgdx,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60535341/

相关文章:

android - LibGDX:当我更换屏幕时,我的特定类如何继续保留?

java - LibGDX 导入 TMX 文件

java - 比较来自加速度计的 3D 信号数据的算法

java - 从文本中提取链接

java - 使用 OkHttp 下载损坏的文件

java - 矩形之间的碰撞检测 libgdx

java - 多个阶段 - 按钮没有反应?

java - Travis CI - 在非 headless (headless)环境中运行 LWJGL 测试?

java - 我的 Swing 应用程序可能不是线程安全的 - 虽然不知道为什么

java - 得到错误的输出