Skocz do zawartości

Strzelanie jako element sztucznej inteligencji EDITED


Huri

Rekomendowane odpowiedzi

Poniżej mój pierwotny post. Pojawiło się inne pytanie.

 

Otóż poradziłem sobie z tym całym wystrzeliwaniem. Teraz nie wiem jak zrobić aby przeciwnik poruszał się w kierunku gracza o jedno pole (16x16 pikseli). I żeby ruszał się tylko ten przeciwnik, który widzi gracza (Ci przeciwnicy poza zasięgiem mają zostać nieruchomi) Którego klocka użyć? Cała reszta ma pozostać taka sama czyli przeciwnik rusza się tylko wtedy gdy gracz wykonał ruch (zmienna obj_gracz.ruszyl_sie=1). Nie wiem czy jasno to napisałem :S ... mam nadzieję, że tak. :)

 

 

Cześć :)

Tworzę właśnie grę komputerową. Ogólny zamysł jest banalny. Gracz kieruje bohaterem po labiryncie w poszukiwaniu klucza i drzwi. Jak znajdzie klucz może otworzyć drzwi. W labiryncie są przeciwnicy, którzy mają mu w tym przeszkodzić. Aktualnie prawie wszystko już zrobiłem poza tą sztuczną inteligencją. Mam na to pewien pomysł ale nie wiem jak mi pójdzie z wykonaniem.

Ale najpierw kilka faktów.

Gracz porusza się po siatce 16x16 pikseli, tak samo i przeciwnik. W tej chwili przeciwnik porusza się tylko wtedy gdy gracz wykonał ruch. Jednak kierunek, który wybiera potwór jest losowy. Chciałbym, żeby przeciwnik ruszał się tylko wtedy gdy gracz znajduje się w zasięgu jego wzroku (odległość w sumie dowolna). Myślę nad takim rozwiązaniem:

 

1. obiekt przeciwnika w każdym kroku lub co kilka kroków wystrzeliwuje niewidoczny obiekt w 4 kierunkach.

2. jeżeli wystrzelony obiekt trafia w obiekt gracza przeciwnik wykonuje jeden krok (przesunięcie się o 16 pikseli) w jego kierunku. Jeżeli nie trafi w gracza (ten niewidoczny obiekt) to przeciwnik się nie rusza.

 

Moje pytanie brzmi. Czy da się wystrzelić 4 obiekty jednocześnie w 4 kierunkach? Jeśli tak to jak?

Dopiero uczę się tworzenia gier w GM i nie wszystko jest dla mnie jasne. Domyślam się, że w EVENT STEPS obiektu przeciwnika muszę czterokrotnie stworzyć obiekt (np. radar) ustawić kierunek wystrzelić go i zmienić kierunek na następny. Czy to dobre rozwiązanie? Może są jakieś inne prostsze lub nie wiem... bardziej wydajne metody stworzenia tak prostej "sztucznej inteligencji" ? Będę wdzięczny za pomoc.

 

Tak sobie pomyślałem, że zamiast wystrzeliwać radar w każdym kroku mogę skorzystać z ALARMu. Acha, jeszcze jedna istotna rzecz. W tej chwili korzystam z metody DRAG&DROP z małymi elementami GML (w proporcjach jakies 99 do 1 ;) ). Nie pytajcie dlaczego wogóle zajmuje się drag&drop. Po prostu taki mam teraz ustalony plan i dlatego jeżeli znajdą się chętni żeby mi pomóc prosiłbym o jak największy udział Drag&Drop. :)

 

Pozdrawiam

Odnośnik do komentarza
Udostępnij na innych stronach

Ok. Jako, że dopiero się uczę pójdę na kompromis i zrezygnuję z tego że rusza się tylko ten przeciwnik, który wykrył gracza. Kombinowałem z ID instancji, która trafia w gracza i zapisuje pozycję do zmiennych ale jakoś mi to nie bardzo wychodzi albo nie do końca rozumiem instance_id :). Daruje też sobie poruszanie się w kierunku ostatnio wykrytej pozycji gracza (chociaż już jakaś myśl mi się pojawiła ).

 

Zastanawiam się też czy takie coś zda egzamin ale to przetestuje już sam. Zamiast wystrzeliwać obiekty w 4 kierunkach stworze prostokąt lub koło i przyczepie na środek każdego przeciwnika. Jeśli zajdzie kolizja między graczem a tym przyczepionym obiektem wtedy przeciwnik zacznie się ruszać. Dzięki temu powinienem zaoszczędzić nieco zasobów systemowych. :)

Odnośnik do komentarza
Udostępnij na innych stronach

Dzięki za ten link :) W sumie opis klocków jest też w Helpie.

 

Jeżeli chodzi o kombinowanie z wykonaniem ruchu w kierunku gracza przez przeciwnika. Myślę sobie tak:

 

1. Obiekt przeciwnika strzela radarem w 4 kierunkach.

2. Jeżeli któryś z wystrzelonych (dowolny) trafia w gracza do zmiennej dir_target zapisywany jest kierunek tego obiektu, który walnął w gracza. (Obawiam się, że jako, że są 4 obiekty radar następuje jakiś konflikt).

3. Kierunek ze zmiennej dir_target jest przekazywany do obiektu przeciwnika i jeśli przeciwnik może wykonać ruch (zależne od tego czy gracz się ruszył) to nadawana jest mu prędkość (speed) np. 1

 

Na mój prosty nie matematyczno-logiczny umysł powinno to zadziałać. Jednak się nie sprawdza.

 

Obiekty radaru są wystrzeliwane w 4 konkretnych kierunkach (0,90,180,270) więc odczytanie wartości kierunku w EVENT COLLISION z obiektem GRACZ powinno dać się zapisać do zmiennej.

 

Sam nie wiem

Wywala mi taki błąd

 

 

GML___________________________________________

################################################################################

############

FATAL ERROR in

action number 1

of Step Event0

for object obj_enemy:

 

Push :: Execution Error - Variable Get 3.dir_tg(100003, -1)

at gml_Object_obj_enemy_Step_0 (line 16) - direction = obj_target.dir_tg

################################################################################

############

Odnośnik do komentarza
Udostępnij na innych stronach

Przekombinowane to i nieoptymalne. Tak to się komibnowało w TGFie albo Multimedia Fusion.

Dużo prościej sprawdzić, czy gracz znajduje się na odpowiedniej linii, jeśli tak, to przeciwnik idzie. Możesz też zrobić, że ustawia się zmienna np. wykrycie na 1 tj. gracz został wykryty i wtedy idzie w jego kierunku, niezależnie czy znajduje się na odpowiedniej linii, czy nie. :)

 

Pobaw się Action Decoderem i podstawowymi funkcjami w programowaniu - warunki itp (jeśli jeszcze nie znałeś tego). ;)

Odnośnik do komentarza
Udostępnij na innych stronach

zabavy v klocky bywa 10x dluzsa niz v GML, ale to twa decyzja :)

 

1,I żeby ruszał się tylko ten przeciwnik, który widzi gracza (Ci przeciwnicy poza zasięgiem mają zostać nieruchomi) Którego klocka użyć?

do action daj z control klocek test expresion a w nim uzyj

GML
distance_to_object(o_hrac)<100

to zapewni, ze jak o_hrac zblizi sie do przeciwnika na mniej jak 100pix to prezciwnik go rozpoznaje i moze vykonac blok klockow

jest to ekvivalent do

GML
if (distance_to_object(o_hrac)<100) {/* blok do wykonania*/ };

2,Teraz nie wiem jak zrobić aby przeciwnik poruszał się w kierunku gracza o jedno pole (16x16 pikseli).

jesli moze ruch byc skokowy to z move klocek jump to position (16)

jesli powolny po pixlach to pobaw sie s zmiennymi a znow jump to position (1)

 

test na direction gracza jest prosty, tylko grac jak sie rusza musi zapisiwac sobie do zmiennej kierunek a nieprzyjaciel tylko podsluchuje gracza

nieprzyjaciel na svym action w control do klocku test expresion moze uzyc

GML
o_hrac.direction

o_hrac.moj_kieronek

direction jest default zmienna GM

jest na tobie jako wykorzystasz

 

jakoze napisanie tego kostowalo mie duzo wiecej czasu, nierobilem przykladu a muszis prubowac, prubowac... i prubowac :)

zyce milej lamiglowki

 

szanuje two decyzje na klocki, ale jesli chces cos wiecej od GM to klocki to strata czasu :) wlasne doswiadczenie

Odnośnik do komentarza
Udostępnij na innych stronach

Dzięki :) Doceniam starania :) i napewno będę próbował.

Pokombinuje. Może zaraz wrzucę gdzieś przykład w GM na którym testuję rozwiązania (sama gra powstaje w osobnym projekcie).

Zdecydowałem się najpierw na klocki żeby poznać podstawowe zasady działania GM. Na GML przejdę jak skończe grę. Znam podstawy programowania i z tego co widziałem w przykładach w internecie nie jest to jakoś specjalnie trudne w GML i raczej rozumiem wszystko. Teraz chce się nauczyć co, kiedy i gdzie jest wykonywane.

 

PS. Wczoraj np. wprowadziłem do gry widok pseudo-izometryczny i gra prezentuje się teraz lepiej. :)

 

EDIT

Banalnie proste :)

Dzięki Twoim poradom zrobiłem już poruszanie się tylko tego przeciwnika, który widzi gracza a reszta poza zasięgiem stoi nieruchomo :) Dodatkowo zrobiłem coś co miałem w dalekich planach (Ściany robią się przezroczyste gdy gracz jest za nimi ukryty). Pozostało jeszcze sprawdzenie z tym kierunkiem poruszania się przeciwnika :) . Bo test na kierunek gracza już stosuje od poczatku wlasciwie zeby wiedziec w którą stronę gracz strzela :)

Odnośnik do komentarza
Udostępnij na innych stronach

Dzięki ale jak już napisałem w poprzednim poście... podstawy ZNAM i nie mam raczej problemów z przystosowaniem się do nowego języka (problem tkwi raczej w moim słomianym zapale :P i poprostu przestaje mnie interesować programowanie) . Programowałem w zamierzchłych czasach na Atari w Basicu, na Amidze w AMOSie (czyli w sumie też taki BASIC), na PC w QBASIC, TURBOPascal, C++, Delphi, JAVA i jeśli można to nazwać programowaniem to w LOGO (ComLOGO). Języków było sporo ale znam tylko takie naprawdę podstawy raczej (zmienne, tablice, pętle, warunki itp). Nie mniej jednak jeśli będę potrzebował pomocy w GML (jak się już nauczę operacji na klockach) to nie omieszkam napisać... więc czuj się ostrzeżony :P :)

Miło, że spotkałem się tu z taką chęcią pomocy :) Od momentu kiedy tu zawitałem naprawiłem/zrobiłem lub dołożyłem nowe funkcje w mojej grze. Oczywiście dzięki Waszej pomocy :) . Jakaś wzmianka w CREDITSach by się przydała. Się zrobi :)

 

Teraz mam problem z tym, że przeciwnik zdaje się ignorować zmienną obj_player.ruszyl_sie i i tak rusza się za każdym razem kiedy wystrzelony z niego (obj_przeciwnik) obiekt obj_radar trafia w gracza. Ale to prawdopodobnie przez to, że za bardzo gmerałem w instrukcjach warunkowych i źle zmieniam wartość zmiennej obj_player.ruszyl_sie . W domu to naprawie. W pracy ciężko przysiąść i się skupić na tym . Jakoś to rozwiążę :)

Odnośnik do komentarza
Udostępnij na innych stronach

A jak GML to nie do mnie, ja mógłbym Ci wyjaśnić co podstawy programowania, uniwersalne zresztą, dla każdego języka, jak to wspomniałeś wyżej "zmienne, tablice, pętle, warunki itp" i może trochę więcej. GMLa nie używam od kilku lat, chociaż ostatnio chciałem sobie nawet zainstalować dla funu i pobawić się trochę.

 

Tak apropo znajomości języków. Ja także znam same języki historyczne już i kompletnie nie używalne, jedynym praktycznym jaki znam jest C++. Także BASIC, Pascal, Batch (powłoka Windowsa) i więcej, ale już nie istotnych, chociaż w tych trzech to byłem już bardzo dobry. ;P

Odnośnik do komentarza
Udostępnij na innych stronach

...

Teraz mam problem z tym, że przeciwnik zdaje się ignorować zmienną obj_player.ruszyl_sie i i tak rusza się za każdym razem kiedy wystrzelony z niego (obj_przeciwnik) obiekt obj_radar trafia w gracza. Ale to prawdopodobnie przez to, że za bardzo gmerałem w instrukcjach warunkowych i źle zmieniam wartość zmiennej obj_player.ruszyl_sie . W domu to naprawie. W pracy ciężko przysiąść i się skupić na tym . Jakoś to rozwiążę :)

a juz myslalem, ze zrezygnovales z wystrzeliwania objekt radar :)

so lepsze sposoby

dla inspiracji

GML
e=o_nieprzyjaciel; // objekty tylko dla pisannia krotszych nazw v point_direction( leniem jestem :) )

g=o_gracz;

_step=16;

_gracz_dir=point_direction(e.x,e.y,g.x,g.y);

_gracz_dir=degtorad(_grac_dir);

x+=(cos(_grazc_dir)div(1)*_step);

y-=(sin(_gracz_dir)div(1)*_step);

nieprzyjaciel porzusza sie tylko jak o_hrac jest na osi x lub y

 

mozna tez przez IF lub CASE :)

Odnośnik do komentarza
Udostępnij na innych stronach

Ok problem rozwiązałem. Polegał na tym, że nie wstawiłem jednego klocka End Block w odpowiednim miejscu. Jeżeli chodzi o te podpowiedzi, które mi wysłałeś to zapisałem je sobie i zostawie na przyszłość :). Napewno się przydadzą chociaż będę musiał przypomnieć sobie trygonometrie coś czuję :P. Niestety zawsze byłem kiepski w matematyce (tak tak wiem, że to podstawa jeśli chodzi o tworzenie gier).

 

Pojawił się kolejny mini-problem ale myślę, że na tą chwilę to oleje. Otóż przy sprawdzaniu odległości między graczem a przeciwnikiem zdarza się sytuacja, że jeśli dwóch przeciwników jest odpowiednio blisko gracza obaj się ruszają (bo znajdują się w odległości mniejszej niż wyznaczona 48px) obaj przeciwnicy się ruszają mimo że tylko jeden z nich "widzi" gracza. Ale mogę to wytłumaczyć tym, że przeciwnik, który zobaczył gracza mówi temu drugiemu przeciwnikowi, że gdzieś tam jest gracz i dlatego ten się rusza ;)

 

Heh. Zabawne i jednocześnie smutne (dla mnie). Wiedziałem, że GML jest 200% lepszy od klocków i coraz częściej widzę dlaczego. Po pierwsze w klockach przy nieco bardziej skomplikowanych funkcjach łatwo się zgubić. Powoli zaczynam mieć problemy z ogarnięciem tego wszystkiego i dodawanie nowych funkcji staje się problematyczne :(... W kodzie ten problem jest o wiele mniejszy. Nie mniej jednak dokończę to co zacząłem na klockach :) Piszę też bloga z produkcji ze wszystkimi swoimi spostrzeżeniami odnośnie stworzenia gier. Może kiedyś skompiluje z tego co napisałem artykuł dla ludzi, którzy będą chcieli wziąć się za GM :)

Odnośnik do komentarza
Udostępnij na innych stronach

nietrza uzyc sin/cos, ale jest prosciej.

uzyvam cyklycznego zjaviska krzywej do generowania 0/1 by zmiescilo sie v jednym wyrazeniu bez IF

idealne do klockow, ladne v GML

IF/CASE duzo bardziej komplikuje klocky.

nastepnie pomnazam _step by ruch byl dokladnie 16pix

 

jezeli ma na gracza rusyc tylko jeden przeciwniki wtedy kdy oba przeciwnici so dosyc blisko to jest prawidlovo.

jesli ma sie porusac zawsze tylko jeden przeciwnik to starczy pobawic sie z zmiennymi u gracza by bylo wiadomo ze ktos na niego ruszyl a nastepnky przeciwnik przed ruchem sprawdza gracza czy juz ktos na niego "poluje" :)

 

OT TO JEST problem.

jak zapamietac wstystkie klocky by ogarnoc kdzie moze byc element ktory prawdopodobnie powoduje blad.

tez jest katastrofalne, kdy zechces przeprogramowac kawalek systemu gry.

bez MEGA dokumentacji/schematu blokowego prawie niema szans.

 

a w GML jak czesto dotrzymuje programator dlugosc kodu +-1strona to zawse jen barzdo proste :)

na prosty przyklad vygloda klocek spoko

ale dla kogos kto juz przywyczajil sie do GML jest prosty przyklad(v klockach), tak jak by mial beignoc do 4. pietra, zamiast jechac windo :twisted:

Odnośnik do komentarza
Udostępnij na innych stronach

Zapamiętam tą regułę z IFami :) . W sumie wydaje się logiczne :)

Nie wiem być może źle robię ale ciągle trzymam się mojej metody.

 

Poradziłem sobie z poniższym. Wpisywałem złą nazwę zmiennej. Czasami jednak przeciwnik nie chodzi po siatce tylko przemieszcza się na ukos a nieraz wogóle się nie zatrzymuje tylko leci dopoki nie walnie w ściane.Robi tak pewnie dlatego, że użyłem klocka CHECK GRID. W momencie kiedy przeciwnik wyłapie gracza radarem "na ukos" wtedy idzie do niego "na ukos" i wtedy warunek z klocka CHECK GRID nie jest spełniony więc przeciwnik leci ciągle aż do przeszkody (ściany) i tam się blokuje. :( . Przeciwnik powienie poruszać się np. w ten sposób:

 

góra, prawo, góra, prawo. Skokowo a nie bezpośrednio skośnie. :S

 

Gdy obiekt radar trafi w gracza zapisuje dwie zmienne z jego pozycją w momencie uderzenia. Nastepnie w sekcji gdzie są klocki odpowiedzialne za ruch przeciwnika wrzucam klocek MOVE TOWARDS i jako parametry podaje te dwie zmienne z obiektu radar. Jednak Gdy dojdzie do kolizji między obiektem gracz i obiektem radar wywala mi taki błąd. Nie bardzo orientuje się jak odczytywać te błędy.

 

 

 

GMLGML___________________________________________

################################################################################

############

FATAL ERROR in

action number 1

of Step Event0

for object obj_enemy:

 

Push :: Execution Error - Variable Get 4.player_y(100004, -1)

at gml_Object_obj_enemy_Step_0 (line 20) - action_move_point( obj_target.player_x, obj_target.player_y, 1 );

################################################################################

############

Odnośnik do komentarza
Udostępnij na innych stronach

Za duże zagnieżdżenie IFów w końcu powoduje taki bałagan, że czasami ciężko rozgryźć o co chodziło. Czasami nawet komentarze nie pomagają. Myślę, że dlatego właśnie jeśli nie ma potrzeby lepiej unikać. Ja np. w moim projekcie jak się zaczął bardziej rozwijać łapałem się na tym, że w złym miejscu wsadzałem START i END BLOCK i przez to wynikały problemy. W kodzie jest podobnie z nawiasami :) No ale kim ja jestem żeby się wypowiadać :)

Odnośnik do komentarza
Udostępnij na innych stronach

Ereg wysłałem Ci PM :)

Teraz wszystko byłoby dobrze (tak myślę) gdyby przeciwnik poruszał się tylko góra-dół i lewo-prawo. Przeciwnik gubi się w takie sytuacji...

 

 

crngine_problem.png

 

 

Podejrzewam, że muszę coś poprawić w IF z CHECK GRID, ale jeszcze nie wiem co dokładnie. Obstawiam, że źle (zbyt często) zapisuje poprzednią pozycję gracza i przeciwnik zamiast iść na poprzednią pozycję gracza idzie na aktualną. Ale... jest już późno a ja mam wodę z mózgu :) . Zobaczymy jutro :) .

 

 

Mam powoli dosyć :). Czuję, że nie obejdzie się bez przejścia na GML żeby uniknąć bólu głowy.

Odnośnik do komentarza
Udostępnij na innych stronach

Jeśli chcesz dodać odpowiedź, zaloguj się lub zarejestruj nowe konto

Jedynie zarejestrowani użytkownicy mogą komentować zawartość tej strony.

Zarejestruj nowe konto

Załóż nowe konto. To bardzo proste!

Zarejestruj się

Zaloguj się

Posiadasz już konto? Zaloguj się poniżej.

Zaloguj się
  • Ostatnio przeglądający   0 użytkowników

    • Brak zarejestrowanych użytkowników przeglądających tę stronę.
×
×
  • Dodaj nową pozycję...