Создание вертикальной боковой скроллера, проблемы с массивами и логикой (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 петля.

Другие вопросы по тегам