在将Rectangle2D对象放入ArrayList之前,该程序运行良好,只是每当我改变方向时,蛇只会旋转而不是弯曲。现在这条蛇甚至都没有显示出来,并且我的控制台向我显示了错误,如Mad Programmer提供的那样:

Exception in thread "AWT-EventQueue-0" java.lang.IndexOutOfBoundsException:
Index: 0, Size: 0
    at java.util.ArrayList.rangeCheck(ArrayList.java:638)
    at java.util.ArrayList.get(ArrayList.java:414)
    at javaapplication968.JavaApplication968$Display.actionPerformed(JavaApplication968.java:110)


我知道这个问题与ArrayLists有关,但是我该如何解决?

这是我的课:

public class Display extends JPanel implements ActionListener, KeyListener {
Timer t = new Timer(1, this);
double xCoord = 50;
double yCoord = 50;
double xvel = 0;
double yvel = .01;
double ranx, xtemp;
double rany, ytemp;
int eaten = 0;
ArrayList<Rectangle2D> rects = new ArrayList<Rectangle2D>();
ArrayList<Double> xloc = new ArrayList<Double>();
ArrayList<Double> yloc = new ArrayList<Double>();

public Display(int xsize, int ysize) {
    t.start();
    addKeyListener(this);
    setFocusable(true);
    setFocusTraversalKeysEnabled(false);
    xtemp = xsize;
    ranx = (xtemp - 15) * Math.random();
    ytemp = ysize;
    rany = (ytemp - 15) * Math.random();
    formSnake();

}

@Override
public void paintComponent(Graphics g) {
    super.paintComponent(g);
    Graphics2D g2 = (Graphics2D) g;
    // Adds snake
    g2.setColor(Color.YELLOW);
    for (int i = 0; i < rects.size(); i++) {
        g2.fill(rects.get(i));
    }
    // Adds fruit at random location
    g2.setColor(Color.BLUE);
    g2.fill(new Ellipse2D.Double(ranx, rany, 15, 15));
    setBackground(Color.BLACK);
}

@Override
public void actionPerformed(ActionEvent e) {
    repaint();
    // Replaces each rectangle location with one before it
    for (int i = rects.size() - 1; i > 0; i--) {
        xloc.set(i, xloc.get(i - 1));
        yloc.set(i, yloc.get(i - 1));
    }
    // Sets new head location
    xloc.set(0, xloc.get(0) + xvel);
    yloc.set(0, yloc.get(0) + yvel);
    getEaten();
}

// Adds initial 3 2DRectangles to snake at start of game
public void formSnake() {
    for (int i = 0; i < rects.size(); i++) {
        xloc.add(xCoord);
        yloc.add(yCoord - 16 * i);
        rects.add(rects.size(),
                new Rectangle2D.Double(xloc.get(i), yloc.get(i), 15, 15));
    }
}

// Adds 1 2DRectangle to the front of the snake every time it eats
public void extend() {
    // Vertical
    if (xvel == 0) {

        if (yvel <= 0) { // Up
            xloc.add(xloc.get(xloc.size() - 1));
            yloc.add(yloc.get(yloc.size() - 1) - 16);
            rects.add(new Rectangle2D.Double(xloc.get(xloc.size() - 1),
                    yloc.get(yloc.size() - 1), 15, 15));

        } else
            // Down
            xloc.add(xloc.get(xloc.size() - 1));
        yloc.add(yloc.get(yloc.size() - 1) + 16);
        rects.add(new Rectangle2D.Double(xloc.get(xloc.size() - 1), yloc
                .get(yloc.size() - 1), 15, 15));
    }
    // Horizontal
    else if (yvel == 0) {
        if (xvel <= 0) { // Left
            xloc.add(xloc.get(xloc.size() - 1) - 16);
            yloc.add(yloc.get(yloc.size() - 1));
            rects.add(new Rectangle2D.Double(xloc.get(xloc.size() - 1),
                    yloc.get(yloc.size() - 1), 15, 15));
        } else
            // Right
            xloc.add(xloc.get(xloc.size() - 1) + 16);
        yloc.add(yloc.get(yloc.size() - 1));
        rects.add(new Rectangle2D.Double(xloc.get(xloc.size() - 1), yloc
                .get(yloc.size() - 1), 15, 15));
    }
}

public void getEaten() {
    if (Math.abs(xCoord - ranx) < 15 && Math.abs(yCoord - rany) < 15) {
        rany = ytemp * Math.random();
        ranx = xtemp * Math.random();
        eaten++;
        extend();
    }
}

//Directions
public void up() {
    yvel = -0.5;
    xvel = 0;
}

public void down() {
    yvel = 0.5;
    xvel = 0;
}

public void left() {
    xvel = -0.5;
    yvel = 0;
}

public void right() {
    xvel = 0.5;
    yvel = 0;
}

//Just for testing purposes
public void stop() {
    xvel = 0;
    yvel = 0;
}

//Direction implementation
@Override
public void keyPressed(KeyEvent e) {
    int code = e.getKeyCode();
    if (code == KeyEvent.VK_UP || code == KeyEvent.VK_NUMPAD8) {
        up();
    }
    if (code == KeyEvent.VK_DOWN || code == KeyEvent.VK_NUMPAD2) {
        down();
    }
    if (code == KeyEvent.VK_RIGHT || code == KeyEvent.VK_NUMPAD6) {
        right();
    }
    if (code == KeyEvent.VK_LEFT || code == KeyEvent.VK_NUMPAD4) {
        left();
    }

}

@Override
public void keyTyped(KeyEvent e) {
}

@Override
public void keyReleased(KeyEvent e) {
    }
}

最佳答案

你似乎正在

Exception in thread "AWT-EventQueue-0" java.lang.IndexOutOfBoundsException: Index: 0, Size: 0
    at java.util.ArrayList.rangeCheck(ArrayList.java:638)
    at java.util.ArrayList.get(ArrayList.java:414)
    at javaapplication968.JavaApplication968$Display.actionPerformed(JavaApplication968.java:110)


xloc.set(0, xloc.get(0) + xvel);,因为没有元素,所以xloc List

更改您的formSnake方法以完全按照其说明... // Adds initial 3 2DRectangles to snake at start of game而不是使用rects.size(),它在调用时将是0

    // Adds initial 3 2DRectangles to snake at start of game
    public void formSnake() {
        for (int i = 0; i < 3; i++) {
            xloc.add(xCoord);
            yloc.add(yCoord - 16 * i);
            rects.add(rects.size(),
                            new Rectangle2D.Double(xloc.get(i), yloc.get(i), 15, 15));
        }
    }

09-25 20:40