1

I am trying to build a Space Invaders game and have developed this section of code to make all the aliens drop down when one of them hits the edge of the screen, however I'm getting a pretty nasty looking error message when it hits line Enemy de = downwardIterator.next();. The game still runs as it should, but it's firing off these error messages in the background when it hits that line. Here's the code:

Iterator<Enemy> iterator = enemyList.iterator();
    while (iterator.hasNext()) {
        Enemy e = iterator.next();

        if(e!=null && e.isActive()){
            e.move();
            e.draw(g);
            if(e.edgeHit()){
                Iterator<Enemy> downwardIterator = enemyList.iterator();
                while (iterator.hasNext()) {
                    Enemy de = downwardIterator.next();
                    de.dropPosition();
                    de.changeDirection();
                }
            }
        }
        else{
            iterator.remove();
        }
    }

e.move just makes the enemies move left and right. e.edgeHit detects when any enemy reaches the edge of the game screen.

This is the full trace when it hits that line:

Exception in thread "AWT-EventQueue-0" java.util.NoSuchElementException
    at java.util.ArrayList$Itr.next(ArrayList.java:834)
    at GamePanel.paintComponent(GamePanel.java:96)
    at javax.swing.JComponent.paint(JComponent.java:1054)
    at javax.swing.JComponent.paintToOffscreen(JComponent.java:5219)
    at javax.swing.RepaintManager$PaintManager.paintDoubleBuffered(RepaintManager.java:1529)
    at javax.swing.RepaintManager$PaintManager.paint(RepaintManager.java:1452)
    at javax.swing.RepaintManager.paint(RepaintManager.java:1249)
    at javax.swing.JComponent._paintImmediately(JComponent.java:5167)
    at javax.swing.JComponent.paintImmediately(JComponent.java:4978)
    at javax.swing.RepaintManager$3.run(RepaintManager.java:808)
    at javax.swing.RepaintManager$3.run(RepaintManager.java:796)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
    at javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:796)
    at javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:769)
    at javax.swing.RepaintManager.prePaintDirtyRegions(RepaintManager.java:718)
    at javax.swing.RepaintManager.access$1100(RepaintManager.java:62)
    at javax.swing.RepaintManager$ProcessingRunnable.run(RepaintManager.java:1677)
    at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:251)
    at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:733)
    at java.awt.EventQueue.access$200(EventQueue.java:103)
    at java.awt.EventQueue$3.run(EventQueue.java:694)
    at java.awt.EventQueue$3.run(EventQueue.java:692)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
    at java.awt.EventQueue.dispatchEvent(EventQueue.java:703)
    at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:242)
    at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:161)
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:150)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:146)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:138)
    at java.awt.EventDispatchThread.run(EventDispatchThread.java:91)

2 Answers 2

4

Your second iterator loop is incorrect.

Iterator<Enemy> downwardIterator = enemyList.iterator();
while (iterator.hasNext()) {
  // ...

should be

Iterator<Enemy> downwardIterator = enemyList.iterator();
while (downwardIterator.hasNext()) {
  // ...

Edit

You might prefer the for-each loop (which uses a hidden iterator) like

for (Enemy de : enemyList) {
  // ...
Sign up to request clarification or add additional context in comments.

Comments

2

In case you want an explanation, you are calling the .next() method on your downwardIterator object and your while loop isn't checking the right iterator object to see if there are any elements left:

Iterator<Enemy> downwardIterator = enemyList.iterator();
while (iterator.hasNext()) { // Check downwardIterator instead of iterator
    Enemy de = downwardIterator.next();
    de.dropPosition();
    de.changeDirection();
}

Also, when your first if condition is met, you can use an enhanced for loop to iterate over your enemyList if enemyList isn't being modified.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.