Фон
Вместе с другом я работаю над 2D-игрой в космосе. Чтобы сделать его как можно более захватывающим и интерактивным, мы хотим, чтобы вокруг свободно плавали тысячи объектов, некоторые сгруппировались вместе, другие плыли в пустом пространстве.
Вызов
Чтобы разгрузить движок рендеринга и физики, нам нужно реализовать какое-то пространственное разбиение. Мы должны преодолеть две проблемы. Первая проблема заключается в том, что все движется, поэтому реконструкция / обновление структуры данных должно быть чрезвычайно дешевым, поскольку это должно быть сделано каждый кадр. Вторая проблема заключается в распределении объектов, как уже говорилось ранее, могут быть кластеры объектов вместе и огромные куски пустого пространства, и, что еще хуже, нет границы для пространства.
Существующие технологии
Я рассмотрел существующие методы, такие как BSP-Trees, QuadTrees, kd-Trees и даже R-Trees, но, насколько я могу судить, эти структуры данных не идеально подходят, так как обновление большого количества объектов, которые были перемещены в другие ячейки относительно дорого
Что я пробовал
Я решил, что мне нужна структура данных, которая больше ориентирована на быструю вставку / обновление, чем на возвращение наименьшего количества возможных попаданий по запросу. Для этого я сделал ячейки неявными, чтобы каждый объект, учитывая его положение, мог вычислить, в какой ячейке (ях) он должен быть. Затем я использую, HashMap
который отображает координаты ячейки в ArrayList
(содержимое ячейки). Это работает довольно хорошо, поскольку на «пустых» ячейках не теряется память, и легко подсчитать, какие ячейки проверять. Однако создание всех этих ArrayList
s (наихудший случай N) является дорогостоящим и поэтому увеличивается во HashMap
много раз (хотя это немного смягчается, если дать ему большую начальную емкость).
проблема
Итак, это работает, но все еще не очень быстро. Теперь я могу попробовать микрооптимизировать код JAVA. Однако я не ожидаю слишком многого от этого, поскольку профилировщик говорит мне, что большая часть времени уходит на создание всех тех объектов, которые я использую для хранения ячеек. Я надеюсь, что есть некоторые другие приемы / алгоритмы, которые делают это намного быстрее, поэтому вот как выглядит моя идеальная структура данных:
- Приоритет номер один - быстрое обновление / реконструкция всей структуры данных.
- Менее важно точно разделить объекты на ячейки одинакового размера, мы можем нарисовать несколько дополнительных объектов и сделать несколько дополнительных проверок столкновений, если это означает, что обновление происходит немного быстрее
- Память не очень важна (компьютерная игра)