我正在使用eclipse。我似乎无法理解为什么这段代码会出错。这似乎完全符合逻辑,第二个我删除了那条小线,程序运行正常。我很确定焦点应该放在第98行,这就是错误所说的。我做成注释的另一部分也给出了完全相同的错误,看似没有理由......为什么它会在objectList中走得太远? 第98行看起来像这样
if(objectIterator.next().getClass() == Enemy.class) //Enemy.class.isAssignableFrom(objectIterator.next().getClass()))
package robotron;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import javax.swing.Timer;
import javax.swing.JPanel;
import java.awt.Dimension;
import java.awt.event.*;
import java.util.*;
public class GameArea extends JPanel implements ActionListener
{
static final long serialVersionUID = 42L;
public static final int FRAME_RATE = 60;
public static final int TIME_BETWEEN_FRAMES = 1000/FRAME_RATE;
public static final int DIFFICULTY_INCREASE = 4;
public static final int LEFT_EDGE = 0;
public static final int RIGHT_EDGE = 800;
public static final int UPPER_EDGE = 0;
public static final int BOTTOM_EDGE = 600;
public static final int PLAYER_MOVE_UP_KEY = KeyEvent.VK_W;
public static final int PLAYER_MOVE_DOWN_KEY = KeyEvent.VK_S;
public static final int PLAYER_MOVE_LEFT_KEY = KeyEvent.VK_A;
public static final int PLAYER_MOVE_RIGHT_KEY = KeyEvent.VK_D;
public static final int UP_KEY = KeyEvent.VK_UP;
public static final int DOWN_KEY = KeyEvent.VK_DOWN;
public static final int LEFT_KEY = KeyEvent.VK_LEFT;
public static final int RIGHT_KEY = KeyEvent.VK_RIGHT;
public static LinkedList<Integer> keyPressedList = new LinkedList<Integer>();
public static Iterator<Integer> keyPressedIterator;
public static LinkedList<GameObject> storeList = new LinkedList<GameObject>();
public static Iterator<GameObject> storeIterator;
public static LinkedList<GameObject> objectList = new LinkedList<GameObject>();
public static Iterator<GameObject> objectIterator;
public static int difficultyIncrements = 0;
public static int enemyUnitCount = 0;
public Timer gameTimer = new Timer(TIME_BETWEEN_FRAMES, this);
public void paintComponent(Graphics g)
{
Graphics2D g2 = (Graphics2D) g;
g.setColor(Color.BLACK);
g.fillRect(0, 0, getWidth(), getHeight());
g.setColor(Color.YELLOW);
g2.fill(Player.playerBoundingBox);
for(GameObject object : objectList)
{
g2.fill(object.getBoundingBox());
}
for(GameObject object : objectList)
{
object.draw(g);
}
}
public GameArea(){
setFocusable(true);
setPreferredSize(new Dimension(800,600));
MyKeyListener keyListener = new MyKeyListener();
addKeyListener(keyListener);
gameTimer.start();
objectList.add(new Player());
}
public void actionPerformed(ActionEvent a)
{
//System.out.println(objectList);
for(GameObject storedObject : storeList)
{
objectList.addLast(storedObject);
}
storeList.clear();
for (GameObject object : objectList)
{
object.update();
object.move();
}
objectIterator = objectList.iterator();
while(objectIterator.hasNext())
{
if(objectIterator.next().getHealth() < 1)
{
if(objectIterator.next().getClass() == Enemy.class) //Enemy.class.isAssignableFrom(objectIterator.next().getClass()))
enemyUnitCount --;
objectIterator.remove();
}
}
if(enemyUnitCount == 0 )
{
objectIterator = objectList.iterator();
while(objectIterator.hasNext())
{
if(objectIterator.next().getClass() != Player.class)
{
objectIterator.remove();
}
}
initiateNewRound();
}
repaint();
}
public void initiateNewRound()
{
difficultyIncrements += DIFFICULTY_INCREASE;
gameTimer.stop();
gameTimer.setInitialDelay(1000);
spawnUnits(5 + difficultyIncrements);
gameTimer.restart();
}
public void spawnUnits(int spawnCoefficient)
{
for(int i = 0; i < spawnCoefficient*2;i++)
{
if(Math.random() * 600 < 301)
{
GameArea.objectList.add(new Walker());
}
}
for(int i = 0; i < spawnCoefficient;i++)
{
if(Math.random() * 600 < 100)
{
GameArea.objectList.add(new DeathTrap());
}
}
if(Math.random() * 600 < 200)
{
GameArea.objectList.add(new SlowTrap());
}
}
private class MyKeyListener implements KeyListener
{
public void keyPressed(KeyEvent e)
{
//System.out.println("keyPressed() " + e.getKeyCode());
if(!keyPressedList.contains(e.getKeyCode()))
{
//System.out.println("new keyPressed() " + e.getKeyCode());
keyPressedList.add(e.getKeyCode());
}
}
public void keyReleased(KeyEvent e)
{
//System.out.println("keyReleased() " + e.getKeyCode());
keyPressedList.removeFirstOccurrence(e.getKeyCode());
}
public void keyTyped(KeyEvent e)
{
}
}
}
这是错误:
这是确切的错误:
Exception in thread "AWT-EventQueue-0" java.util.NoSuchElementException
at java.util.LinkedList$ListItr.next(Unknown Source)
at robotron.GameArea.actionPerformed(GameArea.java:98)
at javax.swing.Timer.fireActionPerformed(Unknown Source)
at javax.swing.Timer$DoPostEvent.run(Unknown Source)
at java.awt.event.InvocationEvent.dispatch(Unknown Source)
at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
at java.awt.EventQueue.access$500(Unknown Source)
at java.awt.EventQueue$3.run(Unknown Source)
at java.awt.EventQueue$3.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
at java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.run(Unknown Source)
答案 0 :(得分:3)
每次调用next()
时,您都会迭代到下一个对象。看看你的代码
while(objectIterator.hasNext())
{
if(objectIterator.next().getHealth() < 1)
// ^^^^^
{
if(objectIterator.next().getClass() == Enemy.class)
// ^^^^^
enemyUnitCount --;
objectIterator.remove();
}
}
在while(objectIterator.hasNext())
循环条件中,您正在检查迭代器是否至少还有一个元素,但是您在每个next
语句中调用了if(...next()...)
两次这意味着在next
的第二次调用中,您正在尝试访问可能不存在的元素。
要更正代码,只需存储next
的结果,并在需要时使用此对象,如
while(objectIterator.hasNext())
{
GameObject gameObjec = objectIterator.next();
if(gameObjec.getHealth() < 1)
{
if(gameObjec.getClass() == Enemy.class)
enemyUnitCount --;
objectIterator.remove();
}
}
答案 1 :(得分:1)
来自方法Iterator.next()
的文档:
返回下一个元素。如果迭代没有更多元素,则抛出
NoSuchElementException
。
在next()
的单次测试后,您正在调用hasNext()
方法两次。
答案 2 :(得分:0)
尽管next()
似乎是“getter”,但它也会推进迭代指针。即每次调用next都会返回不同的元素。
更改代码以调用next()
一次,如果需要多次引用,则将返回的对象分配给变量。
答案 3 :(得分:0)
这似乎完全合乎逻辑......
您可以保证程序执行的一点是,在某种程度上它是完全合乎逻辑的。它将完成代码所要做的事情......一旦你理解了代码的实际内容。 (在调试时要记住这一点。)
如果“逻辑错误”在于您理解程序代码的含义。
以下是您的代码的关键部分:
while(objectIterator.hasNext())
{
if(objectIterator.next().getHealth() < 1)
{
if(objectIterator.next().getClass() == Enemy.class)
enemyUnitCount --;
objectIterator.remove();
}
}
毫无疑问,next()
推进了迭代器和hasNext()
测试是否可以仍然推进迭代器的推进。 (next()
方法与简单的“getter”不同。它有副作用。)
如果仔细查看代码,可以看到while
循环的每次重复都将执行以下操作之一:
hasNext()
,next()
或hasNext()
,next()
,next()
,remove()
假设您在循环重复开始时位于列表的最后一个元素。这是发生的事情:
hasNext()
说true
。next()
调用为您提供最后一个元素。if
测试成功,第二个next()
调用会抛出异常,因为没有“next”。解决方案是这样的:
while(objectIterator.hasNext())
{
GameObject tmp = objectIterator.next();
if(tmp.getHealth() < 1)
{
if(tmp.getClass() == Enemy.class)
enemyUnitCount --;
objectIterator.remove();
}
}
还有一些事项需要注意:
您的代码风格需要如此关注。根据所有主流Java风格指南:
if
和while
个关键字后面应该有一个空格。 if和while不是方法调用。对于这些语句,左大括号应位于上一行的末尾。您应该将它放在新行上的唯一情况是前一行是不同的语句。
while (objectIterator.hasNext()) {
GameObject tmp = objectIterator.next();
if (tmp.getHealth() < 1) {
if (tmp.getClass() == Enemy.class) {
enemyUnitCount --;
}
objectIterator.remove();
}
}