Як я можу здійснити швидке, точне 2D виявлення зіткнень?


11

Я добре знаю, як виявити, чи стикаються два чи більше 2D об'єктів, але мене цікавить, як вирішити, чи слід перевірити на зіткнення. У попередніх проектах я просто перевіряв кожний об'єкт щодо будь-якого іншого об'єкта (я знаю, рівень тупості O (n ^ 2)), і це створювало менш флюїдний геймплей.

Різні форуми вітають велич Квадратів, B-Дерев та будь-якого іншого дерева чи структури, про які ви можете придумати.

Яка найбільш ефективна структура для визначення того, чи слід перевіряти зіткнення?


1
Одне, що ви можете розглянути, - це лише перевірка зіткнень для об’єктів, які перемістилися, і лише об'єктів, які вам близькі. Моя нинішня система працює добре (сотні тисяч об’єктів) - і це все, що я роблю.
ultifinitus

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

1
@ultifinitus По суті, про це я прошу. Як визначити, які об’єкти знаходяться поблизу, не повторюючи кожен об'єкт і не перевіряючи його положення?
Майк Клакк

Майк, ти можеш надіслати мені електронний лист для якогось конкретного коду, який я використав, він знаходиться в c ++ - або я можу надати вам основну структуру, хоча через це може вийти досить неоднозначним і складним.
ultifinitus

1
Це не дублікат, тому що я запитував, яка структура найкраще підходить для визначення, чи варто нам турбуватись щодо перевірки на зіткнення. Це інше запитання стосувалося прозорих проти непрозорих зіткнень. Не кажучи вже про те, що це питання було задано приблизно за рік до того, з ким ви зв’язалися.
Майк Клакк

Відповіді:


12

Для 2d гри, якщо 2D-об'єкти не мають дуже важкого розповсюдження на одну сторону вашої карти, рівномірна сітка майже завжди є шлях. Складність пам’яті прямо вперед (пропорційна розмірам вашої карти) і при розумному розподілі має O (1) час огляду та середнє значення журналу (числоOfObjects / (рядки * стовпці)) ^ 2 тести перетину зроблено на клітинку. Ви можете вирішити перевірити лише комірки, у яких перемістився об'єкт, що робить статичну геометрію набагато ефективнішою. Легко змінювати рівномірну сітку на льоту (набагато менше болю, ніж у дерев яних рішень), і це простіше втілити. Єдиний раз, коли я хотів би сказати, що не використовувати його у 2D грі, це коли вимоги до пам'яті рівномірної сітки стають занадто великими (скажімо, пробіл, де рівні рідкі, але величезні).


Як це рішення має відношення до об'єктів, які межують з 2 або 4 клітинками сітки?
ashes999

1
Будь-яка комірка об'єкта перекривається, вона вважається такою, що є, тому об'єкт може знаходитися в декількох комірках. Більшість структур просторових даних будуть вирішувати питання перекриттів аналогічним чином.
Дарсі Рейнер

Ого, це преетті розумний. +1 Будьте чуваком.
ashes999

1

Двигуни 2D Physics, такі як Box2D та бурундук, широко використовують просторову карту хешу

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


1

Якщо ваш світ має один дуже "довгий" вимір (називайте його X), порівняно з іншими, ви можете зберігати об'єкти в упорядкованому списку, який ви можете пересортувати під час їх переміщення, а потім виявлення зіткнення означає лише перевірку об'єктів, які перекриття по осі X.

Інша можливість полягає в тому, щоб зберігати активні / пасивні списки об'єктів і не турбуватися з пасивними об'єктами (які взагалі не рухаються).

Якщо це всі об'єкти середнього розміру, які видно гравцеві на екрані, все проти всього, мабуть, не дуже погано.

Крім того, що я з Дарсі, однакова сітка хороша.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.