Эффективное отображение игровых положений объекта в Java

В Java (Swing) скажите, что у меня есть 2D игра, где у меня есть различные типы объектов на экране, такие как игрок, плохие парни, включения питания, и т.д. Когда игровые движения через экран, чтобы сделать эффективную проверку того, что находится в непосредственной близости плеера, я думал бы, что захочу индексный доступ к вещам, которые являются около символьно-ориентированного на их положении.

Например, если плеер 'P' ступает на элемент 'E' в следующем примере...

| | | | | |
| | | |P| |
| | |E| | |
| | | | | |

... должен был бы сделать что-то как:

if(player.getPosition().x == entity.getPosition().x && 
              entity.getPosition.y == thing.getPosition().y)
{
    //do something
}

И это прекрасно, но это подразумевает, что объекты занимают свои позиции, и для этого если бы у меня было МНОГО объектов на экране, то я должен был бы циклично выполниться через все возможные доступные объекты и проверить каждое положение по положению плеера. Это кажется действительно неэффективным особенно, если Вы начинаете получать тонны объектов.

Так, я подозревал бы, что захочу своего рода карту как

Map<Point, Entity> map = new HashMap<Point, Entity>();

И храните мою информацию точки там, так, чтобы я мог получить доступ к этим объектам в постоянное время. Единственная проблема с тем подходом состоит в том, что, если бы я хочу переместить объект в другую точку на экране, я должен был бы перерыть значения HashMap для объекта, который я хочу переместить (неэффективный, так как я не знаю его положения Точки заранее), и затем после того как я нашел, что это удаляет его из HashMap и повторно вставляет его с новой информацией о положении.

Какие-либо предложения или совет относительно того, какую структуру данных / формат устройства хранения данных я должен использовать здесь, чтобы иметь эффективный доступ к Объектам на основе их положения, а также Положение на основе Объекта?

7
задан Ben Lakey 12 June 2010 в 04:53
поделиться

3 ответа

Разделение пространства может быть эффективным.

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

Вставка занимает постоянное время. Удаление - практически бесконечно малая доля от n (общего числа сущностей), если n очень велико и вы эффективно настроили свои разделы. Поиск по близости имеет такое же время выполнения, как и удаление. Тем не менее, технически O(n) все еще O(n), какой бы маленькой ни была доля. Это станет очевидным, если раздел станет необычно переполненным.

Чтобы получить список всех объектов в пределах x единиц от объекта, вы должны сначала получить список всех разделов, охватываемых квадратом шириной 2x с центром на объекте. Если вы используете сетку разделов, это довольно тривиально. Далее вы перебираете все сущности в этих разделах и возвращаете каждую из них с расстоянием x или меньше до рассматриваемой сущности.

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

4
ответ дан 7 December 2019 в 07:40
поделиться

неэффективно, так как я не знаю его положение Point заранее
Правильно ли я, что этот объект сущности не имеет информации о местоположении в нем? Предлагаю добавить. Или, в противном случае, вы можете получить карту текущих позиций сущностей Map и сначала получить позицию. Ничего фантастического.

0
ответ дан 7 December 2019 в 07:40
поделиться

Если между Entity и Point существует отображение один-к-одному, и вы хотите иметь возможность отображения в обоих направлениях, то бимап является наиболее естественной структурой данных.

В Guava есть реализация BiMap которая поддерживает операцию BiMap inverse() view. Это только представление, поэтому оно совсем не затратное.

В качестве альтернативы вы можете управлять собственными Map и Map, но это было бы изобретением колеса.

3
ответ дан 7 December 2019 в 07:40
поделиться
Другие вопросы по тегам:

Похожие вопросы: