Как я представляю снаряды в видеоигре?


14

Я делаю простую фиксированную игру-шутер, похожую на «Galaga» , как часть презентации, которую я делаю. Мне интересно, какие стратегии и структуры данных люди будут использовать для отслеживания снарядов, например, лазеров, запущенных с космического корабля. Очень простая реализация, которую я использовал ранее, состоит в том, чтобы просто представлять каждый снаряд как точку и проверять наличие столкновений со всеми объектами в сцене.

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


5
Многие игры FPS предполагают, что пули являются мгновенными, но есть те, которые рассчитывают траектории и время в пути.
— Джон Макдональд

2
+1 это отличный вопрос, и я бы не стал ограничивать его 3d.
— ashes999

Ответы:


8

Для очень быстрых снарядов (таких как лазеры или пули) вы можете использовать Луч .

Луч имеет начальную точку и конечную точку. (Очень минимальная) структура данных для луча:

struct Ray
{
  Vector3f start, end ;
} ;

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

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

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

Если луч - это лазерный луч, который движется со скоростью света, вы бы просто сохранили луч (начиная от сопла пистолета и заканчивая где-нибудь на стене) в течение нескольких кадров. Все, что пересекает луч в каждом кадре, получает урон.

Если луч является более медленным снарядом (например, пуля), то расстояние, которое пуля прошла за временной шаг, моделируется лучом. Начальная точка - это место, где луч находится в начале кадра, а конечная точка - это место, где луч будет находиться после завершения кадра. Все, что находится на пути луча пули, повреждено пулей.

Лучи могут эффективно сталкиваться со сферами, аббами, выпуклыми оболочками и т. Д. Посмотрите на мой проект Hullinator для действующей программы (CTRL + щелчок, чтобы запустить лучи)


1
Луч не очень хорошо работает для многих снарядов. Например, любой снаряд, который можно метнуть, например, снаряды танка. Однако лучи хороши для метательных снарядов.
— MichaelHouse

Что ж, если снаряд движется очень медленно (по сравнению с пулей или лазером), тогда да, я бы смоделировал его как обычное тело (так же, как игрока)
— bobobobo

7
Технически, луч - это отправная точка и направление. Это может быть определено с начальной точкой и другой точкой, но это не является частью его определения. По определению, лучи бесконечны и не имеют конечной точки.
— Кейси Кубалл

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

3

Использование луча хорошо работает для мгновенно перемещающихся снарядов, таких как пули. Для снарядов с более низкой скоростью, таких как тип, который вы будете использовать для космической игры, имеет смысл просто отслеживать их положение в игровом мире, как и любой другой объект. Я часто использую базовый класс Entity, который содержит свойства любого долговременного игрового объекта - положение, вращение, поле столкновения и т. Д. Мой игрок, управляемый снарядами, наследует это, и мой игровой мир должен знать только то, как иметь дело с сущность суперкласса, а не каждый отдельный тип сущности.

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


2

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

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

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

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