Как я могу реализовать быстрое и точное обнаружение столкновений 2D?


11

Я хорошо знаю, как определять, сталкиваются ли два или более 2D-объекта, но мне интересно, как решить, проверять ли столкновение. В предыдущих проектах я просто проверял каждый объект на предмет любого другого объекта (я знаю, уровень глупости O (n ^ 2)), и это создавало не очень плавный игровой процесс.

Различные форумы приветствуют величие Quadtrees, B-Trees и любых других видов деревьев или структур, о которых вы только можете подумать.

Какова наиболее эффективная структура для определения необходимости проверки столкновения?


1
Одной вещью, которую вы можете рассмотреть, является проверка столкновений только для объектов, которые были перемещены, и только для объектов, которые находятся рядом с вами. Моя текущая система работает хорошо (сотни тысяч объектов) - и это все, что я делаю.
ультифинит

Я думаю, gamedev.stackexchange.com/questions/14369/… может вам очень помочь. Первоначально он был предназначен для алгоритма параллельной обработки, но я думаю, что тот же алгоритм может также улучшить однопоточные приложения.
Ali1S232

1
@ultifinitus Об этом я и спрашиваю. Как определить, какие объекты находятся поблизости, не проходя через каждый объект и не проверяя его положение?
Майк Клак

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

1
Это не дубликат, потому что я спрашивал, какая структура лучше всего подходит для определения, стоит ли нам проверять наличие столкновения. Другой вопрос - о прозрачных и непрозрачных столкновениях. Не говоря уже о том, что этот вопрос задавался примерно за год до того, на который вы ссылались.
Майк Клак

Ответы:


12

Для двумерной игры, если 2D-объекты не имеют очень сильного распределения по одной стороне вашей карты, равномерная сетка - почти всегда путь. Сложность памяти прямолинейна (пропорциональна размерам вашей карты), и с разумным распределением имеет время поиска O (1) и среднее значение log (numberOfObjects / (строки * столбцы)) ^ 2 теста пересечения сделано за клетку. Вы можете решить проверять только те ячейки, в которых есть объект, который перемещается, что делает статическую геометрию намного более эффективной. Однородную сетку легко изменить на лету (гораздо меньше проблем, чем в древовидных решениях), и ее проще реализовать. Единственный раз, когда я бы сказал, чтобы не использовать его в 2D-игре, это когда требования к памяти для равномерной сетки становятся слишком большими (скажем, космический сим, где уровни редки, но огромны).


Как это решение работает с объектами, которые граничат с 2 или 4 ячейками сетки?
ashes999

1
Любая ячейка, в которой объект перекрывается, считается, что он находится в нескольких ячейках. Большинство структур пространственных данных будут решать проблему перекрытий аналогичным образом.
Дарси Рейнер

Вау, это очень мило. +1 Ура чувак.
ashes999

1

Механизмы 2D Physics, такие как Box2D и Chipmunk, активно используют пространственную хэш-карту

см. http://chipmunk-physics.net/release/ChipmunkLatest-Docs/#CollisionDetection для справки. Демонстрации бурундука включают действительно хороший визуализатор пространственного хеша, который дает понять, как работает их техника.


1

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

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

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

Кроме этого, я с Дарси, хорошая сетка хороша.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.