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

14

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

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

Polaris878
источник
5
Многие игры FPS предполагают, что пули являются мгновенными, но есть те, которые рассчитывают траектории и время в пути.
Джон Макдональд
2
+1 это отличный вопрос, и я бы не стал ограничивать его 3d.
ashes999

Ответы:

8

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

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

struct Ray
{
  Vector3f start, end ;
} ;

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

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

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

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

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

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

bobobobo
источник
1
Луч не очень хорошо работает для многих снарядов. Например, любой снаряд, который можно метнуть, например, снаряды танка. Однако лучи хороши для метательных снарядов.
MichaelHouse
Что ж, если снаряд движется очень медленно (по сравнению с пулей или лазером), тогда да, я бы смоделировал его как обычное тело (так же, как игрока)
bobobobo
7
Технически, луч - это отправная точка и направление. Это может быть определено с начальной точкой и другой точкой, но это не является частью его определения. По определению, лучи бесконечны и не имеют конечной точки.
Кейси Кубалл
1
Вы правы, на самом деле я описал отрезок , но большинство людей называют их лучами, когда говорят об обнаружении столкновений.
бобобо
3

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

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

JPRO
источник
2

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

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

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

Philipp
источник