Как создать карту путевых точек в 2D-платформере без дорогостоящих симуляций прыжков?

Я работаю над игрой (используя Game Maker: Studio Professional v1.99.355), которая должна иметь как изменяемую пользователем геометрию уровня, так и поиск пути AI, основанный на физике платформера. Из-за этого мне нужен способ динамического определения того, какие платформы могут быть доступны с каких других платформ, чтобы построить граф узлов, который я могу передать A*.

Мой текущий подход, более или менее, таков:

  1. Для каждой платформы рассмотрим каждую другую платформу на уровне.

  2. Для каждой из этих платформ, если она явно недостижима (например, из-за того, что она выше максимальной высоты прыжка), не формируйте связь и переходите к следующей платформе.

  3. Если связь кажется возможной, поместите экземпляр ai_character на стартовую платформу и (в рамках текущего шага) смоделируйте попытку прыжка.

3.a Повторите эту попытку прыжка для каждой возможной стартовой позиции на стартовой платформе.

  1. Если эта попытка окажется успешной, запишите данные, необходимые для их репликации в режиме реального времени, и перейдите к следующей платформе.

  2. Если нет, не формируйте ссылку.

  3. Повторите для всех платформ.

Этот подход работает более или менее и создает структуру ссылок, которая при визуализации выглядит следующим образом:

связанные платформы (гиперссылка, потому что нет представителя)

В этом примере почти скрытое розовое привидение в правом нижнем углу пытается добраться до черно-белого ящика. Светло-голубые прямоугольники просто указывают, где находятся распознанные платформы, фактические платформы — это ряды серых прямоугольников. Линии связи имеют зеленый цвет в начале и красный цвет в пункте назначения.

Огромная и вопиющая проблема с этим подходом заключается в том, что для уровня всего 17 платформ (как показано выше) для создания графа узлов требуется больше секунды. Причина этого очевидна, желтый текст в центре экрана показывает нам, сколько времени ушло на построение графика: более 24 000 (!) смоделированных кадров, каждый с сопутствующими проверками на столкновение с каждым блоком — я буквально просто запускаю событие шага персонажа. в цикле while, так что все, что обычно делается для обработки движения платформера в кадре, теперь выполняется 24 000 раз.

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

Пытаясь ускорить процесс, я сосредоточился на другом важном числе отладки, счетчике тестов: 239. Если бы я просто пробовал все возможные комбинации начальной и конечной платформ, мне нужно было бы запустить 17 * 16 = 272 теста. Выяснив различные способы прогнозирования невозможности прыжка, мне удалось сократить количество дорогостоящих тестов на целых 33 (12%!). Однако чем больше исключений и особых случаев я добавляю в код, тем больше убеждаюсь, что реальная проблема заключается в коде симуляции прыжка, что, наконец, приводит меня к моему вопросу:

Как бы вы с полной достоверностью определили, может ли персонаж прыгать с одной платформы на другую, предпочтительно без необходимости моделирования всего прыжка?

Моя конкретная физика платформы:

Прыжки имеют фиксированную высоту, если только вы не попали в потолок.

Горизонтальное движение не имеет ускорения или инерции.

Допускается горизонтальное управление воздухом.

Дополнительная информация: я нашел это видео, в котором описана аналогичная проблема, но не дано хорошего решения. Это буквально единственный ресурс, который я нашел.


person Chris Noone    schedule 04.03.2015    source источник


Ответы (2)


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

Я посмотрел видео и оно натолкнуло меня на мысль. Вместо того, чтобы смотреть на все платформы, чтобы найти, какие прыжки невозможны, что, если бы вы сделали наоборот? Попробуйте разместить ИИ-персонажа на всех платформах и посмотрите, до каких других платформ он может дотянуться. Это, безусловно, легче реализовать, если ваши враги не могут изменить направление в воздухе. Что ж, мозговой штурм — это ключ к тому, чтобы что-то найти.

person Domino    schedule 11.03.2015

Несколько идей, которые вы могли бы попробовать:

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

  2. Попробуйте заранее рассчитать некоторые траектории прыжков. Это не охватит все варианты использования, которые у вас есть, поскольку вы обеспечиваете полный горизонтальный контроль, но может позволить вам быстрее выявить некоторые распространенные случаи.

  3. Вместо схемы генерации ссылок рассмотрите какую-нибудь сетку проходимости. Когда геометрия изменена, вычислите, какие части уровня можно пройти, а какие нет, с некоторым разрешением (что-то похожее на размеры вашего агента может быть хорошей отправной точкой). Вы также можете отфильтровать их по высоте, чтобы плитки сетки, которые выше вашей высоты прыжка, и вы не можете прыгнуть на них с более высокого места, помечались как непроходимые. Затем, когда вы вычисляете свой путь, как часть вашего шага поиска пути, вы можете вычислить, когда вы начинаете прыжок, если путь действительно выполним («начни прыжок, я могу пройти по вертикали не более 5 плиток, и после пика прыжок, я всегда падаю вертикально вниз с некоторой скоростью).

person divinas    schedule 04.04.2019