Создание вертикальной боковой скроллера, проблемы с массивами и логикой (Java)
Я на втором курсе по программированию и знаю только Java. Однако для моего класса мы должны создать вертикальный боковой скроллер. Моя установка состоит в том, что у меня есть ArrayList для вражеских кораблей и ArrayList для ракет игрока. Я рисую две ракеты в точных точках на корабле игрока в методе рендеринга (Graphics2D g), а вражеские корабли - тем же методом. Ракета ArrayList заполнена
arsenal.add(r);
arsenal.add(r2);
в которой r и r2 - ракеты с параметрами (x,y,w,h), а арсенал - ракетный массив. Я поставил их в очень специфических местах, на разных концах космического корабля. В методе update() у меня есть этот метод:
if (arsenal.size() < 0){
arsenal.add(new Rocket(p.currentX(), p.getHalfY(),30,30));
arsenal.add(new Rocket(p.getHalfX(), p.getHalfY(), 30, 30));
}
Это сделано для того, чтобы при опустошении массива ракеты снова добавлялись и перерисовывались до координат, соответствующих концам космического корабля. Единственный способ, которым ракеты исчезают, это когда они выходят за пределы экрана или сталкиваются с противником. Я вставил этот код, чтобы проверить это:
for(int x = army.size()-1; x >= 0; x--){
if (army.get(x).getR().y > 1024){
army.remove(x);
}
if(p.intersects(army.get(x).getR())){
army.remove(x);
p.changeH(10);
}
for (int q = arsenal.size()-1; q>=0;q++){
if (arsenal.get(q).intersects(army.get(x).getR())){
score+=20;
army.remove(x);
arsenal.remove(q);
}
}
}
Весь этот метод проходит через "армию" массива кораблей противника и проверяет, не прошли ли (1) вражеский корабль за заданную высоту, (2) столкнулся ли корабль игрока с вражеским кораблем и (3) - ракета В арсенале arraylist столкнулся с вражеским кораблем. Все столкновения делаются с использованием прямоугольников. P.changeH(10); команда снизить здоровье игрока на 10, а счет +=20; это увеличить счет. Для всех этих проверок я удостоверяюсь, что вражеский корабль удаляется из массива и, таким образом, становится неиспользованным, а затем, если ракеты уходят за пределы экрана или сталкиваются, они также удаляются из массива и гипотетически уничтожают себя. Последнее, что я хочу упомянуто, что arralust вражеского корабля становится населенным:
if (frameCount % 100 == 0){
Random r = new Random();
int randX = r.nextInt(width - 10);
army.add(new EnemyShip(randX, -200 , 47, 47, enemyP1));
}
Он принимает параметры (x,y,w,h,Image) и сначала выводится за пределы экрана, чтобы он выглядел как боковой скроллер. Переменная x является случайной, поэтому корабли не все появляются в одном и том же месте. frameCount увеличивается на 1 при каждом обновлении, а метод update() вызывается 60 раз в секунду.
После этого огромного знакомства с моим проектом моя проблема в том, что когда я запускаю игру, игра просто останавливается через пару секунд, и затмение выдает мне ошибку в коде:
if (arsenal.get(q).intersects(army.get(x).getR())){
Я не могу понять проблему. Любая помощь с благодарностью. Если нужно больше кода игры, просто дайте мне знать! Спасибо!
РЕДАКТИРОВАТЬ:
GameScreen.update(GameScreen.java:108)
выводит меня на линию:
if (arsenal.get(q).intersects(army.get(x).getR())){
которая является частью цикла:
for (int q = arsenal.size()-1; q>=0;q++){
if (arsenal.get(q).intersects(army.get(x).getR())){
score+=20;
army.remove(x);
arsenal.remove(q);
}
}
В конструкторе я размещаю команды
arsenal.add(r);
arsenal.add(r2);
Это добавляет их в arraylist. В методе рендеринга (Graphics2D g) я рисую их, используя:
for (Rocket r :arsenal){
r.draw(g);
}
В конструкторе ракеты p.currentX() является текущей координатой игрока x, а p.getHalfY() и p.getHalfX() говорят сами за себя. Они закодированы так, что ракета r появляется на одной стороне, а ракета r2 - на другой. Я также создал две логические переменные, rMove и r2move. Они помогают в плавном движении ракеты, а также сообщают ей, когда двигаться:
if (!r2move){
r2.setP(p.getR().x + 40, currentY + 12);
}
if(!rMove){
r.setP(p.currentX() - 10, currentY + 12);
}
setP (x, y) устанавливает позицию ракеты в исходное место. Я говорил об этом с моим учителем, и он сказал, что я как бы использую и массивы, и отдельные объекты, однако я не понимаю проблемы. Если вам нужен более подходящий код, дайте мне знать. Эта строка кода также сообщает ракете, когда двигаться, и это будет, когда будет нажата кнопка пробела:
if (rMove && r2move){
for (Rocket p:arsenal){
p.move();
}
}
if(r.getR().y < 0){
rMove = false;
space = false;
}
if (r2.getR().y < 0){
r2move = false;
space = false;
}
1 ответ
Что исключение говорит вам, что у него есть ArrayList
с 2 элементами в нем, что означает, что его действительные индексы 0 и 1. Но ваш код вызывает .get()
метод для этого ArrayList со значением индекса 2, который, очевидно, не существует и приводит к этому исключению.
Глядя на код, кажется, проблема в том, как вы инициализируете и используете переменную цикла q
в следующих строках:
for (int q = arsenal.size()-1; q>=0;q++){
if (arsenal.get(q).intersects(army.get(x).getR()))
Давайте предположим arsenal
имеет 2 элемента и, следовательно, размер 2. В результате, q
будет инициализирован со значением 1. if
заявление будет вызвано, и arsenal.get(1)
будет называться. Это действительный индекс для arsenal
Arraylist, и поэтому этот код пройдет без каких-либо ошибок.
В следующем проходе цикла, q
будет увеличен на 1 и станет 2. Согласно вашему условию проверки цикла, 2 > 0
и выполнение будет продолжено до следующей строки. if
заявление будет вызвано снова, и arsenal.get(2)
будет называться. Поскольку 2 является недопустимым индексом для arsenal
который имеет только 2 предмета, исключение, которое вы видите, будет выброшено.
Вы можете решить эту проблему, уменьшив значение q
вместо того, чтобы увеличивать его в for
петля.