2013-10-09 2 views
1

Привет, Я разрабатываю змеиную игру. Чтобы создать змею, я использую ArrayList. При перемещении змеи я получаю следующую ошибку: «java.lang.IndexOutOfBoundsException: Index: 3, Size: 3». Ниже моя программа. В Snake.update() метод у меня проблема.как создать змеиное тело, используя arraylist в игре змей

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

Из любопытства: когда вы двигаетесь, вы перекрашиваете все или просто удаляете хвост? –

+0

Во-первых, я не могу создать змею. то как я могу думать об этом –

+1

хорошо, я думал о базовой структуре данных. вы добавляете на одном конце (голова) и удаляете другой (хвост) - вместо arraylist вы можете использовать очередь: http://docs.oracle.com/javase/7/docs/api/java/util/Queue .html –

ответ

2

Без чтения кода я могу сказать, что где-то вы пытаетесь получить несуществующий элемент. Прочитайте сообщение исключения, он говорит вам, что ваш ArrayList состоит из трех элементов (что означает, что последний элемент имеет индекс 2) в то время как вы пытаетесь получить элемент с индексом 3.

Update: да, проблема здесь:

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

body равен 3, а rc после вызова конструктора имеет размер 3. set метод заменяет уже существующий элемент с указанным индексом (см documentation), но элемент с индексом 3 не существует. Это и есть причина исключения.

+0

спасибо за ответ. Я знаю об ошибке.И wannt знать, как создать змею и двигаться правильно, используя arraylist –

1

Ваша проблема заключается в этом цикле:

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

Во время первой итерации вокруг этого цикла, вы будете называть:

rc.set(3, <someValue>); 

3 не является допустимым индексом в списке длины 3 . Самый большой действительный индекс 2.

+0

ok это можно дать как это для (int i = body; i> 0; i--) { rc.add (i, rc.get (i - 1)); } –

1
for (int i = body; i > 0; i--) 

В этом for, я назначен с ва lue of body (3), и похоже, что у вашего ArrayList rc есть только 3 элемента. Поэтому, когда вы пытаетесь получить доступ к индексу 3, используя rc.set(3, something), он дает IndexOutOfBoundsException.

Всегда помните, является ли это Arrays или ArrayList, максимально возможный индекс доступен в них всегда array.length - 1 и ArrayList.size() - 1.

+0

Я знаю эту проблему.но если я использую как body-1 в цикле. хвост .snake исчезает. И я сбиваю с толку, как правильно перемещать тело змеи –

Смежные вопросы