Як я представляю снаряди у відеоігри?


14

Я роблю просту гру з фіксованим шутером, схожу на "Галага" ,) в рамках презентації, яку я роблю. Мені цікаво, які стратегії та структури даних використовували б люди для відстеження снарядів, як лазери, вистрілені з космічного корабля. Надзвичайно проста реалізація, яку я раніше використовував, - просто представляти кожен снаряд як крапку та перевіряти на зіткнення з усіма об'єктами в сцені.

Однак це здається дорогим у великих сценах з багатьма снарядами; Мені цікаво, які інші типи стратегій або реалізацій використовуються для цього типу використання. Які ігри на зразок FPS використовують для відстеження снарядів (куль, снарядів танка тощо)?


5
Багато FPS-ігор припускають, що кулі миттєві, але є й такі, які обчислюють траєкторії та час у дорозі.
Джон Макдональд

2
+1 - це чудове запитання, і я не обов'язково обмежувати його також 3d.
ashes999

Відповіді:


8

Для дуже швидких снарядів (таких як лазери або кулі) ви можете використовувати Ray .

Промінь має початкову і кінцеву точку. (Дуже мінімальна) структура даних для променя є:

struct Ray
{
  Vector3f start, end ;
} ;

Виглядає так:

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

(Ви також можете кешувати вектор напрямку та довжину, але я використовував дуже просте значення defn вище).

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

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

Промені можна ефективно зіткнути зі сферами, aabbs, опуклими корпусами і т. Д. Ознайомтесь з моїм проектом Hullinator для дійсної запущеної програми (CTRL + Клацніть, щоб стріляти променями)


1
Промінь не дуже добре працює для багатьох снарядів. Наприклад, будь-який снаряд, який може бути опушений, як снаряди танків. Промені чудово підходять для прямокутних снарядів.
MichaelHouse

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

7
Технічно промінь - це відправна точка і напрямок. Це можна визначити З початковою точкою та іншою точкою, але це не є частиною її визначення. За визначенням, промені є нескінченними і не мають кінцевої точки.
Кейсі Кубалл

1
Ви маєте рацію, що я описав, це насправді лінійний сегмент , але більшість людей називають їх променями, коли говорять про виявлення зіткнень.
bobobobo

3

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

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


2

Коли ви хочете оптимізувати для виявлення зіткнень, ви можете зберігати всі ігрові об’єкти у дво- або тривимірному дереві . Ця структура даних робить дуже ефективним пошук усіх об'єктів у певній області.

Однак бінарні дерева мають той недолік, що вони легко вироджуються, коли об’єкти додаються, видаляються та змінюються свої позиції, тому вам потрібно буде врівноважити його автоматично.

Компроміс, який було б простіше здійснити, але не настільки ефективний, було б використовувати підхід на основі шматка. Розділіть ігрове поле на кубики і відслідковуйте, які предмети торкаються кожного куба. Перевіряючи на зіткнення з об'єктом, вам потрібно лише перевірити його на списку об'єктів кубів, яких він торкається (замініть "куб" на "прямокутник" для 2d-гри).

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