2013-11-25 3 views
0

Я пишу 2D-платформерную игру, использующую Java для Android.Структура данных, используемая для платформы-платформы.

В настоящее время у меня есть все игровые объекты (за исключением аватара, хранится в массиве массива «Entity»

Entity[][] 

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

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

Какую структуру данных следует использовать? Я думал о чем-то вроде

ArrayList<Entity>[][] 

Но это будет очень дорого, и трата памяти, так как повторяющиеся элементы являются исключением из правила.

Я также рассматривал возможность разделения движущихся объектов на свои собственные ArrayList и прокручивание их всех, но это уродливое решение.

Значит, любые идеи о том, что я мог бы использовать? Я хочу что-то довольно быстро, но не слишком интенсивно с памятью.

ответ

0

Двухмерный массив для хранения сущностей, теряющий память (большинство блоков не будет занято) и не позволяет перекрывать объекты, как вы заметили. С несколькими объектами простой ArrayList (без видимых массивов), вероятно, будет полностью адекватным.

Если у вас есть много объектов, вы можете рассмотреть структуру данных с четырьмя деревьями или другую структуру пространственного индексирования (отметьте http://en.wikipedia.org/wiki/Spatial_index).

Как более простой и более «традиционный» подход, как сохранить двухслойный вид ваших объектов - ArrayList всех активных (видимых) и ArrayList всех неактивных (слишком далеких - по уходу)? Если производительность имеет значение, вы можете отключить обнаружение столкновения на последнем и немного или совсем не выполнять AI/обслуживание.

+0

Я использовал квадрат один раз (создавал симулятор силы тяжести N), но я понятия не имею, как использовать квадтри в этом контексте. В игре нет маленьких «экранов», а скорее большой непрерывный - или он просто загрузит более одного квадранта автоматически, а затем разрешит мне делать пространственный запрос для меньшего набора? Я понимаю это неправильно? – Haedrian

+0

Для каждого объекта вы должны искать прямоугольник вокруг этого объекта для проверки на наличие конфликтов: http://gamedevelopment.tutsplus.com/tutorials/quick-tip-use-quadtrees-to-detect-licious-collisions-in-2d -space - gamedev-374. В качестве оптимизации вы можете сначала проверить, полностью ли ограничены границы в квадранте сущности в квадратном дереве (в этом случае вы просто используете этот квадрант как возможные сущности для столкновения). – creichen

+0

Чтобы разработать: в отличие от того, что говорится в статье, вы можете использовать квадровое дерево в качестве своего эксклюзивного хранилища и удалять и повторно добавлять объекты, когда они пропускают границы квадранта. Или вы можете основываться на глобальном ArrayList и работать как предлагаемая статья. Но единственной точкой квадрового дерева является ускорение обнаружения столкновений, что также, вероятно, является единственной причиной того, почему вы использовали Entity [] [] в начале. – creichen

0

А что вы сохраняете объекты как:

Entity[][] 

И при условии, вы посмотрите вверх объекты, как:

Entity e = entities[i][j] 

Но держать вас врагов в:

Map<String,List<Entity>> map 

Если ключ является строкой, созданной путем объединения i и j со случайным средним символом (например, «1.15», если i == 1 и j == 15). Теперь вы сохраняете быстрый поиск объектов, а также быстро просматриваете (хотя и не так быстро, как массив) врагов без лишнего пустого пространства.

+0

Проблема в том, что я думаю, что это тоже очень дорого. Чтобы переместить единый объект из другого, мне нужно будет создать новый список, поместить в него объект, искать старый список и потенциально удалить его, а затем помещать в хэш-карту. Я согласен с этим намного лучше, чем массив List , но на мой взгляд все еще много накладных расходов. – Haedrian

Смежные вопросы