Як у дуже простих 3D гоночних іграх обробляються зіткнення?


9

Мені було цікаво, як робляться зіткнення в деяких простих іграх з 3d-гонок на автомобілі (особливо в таких іграх, як Outrun 2 / Motoracer).

У класичних автомобільних гоночних іграх зі складним оточенням (відкритий світ), я думаю, це робиться з базовою коробкою (для машини) для зіткнення з літаком (для доріжок, будівель тощо). Вся справа була б оптимізована за допомогою деяких обмежувальних коробок (саме так відбувається зіткнення у багатьох іграх).

У такій грі, як Outrun 2 / Motoracer, геймплей настільки простий, що розробникам, можливо, цього не потрібно, і все можна було б значно спростити. Для тих, хто ніколи не грає, ось що таке специфічне:

  • Автомобіль / велосипед завжди наклеєний на дорогу.
  • Дорога завжди однакових розмірів і має дуже просту форму.
  • Єдині можливості - це слідувати цією дорогою, її неможливо покинути дорогу, або зіткнутися з чимось іншим (крім інших автомобілів / велосипедів, але нас це не хвилює).
  • Коли ви стикаєтесь з дорогою, відбувається дуже основне зіткнення аркад (автомобіль просто відштовхується від нього)

Ось як я думаю, зіткнення (могло) було здійснено:

Весь трек можна було б вважати гігантською кривою 3d Безьє. З цієї кривої можна було формувати дорожні багатокутники (використовуючи передні, ліві та вгору вектори, породжені кривою). За допомогою цього методу також можна розмістити та вирівняти інші елементи (наприклад, будинки, дерева, ...).

Потім, щоб вирішити зіткнення (і намалювати автомобіль):

1) Знайдіть найближче положення на кривій 3d від поточного положення автомобіля 3d. Іншими словами, перетворіть 3d-положення автомобіля в положення кривої Безьє. Кожне 3d положення на дорозі можна розглядати як зміщення по 3d кривій ( t) + бічне зміщення ( d). Перевірте зображення нижче, якщо воно не зрозуміло (це двомірний приклад, але це легко застосувати до 3d).

введіть тут опис зображення

коли t = 0 машина знаходиться на початку колії, коли t = 1 машина знаходиться в кінці. коли d = -1 або 1 автомобіль знаходиться на кордоні колії, коли d = 0 автомобіль знаходиться посередині дороги

2) вирівняти автомобіль до дороги за допомогою tі d(дуже просто: для будь-яких tі dзначень я можу отримати 3d положення + вектори вперед / вперед / вліво). тепер автомобіль склеєний на дорозі

3) перевірити бічне переміщення dавтомобіля. якщо величина занадто велика (d > 1)або низька, (d < -1)автомобіль не вдається . просто затисніть його, щоб поставити машину в потрібне місце.

Це також робить 3D-вибивання дуже простим, просто намалюйте трек від поточного tположення автомобіля до t + some_big_enough_value_to_avoid_visible_clipping.

Або, можливо, я абсолютно помиляюся: було б набагато швидше і простіше просто перевірити зіткнення автомобіля (обмежувальний ящик) і дуже спрощений набір полігонів, що представляють колію (без будівель і подібних). 3D-світ (і отримана модель колізії) просто був би сформований раніше, використовуючи якийсь сторонній інструмент (не більше 3d кривої при запуску гри, лише купу полігонів).

Відповіді:


16

Я працював над кількома комерційними іграми, подібними до тих, що ви описуєте.

У кожній з цих ігор ми насправді мали багатокутники, що створювали невидиму "стіну" по сторонах доріжки, і робили традиційні випробування на зіткнення проти цих стін. Це означало, що ми можемо мати деякі додаткові небезпеки, що стикаються біля дороги, усередині невидимих ​​стін, а також дозволяємо нам змінювати ширину дороги швидше, ніж ви зазвичай можете, коли підходите до сплайну.

Але з урахуванням цього ми також зробили те, що ви перераховуєте в розділі про те, як я думаю, зіткнення спрацювало б для захисту від тунельних / глюків зіткнення, і ця система також активно використовувалася для перегонів логіки AI. Ми також використовували його для визначення того, які автомобілі лідирують, щоб ми могли відображати індикатор "1-й / 2-й / 3-й / тощо" на HUD. Іноді ці дані також використовувались для повторної заготовки автомобіля після великої аварії.

Один фрагмент, який ви пропустили в тому, як я думаю, що зіткнення спрацювало б це те, що коли ви працюєте зі шліцами, як це, ви зазвичай даєте ребра сплайнів. Ребра - це біти даних, що виражають, наскільки далеко доріжка простягається вбік у кожному напрямку від сплайна. Отже, для шліца довжиною 100 метрів у вас може бути 50 ребер, що дає ширину доріжки кожні два метри по її довжині. Це дозволяє вашій доріжці змінювати ширину уздовж її масштабу. У іграх, над якими я працював, ці ребра також розмежовували "поверхню треку" та "зону переміщення". Таким чином, у вас буде один набір ширини дороги, який говорить про те, наскільки далеко від середини шпонки у вас є хороший асфальт, а потім інша ширина, яка говорить про те, наскільки далеко пісок / трава / все, що виходить за межі цього. Це дозволить нам мати гравців, здатних проїхати розумну відстань від колії, але все ж AI знає, де було справжнє дорожнє покриття.

Багато ігор, над якими я працював, також зберігали інші дані в ребрах; В одній грі зафіксовано інформацію про освітлення доріжок у ребрах, для легкого обчислення того, чи знаходиться ділянка в тіні (яка потім використовувалася для візуалізації автомобіля, вирішення того, чи слід намалювати спалах об'єктива та інші ефекти). Інший пояснив інформацією про те, в яких місцях розміщення камер у кінематографах можна побачити цю частину сплайну, тому нам не довелося робити обчислення прямолінійного огляду під час повторів. Ще одна включала інформацію про те, скільки смуг було на сплайні, в якому напрямку вони йшли, і горизонтальному переміщенні, де розташована кожна смуга. Це дозволило нам включити автомобілі дорожнього руху, які могли б правильно їхати на дорожніх смугах. Ребра чудові для зберігання будь-яких різних даних, які можуть вам знадобитися щодо дорожнього покриття.

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

Ваш опис відсікання дає хороший основний опис того, як можна використовувати підхід сплайну, але насправді це трохи складніше, ніж ви пропонуєте - якщо ви використовуєте шпонки для вибивання таким чином, довгі повороти шпильки часто не притягуватимуть протилежну сторону повороту, оскільки, вимірюючи відстань уздовж колії, протилежна сторона повороту може бути дуже далеко, навіть якщо це лише кілька метрів, коли вимірюється, коли ворона летить. Крім того, відстані, на яких можна побачити світову геометрію, зазвичай відрізняються від відстані, на якій можна побачити сітку доріжок, тому вони теж не вписуються в цю систему. Мій досвід полягає в тому, що в більшості випадків для визначення того, чи слід малювати модель, краще не покладатися на слідуючу логіку; це набагато надійніше і призводить до менших збоїв, щоб використовувати для цього стандартне тестування фрустуми камери.


Інформативно і весело читати відповідь
onedayitwillmake

0

У своєму гоночнику OpenGL я спочатку почав використовувати два кола для визначення меж траси, але це здавалося занадто великим клопотом. Я просто використовую glReadPixel для читання кольору пікселів. Якщо автомобіль гравців перевищує зелений (трав'яний) піксель, то рух ще більше обмежений. На продуктивність дуже мало ефекту.


Це звучить так, як ви описуєте 2D гру (кола, зіткнення кольорів пікселів). Це так? Тоді відповідь офтопік.
Кромстер

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