Jak wdrożyć inteligentnego wroga w shoot-em-up?

13

Wyobraź sobie bardzo prostą strzelankę, coś, co wszyscy wiemy:

shoot-em-up 1

Jesteś graczem (zielony). Twój ruch jest ograniczony do Xosi. Nasz wróg (lub wrogowie) znajduje się u góry ekranu, jego ruch jest również ograniczony do Xosi. Gracz strzela we wroga pociskami (żółtymi).

Chciałbym wdrożyć sztuczną inteligencję dla wroga, która powinna być naprawdę dobra w unikaniu pocisków graczy. Moim pierwszym pomysłem było podzielenie ekranu na odrębne sekcje i przypisanie im wag:

ważona strzelanka

Istnieją dwa ciężary: „kula” (szary) jest niebezpieczeństwem nałożonym przez kulę. Im kula jest bliżej wroga, tym większa jest „waga pocisku” ( 0..1gdzie 1 oznacza najwyższe niebezpieczeństwo). Ścieżki bez pocisku mają wagę 0. Drugi ciężar to „odległość-waga” (limonkowo-zielony). Do każdego pasa dodaję 0.2koszt ruchu (ta wartość jest teraz trochę arbitralna i może zostać zmieniona).

Następnie po prostu dodaję obciążniki (białe) i idę na tor o najniższej wadze (czerwony). Ale to podejście ma oczywistą wadę, ponieważ może łatwo ominąć lokalne minima, ponieważ optymalnym miejscem do przejścia byłyby po prostu między dwiema nadlatującymi kulami (oznaczonymi białą strzałką).

Oto czego szukam:

shoot-em-up totalne zniszczenie

  • Powinien znaleźć drogę przez burzę, nawet gdy nie ma miejsca, które nie stanowiłoby zagrożenia ze strony kuli.
  • Wróg może niezawodnie unikać pocisków, wybierając optymalne (lub prawie optymalne) rozwiązanie.
  • Algorytm powinien uwzględniać prędkość ruchu pocisku (ponieważ mogą one poruszać się z różnymi prędkościami).
  • Sposoby poprawiania algorytmu, aby można było zastosować różne poziomy trudności (głupie dla superinteligentnych wrogów).
  • Algorytm powinien pozwalać na różne cele, ponieważ wróg nie tylko chce unikać pocisków, powinien także móc strzelać do gracza. Oznacza to, że pozycje, w których wróg może strzelać do gracza, powinny być preferowane podczas unikania pocisków.

Jak więc sobie z tym poradzisz? W przeciwieństwie do innych gier tego gatunku, chciałbym mieć tylko kilku, ale bardzo „wykwalifikowanych” wrogów zamiast mas głupich wrogów.

grzmot
źródło
2
Czy zastanawiałeś się nad użyciem czegoś takiego jak zachowania kierownicze? Jest jedna dla uniknięcia przeszkód w szczególności: red3d.com/cwr/steer/Obstacle.html
Tetrad
@Tetrad Myślałem o zachowaniach kierowniczych .. również dlatego, że można je ładnie przełączać, na przykład „spróbuj zastrzelić gracza”, a gdy nadchodzi niebezpieczeństwo, przełącz się na „unik”. Obawiam się, że wersja 1D (z czym właściwie mam do czynienia) w wersji uników będzie zbyt głupia, aby podejmować dobre decyzje. Mogę się jednak mylić.
bummzack 11.11.11

Odpowiedzi:

8

Myślę, że twoim podstawowym pomysłem jest dźwięk, ale nie jest on analogowy. Potrzebujesz analogicznego pola wartości, które biegnie przez ekran. Tak więc gradient dyfuzji 1D, z którego można uzyskać wartość dokładnie w punkcie na tej linii, w locie. Gradienty dyfuzji są tanie i mogą być używane przez wielu wrogów jednocześnie, ponieważ opisują one środowisko, a nie widok jednostki na to (trochę jak oświetlenie radia) - prawdopodobnie dlatego zdecydowałeś się na podejście, które masz w swoim pytaniu . Ten gradient powinien być względnie gładki, aby wywoływać organiczny ruch wroga i oczywiście aktualizuje się w miarę postępów gry. Być może średnia krocząca ?

Gradient powinien łączyć:

  • Bliskość
  • Prędkość
  • Szerokość pocisku
  • (opcjonalnie) Pozycja celów (graczy)

Aby uniknąć, musimy być w stanie dokładnie znaleźć rozwiązanie, ilekroć takie istnieje . Tak jest w każdym przypadku, gdy istnieje luka wystarczająco mała, aby wróg mógł ją uniknąć. Oznacza to, że możesz robić tylko to, co możesz, więc podejście gradientowe nie będzie działać gorzej niż jakiekolwiek inne podejście w tym sensie, powiedziałbym.

Gradient dyfuzji powinien popchnąć wroga w stronę lokalnych optymów (będących szczytami na wykresie) z mniej imperatywnym ruchem, im bliżej lokalnego minimum, stąd zmniejszający się efekt powrotu przy unikaniu. To otwiera drzwi do bardziej inteligentnego podejmowania decyzji, kiedy wróg ma dobre otwarcie do strzału.

Jeśli potrzeba strzelania jest większa niż potrzeba ruchu, zrób to; Twój kod może to również określić na podstawie ich różnic. Możesz to zaimplementować jako część podstawowego wykresu, w którym to przypadku pozycja gracza zmniejsza otaczające wartości na wykresie (zakładając, że wrogowie grawitują do najniższego punktu), co łączy wszystkie podejmowanie decyzji w jeden wykres, lub możesz zachować „ wykres „pragnienie wystrzelenia” oddzielnie od głównego wykresu „chęć uniknięcia”, który zapewni większą bezpośrednią kontrolę.

IRL, nie zawracałbym sobie głowy unikaniem pocisku, dopóki nie znajdzie się w odległości, o której wiem, że przy mojej najwyższej prędkości unikania zaczyna być trudny do uniknięcia. Doświadczenie z pierwszej ręki rzucania kamieniami jako chłopak. Kula w odległości x przemieszczającej się z prędkością y ma taką samą ocenę zagrożenia jak kula w odległości 2x, podróżującej z prędkością 2 lat. Dlatego należy to odpowiednio uwzględnić.

Sposoby dostrojenia algorytmu do trudności wroga obejmują

  • wprowadzenie opóźnienia w aktualizacjach wykresu (Born Too Slow)
  • wprowadzenie losowych, zlokalizowanych niedokładności na wykresie
  • po prostu nieposiadanie wrogów zgodnie z tym, co mówi im wykres, w sekwencji aktualizacji (powiedzmy od 1 do 10 klatek) z powodu zwykłego lenistwa AI.

Ponownie możesz zaimplementować wszystkie czynniki w jednym wykresie (mniej kontroli i mniej przydatny dla wielu wrogów) lub w kilku wykresach, na które patrzysz razem, aby uzyskać wyniki (bardziej modułowy, prawdopodobnie działa lepiej dla wielu wrogów). Trudno jest być bardziej szczegółowym, ponieważ istnieje wiele kierunków, w których można zastosować to podejście.

Inżynier
źródło
1
Drogi Nicku. Poszłam zaimplementować małą testową wersję tego zachowania we flashu i jestem bardzo zadowolony z wyniku (pociski są odradzane losowo). Obecnie używam 3 gradientów, jednego dla zagrożenia, kosztu ruchu i statycznego dla krawędzi (tak, że krawędzie ekranu są mniej pożądane). Są wizualizowane w aplikacji flash. Wydaje mi się, że z pewnymi poprawkami mogę osiągnąć bardzo dobre wyniki, a także uwzględnić inne ciężary, takie jak pozycje strzelania. Wielkie dzięki kolego.
bummzack 12.11. O
1
Hej @bummzack, to kumpel z przyjemności, to fajne małe demo! Twoje spojrzenie na problem było dla mnie nowe i wyglądało interesująco - cieszę się, że to działa! Cieszę się, że mogę w tym pomóc, i dziękuję za udostępnienie.
Inżynier
7

Można to traktować jako problem z pattingiem. Zamiast myśleć, w jaki sposób baddy unika pocisków, obrazowanie pocisków jest statyczne, a baddy musi jechać przez nie do dolnej części ekranu.

    E    
B  B**B
  B***B  B
 B***B   B
B**B** B 
 B**B**BB
B*****B B
      P

E = wróg
B = kula
P = gracz
* = opcje ścieżki na dole ekranu

Po tym, jak złoczyńca nakreśli udaną ścieżkę, musi za każdym razem zrobić kolejny krok. Prawdopodobnie istnieje już kilka dobrych algorytmów do wyszukiwania ścieżek, takich jak ten. Jeśli baddy porusza się z taką samą prędkością jak pociski, może to być jeden przykładowy algorytm;

Zacznij od złego ducha i zaznacz bezpieczne pozycje w pustych miejscach po lewej stronie poniżej, bezpośrednio poniżej i poniżej prawej. Następnie rozważ każdą utworzoną przez siebie bezpieczną przestrzeń i powtórz. Jeśli w dowolnym momencie okaże się, że poniżej nie ma bezpiecznych miejsc, zaznacz to miejsce jako niebezpieczne i cofnij się.

Qwerky
źródło
1
Ciekawe podejście Obawiam się, że jest to trochę kosztowne, ponieważ środowisko zmienia się tak szybko i trudno jest zastosować popularne algorytmy wyszukiwania ścieżek, ponieważ najlepiej działają one z dyskretnymi „mapami”.
bummzack 11.11.11
To nie powinno być zbyt drogie, nie zapominaj, że musisz tylko obliczyć dolny rząd za każdym zakrętem, nie musisz ponownie obliczać całej rzeczy.
Qwerky, 11.11.11
@bummzack Environment nie jest „szybki”, przynajmniej pod względem komputera. Dla twórców gier powinieneś zrozumieć, że prawie każda gra jest oparta na krokach, chodzi tylko o wielkość tego kroku. Ale na każdym etapie można wykonać obliczenia, więc potrzebujesz rozwiązania Qwerky.
Deele
Właściwie zgadzam się z @bummzack. Chociaż podejście to jest logicznie solidne, będzie droższe niż podejście 1D zaproponowane w pytaniu. Może to być przedwczesna optymalizacja, ale uważam, że to podejście jest znacznie bardziej eleganckie. Zobacz moją odpowiedź na rozwinięcie tego.
Inżynier
2
To prawdopodobnie właściwa odpowiedź, ale nie do końca realistyczna . W czasie, w którym wróg zajmuje wypracowanie ścieżki, na polu może znajdować się inny zestaw pocisków całkowicie unieważniający ścieżkę, co oznacza, że ​​ponowne obliczenie ścieżki byłoby koniecznością. A przeliczanie to dziwka . Co więcej, twój pomysł propagacji wstecznej do punktu, w którym był bezpieczny, czyni go jeszcze droższym! @Nick Wiggill Nie sądzę, że to przedwczesna optymalizacja, po prostu dobry przewidywanie, aby upewnić się, że nie kopniesz się w kroczu.
Ray Dey,