Удаление и добавление актеров в группу - libgdx - PullRequest
0 голосов
/ 05 марта 2020

У меня есть группа, у которой есть Карта, которая связывает каждый entity с актером; у него есть метод addEntity и removeEntity для добавления и удаления объектов на / с карты и их соответствующих участников в / из группы.

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

Первый раз вызывается сброс (карта и группа пусты) все в порядке, но во второй раз я вызываю его (с картой и группой, содержащей объекты первый вызов) Я получил cuncurrentModificationException от метода removeEntity.

Я попытался отредактировать его следующим образом:

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

В обоих случаях не сработало ни одного исключения, актеры были успешно удалены и добавлены как в Карту, так и в Группу, но они не были нарисованы на сцене. (метод draw у каждого актера вызывается, но я не вижу их на экране, все, что у меня есть, это черный экран).

Кто-то знает правильный способ сделать это или, может быть, говорит мне, где я делаю ошибка? Большое спасибо за помощь.

РЕДАКТИРОВАТЬ: Я пробовал решение @ 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 wich has the reset method
Gdx.app.postRunnable(() -> this.entityCrew.reset(level.getEntities()));

И я заметил, что с этой настройкой первый время я тоже не вижу актеров группы. Они в группе, они нарисованы потоком рендеринга, но они не отображаются на экране, и это меня бесит.

1 Ответ

1 голос
/ 05 марта 2020

Первый сброс вызван (карта и группа пусты) все в порядке, но во второй раз, когда я вызываю его (карта и группа содержат объекты первого вызова), я получил исключение cuncurrentModificationException из метода removeEntity .

Это исключение происходит потому, что при выполнении итерации по коллекции в методе render() один элемент в этой коллекции удаляется, что приводит к путанице в том, что он должен делать.

К счастью для нас, у LibGDX есть класс DelayedRemovalArray, который создан именно для таких случаев. Это работает так:

  • Сообщите DelayedRemovalArray, что вы хотите удалить один или несколько его элементов
  • Поставьте флажок на элементы, которые хотите удалить
  • Сообщите DelayedRemovalArray, что вы закончили установку флагов
  • * DelayedRemovalArray ожидает итерации до конца sh и удаляет помеченные элементы
DelayedRemovalArray<Entity> array;
// Prepare to flag elements
array.begin();
// Flag some elements
array.removeIndex(index);
// Finished flagging elements
array.end();

Из API LibGDX:
DelayedRemovalArray - массив, который ставит в очередь удаление во время итерации, пока итерация не будет завершена.

...