Jak wziąć pod uwagę grawitację podczas przenoszenia AI


9

Robię grę 2D. W tej chwili latający helikopter jest sterowany przez gracza. Sterowanie odbywa się za pomocą klawiszy strzałek: GÓRA, LEWO i PRAWO.

Jest to prędkość wzdłuż osi y dy, a prędkość wzdłuż osi x wynosi dx.

Jego fizyka wygląda następująco:

Ilekroć przycisk UP nie jest wciśnięty , dyprzyspiesza ze stałym przyspieszeniem, bez końca w dół. (Powaga). dxpozostaje w aktualnej wartości.

Gdy UP wciśnięty , dyprzyspiesza ze stałym przyspieszeniem, co obecnie jest to, aż do 4 (w górę, aż do osiągnięcia prędkości 4). dxpozostaje w aktualnej wartości.

Po lewej stronie jest wciśnięty , dxprzyspiesza w stałym przyspieszeniem, z tego co obecnie jest to, do -4 .

Po naciśnięciu PRAWO , dx przyspiesza ze stałym przyspieszeniem, niezależnie od tego, jakie jest obecnie, do 4 .

(Kiedy LEWY lub PRAWY są naciskane, a GÓRA nie jest naciskana jednocześnie, jak powiedziałem: dycoraz bardziej maleje, ponieważ grawitacja wpływa na helikopter)

Wszystko to sprawia, że ​​śmigłowiec często podąża za łukami w powietrzu, a nie po liniach prostych.

To tworzy fizykę, która wydaje się całkiem realistyczna.

Moje pytanie brzmi:

Śmigłowiec przeciwnika, AI, powinien poruszać się przy użyciu tego samego systemu fizyki.

Powiedzmy, że AI chce dostać się z miejsca, w którym się aktualnie znajduje, do punktu B.

wprowadź opis zdjęcia tutaj

Gdyby w grze nie było grawitacji i stopniowego przyspieszania, byłoby to łatwe. Po prostu narysowałbym wektor z pozycji AI do punktu B i kazałbym AI podążać za nim.

Ale ponieważ istnieje grawitacja i stopniowe przyspieszenie, AI nigdy nie może poruszać się w linii prostej (prawie). jaki byłby najlepszy sposób, aby sztuczna inteligencja przeszła do punktu B tak oszczędnie, jak to możliwe?

Jak mogę wziąć pod uwagę grawitację, przenosząc AI do określonego miejsca docelowego?

(Jeśli łatwiej to wytłumaczyć, proszę rozważyć punkt B na tym samym poziomie na osi y co AI, a nie na przekątnej.)

Dzięki


Czy możesz wyłączyć fizykę na AI, gdy jest w ruchu? Jeśli tak, możesz go wyłączyć, gdy zbliża się do punktu, i włączyć, kiedy do niego dojdzie.
Zhafur

@Zhafur To sprawi, że ruch AI będzie wydawał się nierealistyczny lub przynajmniej będzie różnił się od tego, jak ruch gracza się wydaje. Chcę, aby ruch AI wyglądał tak samo jak ruch gracza.
user3150201

Odpowiedzi:


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;

To samo z y. Pamiętaj, aby związać prędkość, aby była w zakresie od zera do prędkości maksymalnej. Jeśli w pewnym momencie wróg ma bardzo małą prędkość i próbuje się zatrzymać, może zacząć poruszać się w przeciwnym kierunku. Nie pozwól mu. Zatrzymaj go, jeśli zwalnia, a jego prędkość jest mniejsza niż 1 * Acc.

Wersja długa: Jeśli nie ma przeszkód, ruch na osi y jest całkowicie nieistotny dla (i nie wpływa) na ruch na osi x. Tak więc pytanie, które opisujesz, można podzielić na dwa osobne pytania.

  1. Przeprowadzka tam na osi x
  2. I poruszając się tam na osi y.

CS.xi CS.ysą naszą aktualną prędkością na osiach xiy.

TS.x& TS.yCzy czas zajęłoby zatrzymać tylko pionowo lub poziomo, biorąc pod uwagę aktualną prędkość w odpowiedniej osi.

D.xi D.ysą odległością na każdej osi.

tl; dr: kontynuujesz przyspieszanie (jeśli to możliwe [chyba że osiągnąłeś maksymalną prędkość]) na osi x, aż osiągniesz miejsce, w którym spełniony jest następujący warunek:

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

To samo z y.


2

Jednym z podejść, które zastosowałem dla podobnego problemu, było najpierw narysowanie wektora do celu, a następnie porównanie go z bieżącym kierunkiem prędkości.

Więc weź podpisany kąt między wektorem prędkości a wektorem docelowym i zastosuj siłę ciągu względem wielkości wektora.

Jeśli więc kąt a między czerwonym wektorem prędkości a zielonym wektorem docelowym jest ujemny, zastosuj ciąg dodatni, w przeciwnym razie nie zastosuj ciągu i pozwól grawitacji go rozwiązać.wprowadź opis zdjęcia tutaj

Zauważ, że będziesz musiał traktować cztery ćwiartki, w których cel może być różnie (tak jakby cel znajdował się w lewym górnym rogu, dodatni kąt wymagałby zastosowania ciągu).

Upewnij się również, że zastosujesz siłę ciągu względem odchylenia od prędkości docelowej.

Technicznie nie bierze to pod uwagę grawitacji, lecz kompensuje bieżący stan i oznacza, że ​​śmigłowiec AI może nie lecieć w linii prostej do celu, ale będzie trochę chybotać. To może, ale nie musi działać w twojej grze.


1
Dzięki. Kilka pytań na ten temat: 1- „... zastosuj ciąg w stosunku do wielkości wektora . Miałeś na myśli „size of the angle ? 2- Przez „kąt oznaczony” masz na myśli dodatnią czy ujemną - prawda? Jeśli tak, to kąt jest dodatni, jeśli znajduje się powyżej brązowej linii, a ujemny, jeśli znajduje się poniżej brązowej linii. Dobrze? 3- Jeśli dobrze rozumiem, masz na myśli: Każda klatka, uzyskaj kąt między bieżącym wektorem prędkości a bieżącym wektorem do celu. Następnie dodaj / odejmij od dx i odpowiednio dy. Czy to jest poprawne?
user3150201

@ user3150201 Tak na pytanie o kąt. Tak w pytaniu o podpisanie / niepodpisanie, atan2 może podać kąt podpisania między dwoma wektorami. Wygląda na to, że zrozumiałeś mój punkt, przepraszam, gdybym był niejasny.
urodzony

1

Możesz po prostu ponownie obliczyć ruch każdej klatki X. Zakładając, że nie umieszczasz zbyt wielu klatek pomiędzy, ale wystarczająco, aby nie wpłynęło to na wydajność, grawitacja na helikopterze nie powinna być wystarczająco silna, aby naprawdę zobaczyć zmieniającą się trajektorię. Ponadto myślę, że gracz mógłby poruszać się w ten sam sposób, dostosowując się do grawitacji podczas ruchu i nie planując tego.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.