如何在蛇游戏中使用arraylist创建蛇体

时间:2013-10-09 07:06:39

标签: java arraylist

嗨,我正在开发一款蛇游戏。要创建我正在使用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;
}

   }

3 个答案:

答案 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 - 1ArrayList.size() - 1