Я создаю двухмерную пошаговую стратегическую игру с использованием c ++ и SFML-2.0. Движение основано на расстоянии, а не на сетке, с несколькими различными фигурами в форме треугольника, каждый из которых в данный ход может либо вращаться на месте, либо двигаться вперед.
Движение будет работать таким образом, что игрок выбирает место для перемещения фигуры, что создает потенциальный путь для фигуры. Как только игрок подтвердит свое решение, фигура будет перемещаться по этому пути в нужное место. Траектории ограничены двумя факторами: расстоянием, расстоянием, на которое способна фигура, принимая во внимание любые повороты (поэтому, если есть кривая, это будет длина вдоль кривой, а не непосредственно от точки к точке); и угол поворота рулевого колеса, насколько далеко деталь может вращаться в любой (и до каждой) точке при движении (например, от -30 до 30 градусов).
Мой вопрос заключается в том, как мне определить диапазон потенциальных мест, которые игрок может выбрать для перемещения фигуры?
Я не совсем уверен, какие уравнения и / или алгоритм использовать здесь. Мой первоначальный план был чрезвычайно сложным, до такой степени, что его было практически невозможно реализовать, не говоря уже о том, чтобы объяснить, и в этот момент я полностью растерялся, когда проект застопорился.
Как я могу определить диапазон, в котором может двигаться юнит, учитывая его радиус поворота?
Например, на изображении ниже. Красные, синие и зеленые линии будут одинаковой длины. Фиолетовый кружок обозначает диапазон движения, который может перемещать юнит. (Форма, вероятно, неточная, и линии, вероятно, на самом деле не имеют одинаковую длину, но вы поняли идею)
источник
Ответы:
Создайте поле потока или расстояния, используя Dijsktra's.
По сути, заполните сетку, используя алгоритм Дейкстры без указания пункта назначения (возможно, другое имя для этого; не знаю). Просто возьмите каждый открытый узел, вычислите доступных соседей, вставьте их в открытый список, установите в закрытом списке, обновите «следующий» путь родительского узла и т. Д. При определении стоимости достижения нового узла учитывайте ограничения поворота.
Результатом будет то, что у вас есть сеть всех ваших узлов о том, как вернуться к началу. Узлы, которые не могут быть достигнуты, не будут затронуты первым шагом. Для узлов, которые могут быть достигнуты, будет вычислен элемент «следующий узел по наилучшему возможному пути к родительскому», так что вы можете как выделить все узлы, так и затем использовать эту информацию, чтобы показать или выполнить путь перемещения, когда пользователь наводит указатель мыши или нажимает на выделенные области.
источник
Решение грубой силы было бы:
Итак, начиная с синего круга, вы обрабатываете свои пути, заканчивая фиолетовым кругом. Затем вы можете использовать эти точки с центральной точкой на устройстве, чтобы сделать красные треугольники, необходимые для отображения формы. (Просто создание этого изображения заставляет меня понять, что эта форма не является правильной, но будет интересно посмотреть, что на самом деле правильно)
источник
Я собираюсь расширить решение Шона в отдельном ответе, поскольку он представляет собой подход, отличный от того, что я предлагал изначально.
Это решение, вероятно, представляет собой наиболее доступный метод. Это требует разделения вашей среды на узлы. Да, это повторное внедрение подхода, основанного на сетке, но его можно сделать относительно хорошо или использовать для широкого поиска пути с более точным позиционированием, обрабатываемым в узле. Чем более грубая структура узла, тем быстрее поиск пути.
Большая проблема здесь заключается в том, что вы на самом деле имеете дело с облицовкой корабля, поэтому многие традиционные решения поиска пути не могут быть использованы без изменений. Обычно они не зависят от пути, потому что им все равно, как вы попали на узел, в котором находитесь. Это прекрасно работает, когда ускорение, замедление и поворот происходят мгновенно и свободно. К сожалению для вас обращение не бесплатно. Тем не менее, поскольку в этом упрощении действительно есть одна дополнительная информация, мы можем закодировать ее как другую переменную. В физике это будет известно как фазовое пространство.
Предполагая пока 2-мерное измерение, вы можете экстраполировать на 3:
Обычно вам потребуется один узел для каждой допустимой дискретной координатной позиции. Например:
И т. Д. Вы должны построить нодграф соседних точек и соединить их пространственной смежностью. Затем вы будете использовать алгоритм Дейкстры, убивая узлы, которые превышают допустимое для хода значение перемещения, пока не останется неизведанных живых узлов, оставшихся подключенными к исследованным узлам. Каждый узел отслеживает наименьшее расстояние, необходимое для его достижения.
Чтобы расширить этот метод для использования с вращением, представьте этот же нодграф в 3-х измерениях. Направление Z соответствует повороту / направлению и является циклическим, то есть, если вы продолжаете двигаться в направлении + Z, вы возвращаетесь к тому, с чего начали. Теперь узлы, соответствующие соседним позициям, соединены только через то направление, которое соответствует этому направлению. Вы перебираете узлы, связанные с уже исследованными узлами, как обычно. Я бы порекомендовал ограничиться N, NE, E, SE, S, SW, W, NW в этой схеме.
Это решение может рассказать вам обо всех доступных областях пространства, а также о том, как лучше всего туда добраться, сколько у вас вращения, когда вы туда доберетесь, и обо всех направлениях, которые вы могли бы иметь, когда вы туда доберетесь.
Затем, когда вы на самом деле выполняете путь, вы можете интерполировать / кубический сплайн, чтобы он выглядел более аутентично.
источник
Звучит так, как будто вам, возможно, придется сначала решить, как именно вы хотели бы включить работу на ходу. Варианты как:
Если они движутся внутри конуса, сначала вращайте, затем начинайте двигаться. Это простое решение для реализации и путь для. Это также менее интересно, поэтому я бы не хотел его использовать.
Непрерывный поворот при движении, до 45 градусов. Этот намного хитрее, и, надеюсь, тот, который вам нужен. Численная интеграция по пути с использованием фиксированного временного шага, вероятно, является самым простым способом приблизиться к этому. Ваш конус будет ограничен максимальным (+ X градусов на каждый шаг) и минимальным (-X градусов на каждый шаг) поворотом.
Как лучше всего пройти через пространство со вторым из этих требований, во многом зависит от среды, в которой они будут перемещаться. Если есть много препятствий, которые вам нужно преодолеть, то все может стать действительно сложным и действительно дорогим. Однако, если его нет, вы можете загрузить (и даже уменьшить) вращение, чтобы в конечном итоге оказаться в нужном месте.
У меня есть ощущение, что я, возможно, только частично затронул темы, по которым у вас возник вопрос, поэтому не стесняйтесь добавлять больше комментариев, и я могу расширить обсуждение.
источник