Creați un joc de hochei AI Folosind comportamentele de conducere Apărare

Acest tutorial este ultima parte a procesului de codificare a unui joc de hochei folosind comportamente de direcție și mașini de stat finite. Aici vom îmbunătăți inteligența artificială a sportivilor noștri pentru a le permite să-și apere obiectivul împotriva adversarilor lor. De asemenea, sportivii noștri vor efectua tactici de atac în timp ce se apără, astfel încât să poată recupera pucul și să înceteze ofensiva adversarului.

Câteva cuvinte despre apărare

Într-un joc competitiv precum hocheiul, procesul de apărare este mult mai mult decât să se grăbească spre zona de poartă a echipei, pentru a împiedica adversarul să marcheze. Prevenirea adversarului de scorul este doar una din multele sarcini implicate.

Dacă o echipă se concentrează doar pe tactici de prevenire a scorurilor, toți sportivii vor deveni doar obstacole pe parcurs. Adversarul va continua să împingă, încercând să găsească un loc în formarea de apărare. Va dura ceva timp, dar în cele din urmă adversarul va înscrie.

Procesul de apărare este un amestec de acțiuni defensive și ofensive. Cea mai bună modalitate de a pune capăt atacului adversarului, care este obiectivul de apărare, este să atac în timp ce apăra. S-ar putea suna cam confuz, dar are sens.

Un atlet care apără echipa trebuie să se îndrepte spre obiectivul său, împiedicând adversarul să marcheze. Pe parcurs, el trebuie să încerce să fure pucul de la adversar care îl poartă sau să intercepteze pucul atunci când este schimbat între adversari. Exact acest tutorial va încerca să pună în aplicare: o tactică defensivă cu acțiuni de atac.

Combinarea atacurilor și a apărării

Pentru a realiza un comportament defensiv care are câteva aspecte de atac în el, vom adăuga două noi stări la mașina AI finit-state:

O mașină de stat finită bazată pe stack, reprezentând procesele de atac și de apărare ...

apăra statul va fi piatra fundamentala in procesul de aparare. În timp ce se află în acea stare, sportivii se vor deplasa spre partea lor, încercând întotdeauna să recupereze pucul pentru a termina ofensiva adversarului. 

patrulare statul va completa procesul de apărare. Acesta va împiedica sportivii să stea în picioare când își ating poziția de apărare în patinoar. Această stare va ține sportivii în mișcare și patrulare în zonă, ceea ce va produce un rezultat mai convingător.

Înțelegerea stării de apărare

apăra stat se bazează pe o idee foarte simplă. Când este activ, fiecare sportiv se va muta în poziția inițială din patinoar. Am folosit deja această poziție, descrisă de mInitialPosition proprietate în Atlet clasa, să pună în aplicare prepareForMatch stat în primul tutorial din această serie.

În timp ce se deplasează spre poziția sa inițială, un atlet va încerca să efectueze unele acțiuni de atac împotriva adversarului dacă este destul de aproape și poartă pucul. De exemplu, în cazul în care atletul se mișcă și liderul adversarului (cel cu puc) devine vecin, apăra statul va fi înlocuit cu ceva mai adecvat, cum ar fi stealPuck stat.

Deoarece sportivii tind să se răspândească prin întregul patinoar în timp ce atacă, când trec apăra și încep să se întoarcă la poziția lor inițială, vor acoperi o zonă semnificativă, asigurând un model de apărare convingător:

Atleții care efectuează acțiuni de atac în timp ce se întorc la pozițiile lor inițiale de apărare.

Unii sportivi nu vor întâlni adversari de-a lungul drumului, așa că se vor deplasa doar spre poziția lor inițială. Alți sportivi, cu toate acestea, s-ar putea apropia de niște adversari interesanți, cum ar fi liderul (cel care poartă pucul).

Implementarea statului de apărare

apăra statul va avea patru tranziții:

Statul de apărare și tranzițiile sale în FSM care descriu procesul de apărare ...

Trei dintre ele, echipa are pucul, aproape de liderul adversarului, și pucul nu are proprietar, sunt legate de acțiunile de atac. Ei vor fi responsabili pentru a face ca sportivii să pară că atacă adversarii în timp ce se mută pentru a apăra obiectivul echipei. pe poziție tranziția va fi declanșată atunci când atletul ajunge în sfârșit la poziția sa inițială în patinoar.

Primul pas în implementarea apăra statul este de a face sportivul să se îndrepte spre poziția sa inițială. Din moment ce el trebuie să încetinească în timp ce se apropie de destinație, comportamentul de direcție sosire este perfect potrivit:

clasa Atlet // (...) funcția privată defend (): void var aPuckOwner: Athlete = getPuckOwner (); // Deplasați-vă spre poziția inițială, ajungând acolo ușor. mBoid.steering = mBoid.steering + mBoid.arrive (mInitialPoziție); // Are pucul un proprietar? dacă (aPuckOwner! = null) / Da, da. Cine o are? dacă (doesMyTeamHasThePuck ()) // Echipa mea are pucul, timpul pentru a opri apărarea și a începe ataca! mBrain.popState (); mBrain.pushState (atac);  altfel dacă (Utils.distance (aPuckOwner, acest lucru) < 150)  // An opponent has the puck and he is close to us! // Let's try to steal the puck from him. mBrain.popState(); mBrain.pushState(stealPuck);   else  // No, the puck has no owner, it is running in the rink. // There is no point to keep defending the goal, because nobody has the puck. // Let's switch to 'pursuePuck' and try to get the puck to our team. mBrain.popState(); mBrain.pushState(pursuePuck);   // (… ) 

Comportamentul de sosire va crea o forță care va împinge atletul spre poziția sa inițială (mInitialPosition) in timp ce apăra statul este activ. După calculul forței de sosire, în acest cod, executăm o serie de teste care vor verifica proprietatea puțului și apropierea adversarilor, apăra stat de la creier și împingând unul nou în funcție de situație.

Dacă pucul nu are proprietar, probabil că se mișcă liber în patinoar. În acest caz, pursuePuck statul va fi împins în creier (linia 29). În cazul în care pucul are un proprietar de echipă, înseamnă că procesul de apărare sa terminat și este timpul să atacăm (linia 16). În cele din urmă, dacă proprietarul pucului aparține echipei de adversari și este destul de aproape, stealPuck va fi împins în creier (linia 22).

Rezultatul este o echipă care își poate apăra scopul, urmărind și încercând să fure pucul de la adversar care îl poartă. Mai jos este o demonstrație a implementării actuale de apărare:

Patrolând zona

Comportamentul actual de apărare este acceptabil, dar poate fi modificat puțin pentru a fi mai convingător. Dacă analizați demo-ul anterior, este posibil să observați în cele din urmă că sportivii se vor opri și vor sta în continuare după ce ajung în poziția inițială în timp ce apără. 

Dacă un sportiv se întoarce în poziția sa inițială fără a întâlni adversari de-a lungul drumului, el va rămâne în continuare până când un adversar cu pucul trece sau echipa va recupera pucul. 

Putem îmbunătăți acest comportament prin adăugarea unui a patrulare stat, care este împins în creier de către apăra atunci când atletul atinge poziția sa inițială:

Starea de patrulare și tranzițiile sale în FSM, care descriu procesul de apărare.

patrulare stat este extrem de simplu. Când este activ, va face sportivii să se deplaseze la întâmplare pentru o perioadă scurtă de timp, ceea ce mimează vizibil comportamentul așteptat de la un atlet care încearcă să apere un loc în patinoar.

Când distanța dintre atlet și poziția sa inițială este mai mare decât 10, de exemplu, patrulare se scoate din creier și împinge apăra. Dacă atletul ajunge din nou în poziția inițială în timp ce apără, patrulare este împins încă o dată în creier și procesul se repetă:

Demonstrarea stării de patrulare.

Modelul de mișcare aleatorie cerut de patrulare starea poate fi realizată cu ușurință cu comportamentul de direcție rătăcit. Punerea în aplicare a directivei patrulare stat este:

clasa Atlet // (...) privat funcția patrol (): void mBoid.steering = mBoid.steering + mBoid.wander (); // Sunt prea departe de poziția mea inițială? dacă (Utils.distance (mInitialPosition, this)> 10) // Da, sunt. Este timpul să opriți patrularea și să vă întoarceți la // poziția mea inițială. mBrain.popState (); mBrain.pushState (apăra);  // (...)

Verificarea distanței (linia 8) asigură că atletul va patrula o zonă mică în jurul poziției sale inițiale, în loc să lase complet poziția de apărare inițială nesupravegheată.

Rezultatele utilizării patrulare stat este un comportament mai convingător:

Punându-le pe toți împreună

În timpul punerii în aplicare a directivei stealPuck stat în tutorialul anterior, a existat o situație în care sportivii ar trebui să treacă la apăra stat. Totuși, acel stat nu a fost implementat atunci.

În timp ce încerca să fure pucul ( stealPuck stat), dacă adversarul este prea departe de atlet, este inutil să continuăm să încercăm să furăm pucul. Cea mai bună opțiune în această situație este de a afișa stealPuck stat și împinge apăra, sperând că un coechipier va fi mai aproape de liderul adversarului pentru a fura pucul.

stealPuck starea trebuie schimbată (linii 28 și 29) pentru a permite sportivilor să împingă apăra stat în această situație:

clasa Atlet // (...) funcția privată stealPuck (): void // Pucul are proprietar? if (getPuckOwner ()! = null) / Da, da, dar cine o are? dacă (doesMyTeamHasThePuck ()) // Echipa mea are pucul, deci e timpul să nu mai încerci să furi // pucul și să începi să ataci. mBrain.popState (); mBrain.pushState (atac);  altfel // Un adversar are pucul. var aOpponentLeader: atlet = getPuckOwner (); // Este adversarul cu pucul aproape de mine? dacă (Utils.distance (aOpponentLeader, acest lucru) < 150)  // Yeah, he is close! Let's pursue him while mantaining a certain // separation from the others to avoid that everybody will ocuppy the same // position in the pursuit. mBoid.steering = mBoid.steering + mBoid.pursuit(aOpponentLeader.boid); mBoid.steering = mBoid.steering + mBoid.separation(50);  else  // No, he is too far away. Let's switch to 'defend' and hope // someone closer to the puck can steal it for us. mBrain.popState(); mBrain.pushState(defend);    else  // The puck has no owner, it is probably running freely in the rink. // There is no point to keep trying to steal it, so let's finish the 'stealPuck' state // and switch to 'pursuePuck'. mBrain.popState(); mBrain.pushState(pursuePuck);   // (… ) 

După actualizarea stealPuck stat, sportivii sunt acum capabili să organizeze tactici de atac și de apărare, ceea ce face ca două echipe controlate de AI să poată juca unul împotriva celuilalt.

Rezultatul este demonstrat mai jos:

Concluzie

În acest tutorial am implementat o tactică de apărare folosită de atleți pentru a-și apăra obiectivul de la adversari. Am îmbunătățit apoi apăra prin adăugarea unor acțiuni de atac, cum ar fi încercarea de a fura pucul adversarului, ceea ce a făcut ca tactica de apărare să se simtă mai naturală și mai convingătoare.

Am îmbunătățit, de asemenea, simțul comportamentului apărării prin adăugarea unei stări extrem de simple, dar puternice patrulare. Ideea este de a împiedica sportivii să stea în picioare în timp ce apăra obiectivul echipei.

Și cu asta, am creat un sistem complet de AI pentru jocul nostru de hochei! 

Referințe

  • Sprite: Stadionul de hochei pe GraphicRiver
  • Sprites: Jucătorii de hochei de Taylor J Glidden