2

こんにちは、ヘビゲームを開発しています。私が使用しているヘビを作成するにはArrayList. ヘビを動かしているときに、「java.lang.IndexOutOfBoundsException: Index: 3, Size: 3」というエラーが発生します。以下は私のプログラムです。Snake.update()メソッドに問題があります。

ゲーム.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;
}

   }
4

3 に答える 3

3

コードを読まなくても、どこかで存在しない要素を取得しようとしていることがわかります。例外のメッセージを読むと、ArrayListインデックスが 3 の要素を取得しようとしているときに、3 つの要素で構成されていることがわかります (つまり、最後の要素のインデックスが 2 であることを意味します)。

更新:はい、問題はここにあります:

for (int i = body; i > 0; i--) {
    rc.set(i, rc.get(i - 1));
}

bodyメソッドは既存の要素を指定されたインデックス (ドキュメントrcを参照) に置き換えますが、インデックスが3の要素は存在しません。それが例外の原因です。set

于 2013-10-09T07:09:50.210 に答える
1

あなたの問題はこのループにあります:

for (int i = body; i > 0; i--) {
    rc.set(i, rc.get(i - 1));
}

このループの最初の繰り返しでは、次のように呼び出します。

rc.set(3, <someValue>);

長さ 3 のリストでは、3 は有効なインデックスではありません。最大の有効なインデックスは 2 です。

于 2013-10-09T07:10:36.147 に答える
1
for (int i = body; i > 0; i--)

このでは、 i に body の値 (3) が割り当てられており、要素が 3 つしかないforように見えます。ArrayList rcしたがって、 を使用してインデックス 3 にアクセスしようとするとrc.set(3, something)IndexOutOfBoundsException.

ArraysまたはArrayListであるかどうかに関係なく、それらでアクセス可能な最大のインデックスは常にarray.length - 1およびであることを常に覚えておいてくださいArrayList.size() - 1

于 2013-10-09T07:10:57.413 に答える