Jarmund Jarmund - 4 months ago 20
Java Question

GdxRuntimeException: #iterator() cannot be used nested

I'm working on this game which has a

World
. In this
World
there are many
Units
.

The problem stems from the fact that
World
serves (among other things) two main tasks:


  1. Iterate through each
    Unit
    so that they can update their properties based on time passed an so forth.

  2. Find potential targets for each
    Unit
    .



In
World
, this happens:

for (Actor a : stage.getActors())
{
a.draw(batch, 1);
a.act(10);
findTargets((Unit)a);
}


findTargets() is defined as such:

public ArrayList<Unit> findTargets(Unit source) {
double sight = source.SIGHT;
ArrayList<Unit> targets = new ArrayList<Unit>();
for (Actor a : stage.getActors()) {
Unit target = (Unit)a;
if (!(target instanceof Unit))
continue;

if (target.equals(source)) continue;
if (((Unit)target).getPos().dst(source.getPos()) < sight) {
targets.add((Unit)target);
}
}
return targets;
}


The problem is obvious:
findTargets()
also iterates over every unit, resulting in a nested iteration. However, I'm unsure as to how I should proceed to "un-nest" this, as I'm only seeing a catch 22: Every unit does in effect have to iterate over every other unit to see if they're within their sight-range.

Some fresh eyes on this would be greatly appreciated.

Answer

There may be ways to refactor your design to avoid the nesting. But the simplest solution might be to just use the old school for loops for both outer and inner, or just the inner. Don't use the iterator, as that is not allowed here for nested loops. getActors returns a libGDX Array, so just traverse that by index

for (int i=0; i < stage.getActors().size; i++) {
  //...etc --> use stage.getActors().items[i] ...
Comments