Я делаю простую фиксированную игру-шутер, похожую на «Galaga» , как часть презентации, которую я делаю. Мне интересно, какие стратегии и структуры данных люди будут использовать для отслеживания снарядов, например, лазеров, запущенных с космического корабля. Очень простая реализация, которую я использовал ранее, состоит в том, чтобы просто представлять каждый снаряд как точку и проверять наличие столкновений со всеми объектами в сцене.
Однако это кажется дорогостоящим в больших сценах со многими снарядами; Мне интересно, какие другие типы стратегий или реализаций используются для этого типа использования. Что такие игры, как FPS, используют для отслеживания снарядов (пуль, танковых снарядов и т. Д.)?
game-design
design-patterns
Polaris878
источник
источник
Ответы:
Для очень быстрых снарядов (таких как лазеры или пули) вы можете использовать Луч .
Луч имеет начальную точку и конечную точку. (Очень минимальная) структура данных для луча:
Выглядит так:
(Вы также можете кэшировать вектор направления и длину, но я использовал очень простое определение выше).
Если луч - это лазерный луч, который движется со скоростью света, вы бы просто сохранили луч (начиная от сопла пистолета и заканчивая где-нибудь на стене) в течение нескольких кадров. Все, что пересекает луч в каждом кадре, получает урон.
Если луч является более медленным снарядом (например, пуля), то расстояние, которое пуля прошла за временной шаг, моделируется лучом. Начальная точка - это место, где луч находится в начале кадра, а конечная точка - это место, где луч будет находиться после завершения кадра. Все, что находится на пути луча пули, повреждено пулей.
Лучи могут эффективно сталкиваться со сферами, аббами, выпуклыми оболочками и т. Д. Посмотрите на мой проект Hullinator для действующей программы (CTRL + щелчок, чтобы запустить лучи)
источник
Использование луча хорошо работает для мгновенно перемещающихся снарядов, таких как пули. Для снарядов с более низкой скоростью, таких как тип, который вы будете использовать для космической игры, имеет смысл просто отслеживать их положение в игровом мире, как и любой другой объект. Я часто использую базовый класс Entity, который содержит свойства любого долговременного игрового объекта - положение, вращение, поле столкновения и т. Д. Мой игрок, управляемый снарядами, наследует это, и мой игровой мир должен знать только то, как иметь дело с сущность суперкласса, а не каждый отдельный тип сущности.
Чтобы повысить производительность, очень часто нужно хранить пул для любых объектов, которые вы будете часто создавать и разрушать. Когда вам нужен новый снаряд, который вы вытащите из этого пула, измените новый снаряд по мере необходимости и верните его обратно в пул, когда он истек.
источник
Если вы хотите оптимизировать обнаружение столкновений, вы можете хранить все игровые объекты в двух- или трехмерном дереве . Такая структура данных позволяет очень эффективно извлекать все объекты в определенной области.
Однако у двоичных деревьев есть недостаток, заключающийся в том, что они легко вырождаются при добавлении, удалении объектов и изменении их положений, поэтому вам необходимо автоматически их сбалансировать .
Компромисс, который было бы легче реализовать, но не был бы столь же эффективным, состоял бы в использовании подхода, основанного на чанках. Разделите игровое поле на кубики и проследите, какие объекты касаются каждого куба. Когда вы проверяете наличие столкновений с объектом, вам нужно проверять его только по спискам объектов кубов, к которым он прикасается (замените «куб» на «прямоугольник» для 2D-игры).
источник