Я должен получить прямоугольники змеи, чтобы спуститься по сторонам экрана. Однако он остается на месте, и когда я запускаю его, я также получаю ошибку 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 не заканчивается должным образом. У кого-нибудь есть хорошее решение?
Это кажется маловероятным, что ошибка IndexOutOfBounds вызывается по вашему циклу for. Скорее это оператор catParts.remove (0) или оператор get сразу же, поскольку, похоже, нет гарантии, что у catParts есть как минимум 2 элемента. Попробуйте добавить утверждение перед этим утверждением, чтобы убедиться, что есть элементы, прежде чем пытаться его удалить. – sprinter
Ну, вы запустили код в отладчике и изучили переменные и т. Д.? – OldProgrammer
Теперь, когда вы добавили трассировку, довольно ясно, что это инструкция remove. Ваша логика в этом методе не имеет смысла - почему вы удаляете элемент, когда нет гарантии, что в списке есть элементы? – sprinter