Подтвердить что ты не робот

Управление обнаружением столкновений в играх

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

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

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

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

Пара комментариев об этом:

  • Мне кажется измененным, что EnemyManager находится в "контроле" вместо PlayerProjectilesManager
  • И обнаружение столкновения, и реакция столкновения обрабатываются одним и тем же владельцем, это не является требованием с моей точки зрения

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

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

4b9b3361

Ответ 1

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

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

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

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

Ответ 2

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

Итак, в прошлом я сказал, что класс EnemyManager

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

а также для игровых снарядов был класс PlayerProjectilesManager

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

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