Управление обнаружением столкновений в играх - PullRequest
16 голосов
/ 30 ноября 2010

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

Позвольте мне уточнить - скажем, в игре у меня есть группа врагов игруппа снарядов, выпущенных игроком.Так, в прошлом я говорил, например, класс EnemyManager, что каждый кадр обновляет позиции врагов, а также для снарядов игрока был класс PlayerProjectilesManager, который перемещался вокруг пуль.Это круто - все хорошо и модно.Но затем я решаю, что хочу, чтобы пули воздействовали на врагов (сумасшедший, я знаю!).Это означает, что где-то в коде мне нужно:

  1. Выяснить, какие пули и враги сталкиваются (мне все равно, как на этот вопрос)
  2. Выяснить реакцию накаждое столкновение

Итак, в основном то, что я делал в прошлом, это просто взял класс EnemyManager в «владение» столкновениями, и во время своего цикла обновления он находит пули игрока, которые сталкиваются с пулями противника.(т.е. шаг 1), а также вызывает код для обоих объектов для обработки столкновения (например, враг теряет здоровье, пуля исчезает) (то есть шаг 2).Поэтому я дал контроль над обнаружением столкновений и «реакцией» столкновений на EnemyManager.

Пара замечает по этому поводу:

  • Мне кажется, что EnemyManager находится под «контролем», а не PlayerProjectilesManager
  • Обнаружение столкновений и столкновений как «контролируется»«Реакция» обрабатывается одним и тем же владельцем, с моей точки зрения это не является обязательным требованием

По моему мнению, стороннее юридическое лицо, управляющее обнаружением столкновений.Например, есть CollisionManager, в котором есть код, который знает, какие другие менеджеры должны обнаруживать коллизии.Это приводит к другим вопросам, таким как, какие интерфейсы «выставляют» менеджеры для эффективного обнаружения столкновений, не подвергая CollisionManager слишком многим внутренностям.Затем я полагаю, что CollisionManager передает какое-то событие, содержащее два объекта, столкнувшихся и т. Д., И, возможно, EnemyManager / PlayerProjectilesManager может отдельно прослушивать эти события и реагировать соответственно и раздельно.Начинаю иметь смысл в моей голове.:)

Мысли?Почти в каждой игре есть обнаружение столкновений, поэтому я уверен, что это обсуждалось ранее.:)

Ответы [ 2 ]

11 голосов
/ 30 ноября 2010

это хороший вопрос. Лично я бы не стал так сильно усложнять использование «Менеджеров». Допустим, у нас есть GameEngine, который запускает игру в основном цикле. Этот основной цикл может состоять из 3 шагов: получить пользовательский ввод, обновить состояние всех объектов в игре (на основе пользовательского ввода) и, наконец, снова нарисовать все на экране.

Все, что касается обнаружения столкновений, выполняется на втором этапе - при обновлении состояния объектов. Допустим, все объекты в игре хранятся в пуле. Это включает в себя игрока, патроны, врагов и даже мир (если вы хотите, чтобы на мир так или иначе влияли). Все различные объекты могут иметь некоторые общие свойства - они могут быть Drawable, Movable, Collidable e.t.c. (думайте как реализация интерфейса или расширение базового класса, чтобы иметь эти свойства)

Для каждого из этих свойств у меня был бы класс, который бы что-нибудь делал со всеми объектами в пуле. Как Mover.moveAll (objectsFromPool). Это переместит все объекты, которые являются Подвижными. То же самое для обнаружения столкновений -> после того, как мы переместили объекты с Mover, тогда мы проверяем на столкновение с CollisionDetector.cehckAll (objectsFromPool). Этот метод checkAll () будет выполнять фактическое обнаружение столкновений между самими объектами, зная их координаты. Если объект Collidable, CollisionDetector будет вызывать его метод onCollide (withOtherObject), а затем сам объект реагирует должным образом, в зависимости от того, какой другой объект ударил его. Скажем, если игрок тронут вражеским телом, они оба отступят, например. Если в пулю попала другая пуля - они оба будут помечены для удаления. Если враг поражен пулей, то произойдет некоторый урон, и пуля будет помечена для удаления. Все эти реакции должны быть в самих соответствующих объектах. Детектор столкновений применяет свои алгоритмы для обнаружения столкновений между любыми двумя объектами, а затем вызывает их метод onCollide (withOtherObjct). Если объект не является Collidable, CollisionDetector будет просто игнорировать его (например, частицы дождя или пыль не являются Collidable).

Надеюсь, мне удалось выразить себя правильно:)

0 голосов
/ 30 ноября 2010

Кстати, вопросы, относящиеся к разработке игр, лучше всего подходят для https://gamedev.stackexchange.com/.

Итак, в прошлом я говорил класс EnemyManager

Я считаю, что любой класс SomethingManager является признаком того, что ваш код еще не организован точно. По большей части объекты должны управлять собой. Если они не могут, это подразумевает, что есть некоторая внешняя информация о них, и эта информация, вероятно, имеет представление более конкретное, чем «менеджер». 3 примерами для конкретной игры могут быть GameWorld, GameRegion или GameLevel. Враги существуют в мире, или регионе мира, или на текущем игровом уровне, так что пусть такой объект поддерживает свой список врагов.

и аналогично для игрока снаряды имели класс PlayerProjectilesManager

Снаряды тоже будут жить в каком-то игровом пространстве, мире, регионе или уровне.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...