Як врахувати гравітацію при переміщенні ШІ


9

Я роблю 2D гру. Наразі навколо нього літає вертоліт, який контролюється гравцем. Це керується за допомогою клавіш зі стрілками: Вгору, Вліво та Вправо.

Це швидкість по осі y dy, а швидкість по осі x - dx.

Це фізика така:

Щоразу, коли UP не натискається , dyприскорюється з постійним прискоренням, нескінченно, вниз. (Гравітація). dxзалишається в його поточному значенні.

Якщо натиснути кнопку UP , dyприскорюється з постійним прискоренням від того, що є зараз, до 4 (вгору, до досягнення швидкості 4). dxзалишається в його поточному значенні.

Якщо натиснути ліворуч , dxприскорюється з постійним прискоренням, від того, що зараз є, до -4 .

Якщо натиснути ВПРАВО , dx прискорюється з постійним прискоренням, від того, що зараз є, до 4 .

(Коли натискають ліворуч або праворуч, а вгору не натискають одночасно, як я вже сказав: dyвсе більше стає меншим та меншим, бо гравітація впливає на вертоліт)

Все це змушує вертоліт часто слідувати дугами у повітрі, а не прямими лініями.

Це створює фізику, яка здається цілком реальною.

Моє запитання:

Противник вертоліт, ШІ, повинен рухатися за тією ж системою фізики.

Скажімо, ШІ хоче потрапити з місця, де він зараз знаходиться, до пункту B.

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

Якби не було гравітації і поступового прискорення в грі, було б легко. Я просто намалював би вектор з позиції ШІ до точки В і змусив ІІ слідувати за ним.

Але оскільки є гравітація та поступове прискорення, ШІ ніколи не може рухатися по прямій (майже). що було б найкращим способом змусити ШІ якомога ефективніше перейти до точки В?

Як я можу взяти до уваги тяжкість при переміщенні ШІ до певного пункту призначення?

(Якщо це легше пояснити, будь ласка, вважайте, що точка B знаходиться на тому ж рівні на осі y, що і AI, а не по діагоналі до неї.)

Дякую


Чи можете ви відключити фізику на ШІ, поки вона рухається? Якщо так, то ви можете відключити його, коли він рухається до точки, і ввімкнути, коли він досяг її.
Джафур

@Zhafur Це зробить рух AI здатися нереальним, або, принаймні, різницею від того, як здається рух гравця. Я хочу, щоб рух ШІ виглядав так само, як рух гравця.
користувач3150201

Відповіді:


4

tl; dr:

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;

Те саме з у. Пам'ятайте про обмежену швидкість, щоб вона знаходилася між нулем і максимальною швидкістю. Якщо у противника в якийсь момент є дуже повільна швидкість і він намагається зупинитися, він може почати рухатись у зворотному напрямку. Не дозволяйте цього. Зупиніть його, якщо він уповільнює і швидкість його не перевищує 1 * Acc.

Довга версія: Якщо немає перешкод, рух по осі y абсолютно не має значення (і не впливає) на рух по осі x. Тож описуване вами питання можна розділити на два окремих питання.

  1. Переїзд туди на x-Axis
  2. І рухається там по Y-Axis.

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();

Те саме з у.


2

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

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

Тож якщо кут a між червоним вектором швидкості та зеленим цільовим вектором від'ємний, тоді застосуйте позитивну тягу, інакше не застосовуйте тягу і нехай тяжіння розібрається.введіть тут опис зображення

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

Також обов'язково застосуйте величину тяги щодо відхилення від цільової швидкості.

Технічно це не враховує тяжкості, це компенсує поточний стан, і це означає, що вертоліт AI може не літати по прямій до цілі, але трохи похитнеться. Це може чи не може працювати для вашої гри.


1
Дякую. Кілька питань з цього приводу: 1- "... застосувати тягу відносно розміру вектора " . Ви мали на увазі "розмір кута " ? 2- Під «підписаним кутом» ви маєте на увазі позитивний чи негативний - правильно? Якщо так, то кут позитивний, якщо він вище лінії коричневого, і негативний, якщо він нижче лінії коричневого. Правильно? 3- Якщо я правильно розумію, що ви маєте на увазі: кожен кадр, отримайте кут між поточним вектором швидкості та поточним вектором до цілі. Потім додайте / віднімайте від dx і dy відповідно. Це правильно?
користувач3150201

@ user3150201 Так, питання кута. Так, підписане / непідписане питання, atan2 може дати вам кут підписаного між двома векторами. Схоже, ви зрозуміли мою думку, вибачтесь, якщо я був незрозумілий.
борнадер

1

Ви можете просто перерахувати рух кожного X кадру. Якщо припустити, що ви не ставите занадто багато кадрів між собою, але достатньо, щоб це не впливало на продуктивність, сила тяжіння на вертольоті не повинна бути достатньо сильною, щоб дійсно побачити, як траєкторія змінюється. Плюс, я думаю, що гравець міг би рухатись так само, пристосовуючись до сили тяжіння під час руху та не плануючи.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.