Java-игра: ArrayList и Iterator против потока - PullRequest
1 голос
/ 28 июня 2011

Sup парни.

Я пишу простую игру про зомби для своих классов Java, и у меня возникла небольшая проблема: Zombies - это класс, который я создал, и я рассматриваю их в ArrayListПримерно так:

horda.add(new Zumbi( (int)(Math.random()* 750), 0));

Где аргументы представляют позицию появления зомби на экране.Чтобы убить их, вы должны щелкнуть по ним, довольно просто, проверяя столкновение с итератором, здесь:

java.util.Iterator<Zumbi> itr = horda.iterator();
        while (itr.hasNext()){
            Zumbi z = itr.next();
            if (tiroPos.x > z.zumbiPos.x && 
                tiroPos.x < z.sprite.getWidth() + z.zumbiPos.x &&
                tiroPos.y > z.zumbiPos.y &&
                tiroPos.y < z.sprite.getHeight() + z.zumbiPos.y){

                //things to do when it hits    
            }

tiroPos - указатель, который содержит координаты, где стреляет игрок.Дело в том, что иногда то, что должно произойти, когда вы попадаете в зомби, не происходит.Я не знаю, так ли это, потому что итератор работает недостаточно быстро или что-то еще.

Может быть, создание отдельного потока для каждого зомби работает, но это изменило бы код - это несколько фундаментальных способов, и яне хотел рисковать потерять все это время, если это не поможет.

Итак, есть мысли?

// РЕДАКТИРОВАТЬ: Забыл сказать: я проверяюколлизии в переопределенном методе рисования, потому что я не знаю, как рисовать вещи в других методах, и когда я пытался получить доступ к ArrayList (это Sync'd ArrayList) в другом потоке, это вызывало у меня исключение совместной модификации.

// РЕДАКТИРОВАТЬ2: Проблема решена (чего никогда не было).

Объект MouseEvent, переданный MouseListener, проходит через кординат нижнегоконец указателя мыши.Так что это была не проблема столкновений, а скорее математическая проблема.Я должен был сравнить clickPoint.y - 25 , чтобы понять это правильно.

Спасибо всем, кто пытался помочь!

Ответы [ 4 ]

2 голосов
/ 28 июня 2011

Следует помнить две вещи:

  1. Если вам нужно удалить элементы из ArrayList во время итерации, вы должны сделать это с помощью метода remove() на итераторе. Если вы измените сам список, он потерпит неудачу.

  2. Если два потока обращаются к списку, вы должны заключить его в Collections.synchronizedList или выбрать другую структуру данных.

Редактировать: звучит так, как будто вы изменяете список в одном потоке, повторяя его в другом. Это вызовет исключение ConcurrentModificationException. Самый простой способ избежать этого - обернуть использование списка синхронизированным блоком в обоих потоках. Пример:

synchronized(horda) {
    iterator = horda.iterator();
    while (iterator.hasNext()) {
        z = iterator.next();
        ...
    }
}

Другой альтернативой является клонирование списка перед итерацией или использование одной из специальных реализаций списка из java.util.concurrent, например CopyOnWriteArrayList .

0 голосов
/ 28 июня 2011

Я предполагаю, что игрок «стреляет», щелкая в окне, и, следовательно, tiroPos - это координаты x, y клика.

Если это так, и ваша проблема в том, что некоторые зомби не получают выстрел, когда их нажимают, когда пользователь нажимает много, возможно, что только последний «выстрел» сохраняется в 1004 *.

Вы можете проверить это, добавив соответствующие вызовы System.out.println() вокруг вашего цикла for и еще один, для которого вы установите tiroPos. Если tiroPos меняется в середине цикла for, именно поэтому некоторые зомби не получают выстрел.

Если это так, вам нужно начать хранить список кликов, а не только последний клик.

Редактировать: это не исправит ваши исключения одновременной модификации.

0 голосов
/ 28 июня 2011

Лучше всего использовать цикл for-each для итерации по зомби, по моему мнению.Он был введен для выполнения такой задачи, поэтому вы также можете использовать его.

0 голосов
/ 28 июня 2011

Многопоточность может только вам очень помочь, и она действительно зависит от того, сколько у вас вычислительной мощности.

Quaddree обычно используются для обнаружения столкновений, поэтому их стоит рассмотреть в качестве альтернативы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...