Как учитывать гравитацию при движении ИИ

9

Я делаю 2D игру. В настоящее время вертолет летит вокруг, управляемый игроком. Управление осуществляется с помощью клавиш со стрелками: ВВЕРХ, ВЛЕВО и ВПРАВО.

Это скорость по оси Y есть dy, а скорость по оси X есть dx.

Это физика выглядит следующим образом:

Всякий раз, когда ВВЕРХ не нажимается , dyускоряется с постоянным ускорением, неограниченно вниз. (Сила тяжести). dxостается в его текущем значении.

Когда нажата кнопка ВВЕРХ , dyускоряется с постоянным ускорением от того, что есть в данный момент, до 4 (вверх, пока не достигнет скорости 4). dxостается в его текущем значении.

Когда нажата кнопка ВЛЕВО , dxускоряется с постоянным ускорением, начиная с текущего значения, до -4 .

Когда RIGHT нажата , dx ускоряется с постоянным ускорением, от того, чем оно является в настоящее время, до 4 .

(Когда нажимаются ВЛЕВО или ВПРАВО, а ВВЕРХ не нажимается одновременно, как я уже сказал: dyвсе больше становится все меньше и меньше, потому что сила тяжести влияет на вертолет)

Все это заставляет вертолет часто следовать по аркам в воздухе, а не по прямым линиям.

Это создает физику, которая кажется довольно реалистичной.

Мой вопрос:

Вертолет противника, ИИ, должен двигаться, используя ту же физическую систему.

Допустим, ИИ хочет добраться от того места, где он сейчас находится, к точке Б.

введите описание изображения здесь

Если бы в игре не было гравитации и постепенного ускорения, это было бы легко. Я бы просто нарисовал вектор из позиции ИИ в точку В и заставил ИИ следовать за ним.

Но поскольку есть гравитация и постепенное ускорение, ИИ никогда не сможет двигаться по прямой (почти). Каков наилучший способ заставить ИИ перейти в точку B, насколько это возможно?

Как я могу принять во внимание гравитацию при перемещении ИИ к определенному месту назначения?

(Если это легче объяснить, пожалуйста, рассмотрите точку B на том же уровне по оси Y, что и AI, а не по диагонали к нему.)

Спасибо

user3150201
источник
Можете ли вы отключить физику на ИИ, пока он движется? Если это так, то вы можете отключить его, когда он движется к точке, и включить, когда он достигнет этого.
Жафур
@Zhafur Это заставит движение ИИ казаться нереальным или, по крайней мере, отличаться от того, как выглядит движение игрока. Я хочу, чтобы движение ИИ выглядело так же, как и движение игрока.
user3150201

Ответы:

4

ТЛ; др:

TimeToStop.x = CurrentSpeed.x / Accelaration.x;

if (TimeToStop.x * CurrentSpeed.x >= 1.99 * DistanceFromTarget.x)
    slow_down_x(); // CurrentSpeed += Acc.x * direction;
else
    speed_up_towards_target_x(); // CurrentSpeed += Acc.x * direction;

То же самое с y. Не забудьте ограничить скорость, чтобы она находилась между нулем и максимальной скоростью. Если в какой-то момент у противника очень низкая скорость и он пытается остановиться, он может начать двигаться в противоположном направлении. Не позволяйте ему. Остановите его, если он замедляется и его скорость ниже 1 * Приз.

Длинная версия: если препятствий нет, движение по оси Y совершенно не имеет отношения к движению по оси X (и не влияет на него). Таким образом, вопрос, который вы описываете, можно разбить на два отдельных вопроса.

  1. Перемещение туда по оси X
  2. И двигаясь там по оси Y.

CS.x& CS.yнаша текущая скорость по осям X и Y.

TS.x& TS.yЭто время, которое потребуется вам, чтобы остановиться только вертикально или горизонтально, учитывая текущую скорость на соответствующей оси.

D.x& D.y- расстояние по каждой оси.

tl; dr: вы продолжаете ускоряться (если возможно [если вы не достигли максимальной скорости]) по оси x, пока не достигнете точки, где выполняется следующее условие:

if (TS.x * CS.x >= 1.99 * D.x) hit_the_breaks_on_x();

То же самое с y.

AturSams
источник
2

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

Итак, возьмите знаковый угол между вектором скорости и целевым вектором и примените тягу относительно размера вектора.

Таким образом, если угол a между красным вектором скорости и зеленым целевым вектором отрицательный, тогда примените положительную тягу, в противном случае не применяйте тягу и позвольте гравитации разобраться с этим.введите описание изображения здесь

Обратите внимание, что вам придется обрабатывать четыре квадранта, где цель может отличаться (как если бы цель находилась в верхнем левом углу, положительный угол потребовал бы применения тяги).

Кроме того, обязательно применяйте величину тяги относительно отклонения от целевой скорости.

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

bornander
источник
1
Спасибо. Несколько вопросов по этому поводу: 1- «... применить тягу относительно размера вектора » . Вы имели в виду «размер угла » ? 2- Под «угловым знаком» вы подразумеваете положительное или отрицательное - правильно? Если так, то угол положителен, если он выше коричневой линии, и отрицателен, если он ниже коричневой линии. Правильно? 3- Если я правильно понимаю, что вы имеете в виду: каждый кадр, получить угол между текущим вектором скорости и текущим вектором для цели. Затем добавьте / вычтите из dx и dy соответственно. Это правильно?
user3150201
@ user3150201 Да на угол вопроса. Да, в вопросе со знаком / без знака atan2 может дать вам угол между двумя векторами со знаком. Похоже, вы поняли мою точку зрения, извинения, если мне было неясно.
рожден
1

Вы можете просто пересчитать движение каждые X кадров. Предполагая, что вы не помещаете слишком много кадров между ними, но достаточно, чтобы это не влияло на производительность, гравитация на вертолете не должна быть достаточно сильной, чтобы действительно увидеть изменение траектории. Кроме того, я думаю, что игрок мог бы двигаться таким же образом, приспосабливаясь к гравитации во время движения и не планируя этого.

Александр Дансеро
источник