2014-12-05 43 views
0

我應該讓蛇的長方形沿着屏幕的一側走下去。然而,它保持原位,當我運行它,我也得到一個IndexOutOfBoundsException錯誤。我相信這與我的Render.java文件中的for循環有關。下面是代碼: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) 

我相信我會得到這個錯誤,因爲Render.java中的for循環沒有正確結束。有沒有人有這個好的解決方案?

+1

這似乎不大可能,一個IndexOutOfBounds錯誤造成通過你的for循環。更可能的是catParts.remove(0)語句或get語句,因爲似乎不能保證catParts至少有2個元素。嘗試在該語句之前添加斷言,以確保在嘗試刪除元素之前有元素。 – sprinter 2014-12-05 02:34:44

+0

那麼你有沒有在調試器中運行代碼並檢查變量等? – OldProgrammer 2014-12-05 02:35:07

+0

現在你已經添加了跟蹤,這很清楚,它是刪除語句。您在該方法中的邏輯沒有任何意義 - 爲什麼當不能保證列表中包含元素時刪除元素? – sprinter 2014-12-05 02:37:36

回答

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 2014-12-05 02:45:50

+1

太棒了。有幾件事情你應該看看,如果你想進步一個編碼器:單元測試(JUnit),調試,斷言陳述。所有這些將在這個和未來的項目中幫助你很多。 – sprinter 2014-12-05 05:43:38

0

你可以試試這個更新:

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