2014-12-05 2 views
0

Я должен получить прямоугольники змеи, чтобы спуститься по сторонам экрана. Однако он остается на месте, и когда я запускаю его, я также получаю ошибку IndexOutOfBoundsException. Я считаю, что это имеет какое-то отношение к циклу for в моем файле Render.java. Вот код:IndexOutOfBoundsException в змее, как игра

LewisProject.java

package lewisproject; 

import java.awt.Point; 
import java.awt.Dimension; 
import java.awt.Toolkit; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.awt.event.KeyEvent; 
import java.awt.event.KeyListener; 
import java.util.ArrayList; 
import java.util.Random; 
import javax.swing.JFrame; 
import javax.swing.Timer; 

public class LewisProject implements ActionListener { 

    public Toolkit toolkit; 

    public JFrame jframe; 
    public Render render; 
    public static LewisProject lewisproject; 

    public Timer timer = new Timer(20, this); 

    public ArrayList<Point> catParts = new ArrayList<>(); 

    //head is the position of the first cat and the mouse is what you need to get in order to get more cats. 
    public Point head, mouse; 

    public Random random; 

    public boolean over = false; 

    public Dimension dim; 
    public int ticks = 0, direction = DOWN, score, tailLength; 

    public static final int UP = 0, DOWN = 1, LEFT = 2, RIGHT = 3, SCALE = 10; 

    public LewisProject() { 

     //Grabs the screen size 
     dim = Toolkit.getDefaultToolkit().getScreenSize(); 
     toolkit = Toolkit.getDefaultToolkit(); 
     jframe = new JFrame("Cat Assassin"); 
     jframe.setVisible(true); 
     //Sets Size of screen 
     jframe.setSize(800, 800); 
     //Centers the JFrame to the middle of your screen 
     jframe.setLocation(dim.width/2 - jframe.getWidth()/2, dim.height/2 - jframe.getHeight()/2); 
     jframe.add(render = new Render()); 
     //Closes the JFrame when you hit X. 
     jframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     head = new Point(0, 0); 
     //Puts a mouse in a random area of the screen. 
     mouse = new Point(dim.width/SCALE, dim.height/SCALE); 
     random = new Random(); 
     timer.start(); 

    } 

    @Override 
    public void actionPerformed(ActionEvent arg0) { 
     //re renders square 
     render.repaint(); 
     ticks++; 
     //These if statements are self explanatory. They add the point through the x and y axis depending on what direction the cats are going. 
     if (ticks % 10 == 0 && head != null && over != true) { 
      catParts.add(new Point(head.x, head.y)); 
      if (direction == UP) { 
       if (head.y - 1 > 0) { 
        head = new Point(head.x, head.y - 1); 
       } else { 
        over = true; 
       } 
      } 
     } 
     if (direction == DOWN) { 
      if (head.y + 1 < dim.height/SCALE) { 
       head = new Point(head.x, head.y + 1); 
      } 
     } else { 
      over = true; 
     } 

     if (direction == LEFT) { 
      if (head.x + 1 > 0) { 
       head = new Point(head.x - 1, head.y); 
      } else { 
       over = true; 
      } 
     } 

     if (direction == RIGHT) { 
      if (head.x + 1 < dim.width/SCALE) { 

       head = new Point(head.x + 1, head.y); 
      } else { 
       over = true; 
      } 
     } 
     catParts.remove(0); 
     head = catParts.get(catParts.size() - 1); 
     if (mouse != null) { 
      if (head.x == mouse.x && head.y == mouse.y) { 
       score++; 
       tailLength++; 
       mouse.setLocation(dim.width/SCALE, dim.height/SCALE); 
      } 
     } 
    } 


    public static void main(String[] args) { 
     lewisproject = new LewisProject(); 
    } 
} 

Render.java

package lewisproject; 
import java.awt.Color; 
import java.awt.Graphics; 
import java.awt.Point; 
import javax.swing.JPanel; 

public class Render extends JPanel{ 
    //It's more of a light gray but whatever. 
    public static Color white = new Color(15132390); 

//used @Override to get the error to be quiet while I work. 
    @Override 
    protected void paintComponent(Graphics g){ 
     //Calls the super class (JPanel) and paints graphics. 
     super.paintComponent(g); 
     //Sets the Color of Rectangle to black and sets dimensions 
     g.setColor(white); 
     g.fillRect(0, 0, 800, 800); 
     LewisProject lewisproject = LewisProject.lewisproject; 
     g.setColor(Color.BLUE); 
     for (Point point : lewisproject.catParts){ 

      g.fillRect(point.x * LewisProject.SCALE, point.y * LewisProject.SCALE, LewisProject.SCALE, LewisProject.SCALE); 

     } 
      g.fillRect(lewisproject.head.x * LewisProject.SCALE, lewisproject.head.y * LewisProject.SCALE, LewisProject.SCALE, LewisProject.SCALE); 

    } 
} 

Ошибка

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.remove(ArrayList.java:477) 
    at lewisproject.LewisProject.actionPerformed(LewisProject.java:101) 
    at javax.swing.Timer.fireActionPerformed(Timer.java:313) 
    at javax.swing.Timer$DoPostEvent.run(Timer.java:245) 
    at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:311) 
    at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:744) 
    at java.awt.EventQueue.access$400(EventQueue.java:97) 
    at java.awt.EventQueue$3.run(EventQueue.java:697) 
    at java.awt.EventQueue$3.run(EventQueue.java:691) 
    at java.security.AccessController.doPrivileged(Native Method) 
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:75) 
    at java.awt.EventQueue.dispatchEvent(EventQueue.java:714) 
    at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:201) 
    at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:116) 
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:105) 
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101) 
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:93) 
    at java.awt.EventDispatchThread.run(EventDispatchThread.java:82) 

Я считаю, что получаю эту ошибку, потому что цикл for в Render.java не заканчивается должным образом. У кого-нибудь есть хорошее решение?

+1

Это кажется маловероятным, что ошибка IndexOutOfBounds вызывается по вашему циклу for. Скорее это оператор catParts.remove (0) или оператор get сразу же, поскольку, похоже, нет гарантии, что у catParts есть как минимум 2 элемента. Попробуйте добавить утверждение перед этим утверждением, чтобы убедиться, что есть элементы, прежде чем пытаться его удалить. – sprinter

+0

Ну, вы запустили код в отладчике и изучили переменные и т. Д.? – OldProgrammer

+0

Теперь, когда вы добавили трассировку, довольно ясно, что это инструкция remove. Ваша логика в этом методе не имеет смысла - почему вы удаляете элемент, когда нет гарантии, что в списке есть элементы? – sprinter

ответ

2

Вы должны проверить размер коллекции catParts, прежде чем пытаться удалить или получить предметы:

if (!catParts.isEmpty()) { 
    catParts.remove(0); 
} 
if (!catParts.isEmpty()) { 
    head = catParts.get(catParts.size() - 1); 
    if (mouse != null) { 
     if (head.x == mouse.x && head.y == mouse.y) { 
      score++; 
      tailLength++; 
      mouse.setLocation(dim.width/SCALE, dim.height/SCALE); 
     } 
    } 
} 
+0

Спасибо. Это сработало для меня. – Lewis

+1

Отлично. Несколько вещей, на которые вы, вероятно, должны взглянуть, хотите ли вы продвигаться как кодер: модульное тестирование (JUnit), отладка, утверждение assert. Все это поможет вам в этом и будущих проектах. – sprinter

0

Вы можете попробовать это обновление:

if(!catParts.isEmpty()) {//<-- put a check before removing with index 
    catParts.remove(0); 
}