嗨,我正在开发一款蛇游戏。要创建我正在使用ArrayList
的蛇。移动蛇时,我收到以下错误:“java.lang.IndexOutOfBoundsException:Index:3,Size:3”。以下是我的计划。在Snake.update()
方法中,我遇到了问题。
Game.java:
import javax.swing.JFrame;
@SuppressWarnings("serial")
public class Game extends JFrame {
public Game(){
add(new GamePanel());
setTitle("Game Test3");
setVisible(true);
setAlwaysOnTop(true);
setLocationRelativeTo(null);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
pack();
}
public static void main(String[] args) {
new Game();
}
}
GamePanel.java:
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.RenderingHints;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.swing.JPanel;
@SuppressWarnings("serial")
public class GamePanel extends JPanel implements Runnable, KeyListener {
public static int width = 300;
public static int height = 400;
private Thread thread;
private Image image;
private Graphics2D g;
private Food food;
private Snake snake;
public GamePanel() {
setPreferredSize(new Dimension(width, height));
setFocusable(true);
}
public void addNotify() {
super.addNotify();
if (thread == null) {
thread = new Thread(this);
thread.start();
}
addKeyListener(this);
}
public void run() {
image = createImage(width, height);
g = (Graphics2D) image.getGraphics();
RenderingHints reneringHints = new RenderingHints(
RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g.setRenderingHints(reneringHints);
food = new Food();
snake = new Snake();
while (true) {
gameRender();
gameUpdate();
gameDraw();
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
private void gameDraw() {
Graphics2D g2 = (Graphics2D) getGraphics();
g2.drawImage(image, 0, 0, this);
g2.dispose();
}
private void gameRender() {
g.setColor(Color.black);
g.fillRect(0, 0, width, height);
// food drawing
food.draw(g);
// snake drawing
snake.draw(g);
}
private void gameUpdate() {
food.update();
snake.update();
}
public void keyPressed(KeyEvent e) {
int key = e.getKeyCode();
if (key == KeyEvent.VK_LEFT) {
snake.setLeft(true);
}
if (key == KeyEvent.VK_RIGHT) {
snake.setRight(true);
}
if (key == KeyEvent.VK_UP) {
snake.setUp(true);
}
if (key == KeyEvent.VK_DOWN) {
snake.setDown(true);
}
}
public void keyReleased(KeyEvent e) {
int key = e.getKeyCode();
if (key == KeyEvent.VK_LEFT) {
snake.setLeft(false);
}
if (key == KeyEvent.VK_RIGHT) {
snake.setRight(false);
}
if (key == KeyEvent.VK_UP) {
snake.setUp(false);
}
if (key == KeyEvent.VK_DOWN) {
snake.setDown(false);
}
}
public void keyTyped(KeyEvent e) {
}
}
//蛇体
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.util.ArrayList;
public class Snake {
private int x;
private int y;
private int r;
int body;
Rectangle rectangle;
ArrayList<Rectangle> rc = new ArrayList<Rectangle>();
private boolean left;
private boolean right;
private boolean up;
private boolean down;
public Snake() {
x = 150;
y = 150;
r = 4;
body = 3;
for (int i = 0; i < body; i++) {
rc.add(new Rectangle(x - i * r * 3, y, r * 3, r * 3));
}
}
public void draw(Graphics2D g) {
for (int i = 0; i < body; i++) {
if (i == 0) {
g.setColor(Color.red);
} else {
g.setColor(Color.green);
}
g.fillOval(rc.get(i).x, rc.get(i).y, rc.get(i).width,
rc.get(i).height);
}
}
public void update() {
for (int i = body; i > 0; i--) {
rc.set(i, rc.get(i - 1));
}
if (left) {
rc.get(0).x -= 1;
System.out.println("vbnv");
}
if (right) {
rc.get(0).x += 1;
}
if (up) {
rc.get(0).y -= 1;
}
if (down) {
rc.get(0).y += 1;
}
}
public void setLeft(boolean b) {
left = b;
}
public void setRight(boolean b) {
right = b;
}
public void setUp(boolean b) {
up = b;
}
public void setDown(boolean b) {
down = b;
}
}
答案 0 :(得分:3)
在没有阅读代码的情况下,我可以告诉您某处正在尝试获取不存在的元素。阅读异常消息,它告诉您ArrayList
由三个元素组成(这意味着最后一个元素的索引为2),同时尝试获取索引为3的元素。
更新:是的,问题在于:
for (int i = body; i > 0; i--) {
rc.set(i, rc.get(i - 1));
}
body
等于3,构造函数调用后的rc
大小为3. set
方法用已指定的索引替换已存在的元素(请参阅documentation ),但索引为3的元素不存在。这是异常的原因。
答案 1 :(得分:1)
你的问题就在这个循环中:
for (int i = body; i > 0; i--) {
rc.set(i, rc.get(i - 1));
}
在围绕此循环的第一次迭代中,您将调用:
rc.set(3, <someValue>);
3不是长度为3的列表中的有效索引。最大有效索引是2。
答案 2 :(得分:1)
for (int i = body; i > 0; i--)
在这个for
中,我被赋予了body的值(即3),看起来ArrayList rc
中只有3个元素。因此,当您尝试使用rc.set(3, something)
访问索引3时,会给出IndexOutOfBoundsException
。
永远记住,无论是Arrays
还是ArrayList
,其中可访问的最大可能索引始终为array.length - 1
和ArrayList.size() - 1
。