Я программировал игры в конце 80-х и в последнее время на Java для мобильных устройств. Я могу сказать вам, что вы собираетесь убить частоту кадров, если будете использовать LinkedList или Vector для хранения объектов Java, соответствующих таким простым вещам, как маркеры. Это не то, как эффективные мобильные игры запрограммированы. Эффективные мобильные игры программируются с учетом того, что «каждый бит имеет значение». Это одна из тех областей, где царит оптимизация.
Из-за упрощения, но представьте, что у вас есть игра с четырьмя пулями "живыми" (на самом деле это не "на экране", ваш "активный мир" может и обычно должен быть немного больше, чем ваш экран, он делает много обработки проще).
(20,30,3) (10, 50, 2) (30, 40, -3) (50, 50, 5)
Таким образом, первый пункт находится в пикселе (20,30) в вашем координатном пространстве и движется со скоростью 3 (что бы ни означала скорость 3, это всего лишь пример) вправо (упрощенно, это просто объяснить) , пуля 2 в (10,50) идет со скоростью 2 вправо, пуля 3 в (30,40), со скоростью 3 влево (минус здесь означает слева) и последняя пуля в (50,50,5) едут со скоростью 5 вправо.
Как это отображается в памяти в современных мобильных играх?
Вот так, в int []:
int [] = {4, 20, 30, 3, 10, 50, 2, 30, 40, -3, 50, 50, 5, ..., ..., ...};
Первые 4 говорят нам, что эта «структура данных представляет собой 4 элемента. И вы знаете, что каждое из них состоит из 3 значений (в нашем упрощенном примере).
Теперь представьте, что пуля 2 попадает в стену и исчезает, что происходит?
Это:
int [] = {3, 20, 30, 3, 50, 50, 5, 30, 40, -3, 50, 50, 5, ..., ..., ...};
Мы упрощаем уменьшенный первый int до 3, чтобы указать, что на данный момент в нашем игровом мире осталось только 3 маркера, и мы просто переместились (50, 50, 5) в положение «2», заменив (10, 50,2) по (50, 50, 5). Это связано с тем, что порядок нашей маркировки не имеет значения (все они имеют одинаковый эффект), и «перемещение всех элементов int [] влево» будет действительно неэффективным.
Обратите внимание, что мы даже не удосужились «очистить» «четвертую пулю»: старый (50,50,5) все еще там в конце, но мы знаем, что у нас осталось только 3 элемента, поэтому мы не будем все равно.
Так в памяти это выглядит так:
int [] = {3, 20, 30, 3, 50, 50, 5, 30, 40, -3, 50, 50, 5, ..., ..., ...};
Вас беспокоит только это:
int [] = {3, 20, 30, 3, 50, 50, 5, 30, 40, -3, ..., ..., ..., ..., ...,. ..};
ТО - это то, как это делается в большинстве современных мобильных игр: создание нулевого объекта для «обработки маркеров» в основном цикле. Вы управляете такими простыми структурами данных самостоятельно, используя массивы примитивов.
И int [] инициализируется в начале вашей игры вашего уровня на максимальное количество пуль, которое может произойти в вашей игре / уровне.
Вот вам и ваш «пул многоразового использования».
Если вы начнете думать о том, чтобы иметь объект Java для чего-то столь же тривиального, как пуля, и использовать LinkedList или Vector, которые вы будете изменять в каждом кадре, вы никогда не получите приемлемую производительность: вы будете генерирование бесчисленных ненужных объектов 50 раз в секунду и слишком частое срабатывание ГХ.
Теперь я, конечно, не говорю, что ОО-программирование не имеет места в мобильной игре: я просто говорю, что если вы будете думать с точки зрения объектов для таких простых вещей, как пули, вы никогда не получите приемлемости производительность.
Моя техника «удаления пуль» включает в себя один декремент (количество пуль) и 3 int копии. Вы не можете победить это;)
И это работает для многих вещей: пуль, эффектов частиц, врагов, предметов, бонусов и прочего:)
Тривиальные вещи, которые, вероятно, часто удаляются / воссоздаются в игровом цикле, вероятно, не должны моделироваться с использованием объектов и, конечно, не должны помещаться ни в Vector, ни в LinkedList.