Creaţi un Hockey joc AI folosind direcție comportamente: mecanica de joc
Romanian (Română) translation by Ermal Yota (you can also view the original English article)
În trecut posturi din această serie, ne-am concentrat pe conceptele din spatele inteligenta artificiala, am fost de învăţare despre. În această parte, noi vom wrap toate punerea în aplicare într-un joc de hochei în totalitate redate. Veţi învăţa cum să adăugaţi piese lipsă necesare pentru a transforma aceasta într-un joc, cum ar fi scorul, ups de putere, şi un pic de joc de proiectare.
Rezultat final
Mai jos este jocul care va fi implementat folosind toate elementele descrise în acest ghid.
Gândire joc de Design
Părţile anterioare din aceasta serie axat pe explicând modul în care funcţionează AI jocului. Fiecare parte detaliat un anumit aspect al jocului, cum ar fi cum trece de sportivi şi cum sunt implementate atac şi apărare. Ei s-au bazat pe concepte cum ar fi comportamente şi maşini de stare finită bazate pe stiva de direcţie.
Pentru a face un joc jucabile pe deplin, cu toate acestea, toate aceste aspecte trebuie să fie înfăşurat într-un mecanic de joc de bază. Alegerea cea mai evidentă ar fi să pună în aplicare toate regulile oficiale de un meci de hochei oficial, dar că ar avea nevoie de o mulţime de muncă şi timp. Să aruncăm o abordare mai simplă de fantezie în schimb.
Toate regulile de hochei va fi înlocuit cu unul singur: dacă vă transportă puck şi sunt atinse de un adversar, congela şi sfărâma în bucăţi 1 milion! Acesta va face jocul mai simplu de a juca şi de distracţie pentru ambii jucatori: unul transportă puck şi unul încearcă să-l recupereze.
În scopul de a îmbunătăţi acest mecanic, vom adăuga câteva power-up-uri. Acestea vor ajuta jucătorul să înscrie şi de a face jocul un pic mai dinamic.
Adăugând posibilitatea să Scor
Să începem cu sistemul de punctaj, responsabil pentru a determina cine câştigă sau pierde. O echipa scoruri de fiecare dată când intră pucul în poarta adversarului.
Cel mai simplu mod de a pune în aplicare acest lucru este utilizând două dreptunghiuri suprapuse:

Dreptunghiul verde reprezintă suprafaţa ocupată de obiectivul structura (cadru si net). Functioneaza ca un bloc solid, Deci puck şi sportivii nu va fi capabil să se deplaseze prin el; Ei vor sări înapoi.
Dreptunghi roşu reprezintă zona de"scor". În cazul în care pucul se suprapune acest dreptunghi, înseamnă o echipă a marcat doar.
Dreptunghi roşu este mai mică decât cea verde, şi plasat în faţa sa, Deci dacă puck atinge scopul pe orice parte dar fata, aceasta va sări înapoi şi scorul nu vor fi adăugate:

Organizarea totul după cineva partituri
După ce o echipă marchează, toţi sportivii trebuie să revină la poziţia lor iniţială şi puck trebuie să fie plasat în centrul de patinoarul din nou. După acest proces, poate continua meciul.
Mutarea sportivi la poziţia lor iniţială
După cum sa explicat în prima parte a acestei serii, toţi sportivii au o stare de AI numit prepareForMatc
h că va muta-le spre poziţia iniţială, şi le provoca să vin fără probleme la o staţie de acolo.
Atunci când pucul se suprapune cu una din zonele de"scor", orice activ curent AI stat toate atlet este eliminată şi prepareForMatch
este împins în creier. Ori de câte ori sunt sportivi, vor reveni la poziţia lor iniţială după câteva secunde:
Se deplasează aparatul de fotografiat spre centrul de patinoar
Deoarece aparatul de fotografiat urmează întotdeauna puck, în cazul în care este direct teleportat la centrul de patinoar după cineva partituri, vizualizarea curentă va schimba brusc, care ar fi urât şi confuz.
O modalitate mai bună de a face acest lucru este de a muta puck Lin spre centrul de patinoar; deoarece aparatul de fotografiat urmează puck, acesta va aluneca gratios vizualizarea la scopul la centrul de patinoar.
Acest lucru poate fi realizat prin schimbarea vectorului de viteză puck după ce hit-uri orice zona de gol. Vectorul viteza noi trebuie să "push" puck spre centrul de patinoar, astfel încât aceasta poate fi calculată ca:
var c :Vector3D = getRinkCenter(); var p :Vector3D = puck.position; var v :Vector3D = c - p; v = normalize(v) * 100; puck.velocity = v;
Prin scăderea poziţia centrul de patinoarul din pucul poziţia curentă, este posibil să se calculeze un vector care arată direct spre centrul de patinoar.
După normalizarea acest vector, pot fi scalate de orice valoare, cum ar fi 100
, care controlează cât de repede puck se îndreaptă spre centrul de patinoar.
Mai jos este o imagine cu o reprezentare a vectorului viteză noi:

Acest vector V
este folosit ca puck pe vectorul viteză, astfel încât puck va muta spre centrul de patinoar, aşa cum sa intenţionat.
Pentru a preveni orice comportament ciudat în timp ce puck se îndreaptă spre centrul de patinoar, cum ar fi o interacţiune cu un atlet, puck este dezactivat în timpul procesului. În consecinţă, se opreşte interactiunea cu sportivi şi este marcat ca invizibile. Jucatorul va vedea puck în mişcare, dar aparatul de fotografiat va încă-l urmeze.
Pentru a decide dacă pucul este deja în poziţie, distanţa dintre acesta şi centrul de patinoar este calculată în timpul mişcării. În cazul în care este mai mic de 10
, de exemplu, puck este destul de aproape pentru a fi plasat în centrul de patinoar direct şi reactivat astfel încât meciul poate continua.
Adăugarea de putere-up-uri
Ideea din spatele ups de putere este de a ajuta jucătorul atinge obiectivul principal al jocului, care este de a Scor prin efectuarea pucul în poarta adversarului.
Dragul de aplicare, jocul nostru va avea doar două de putere-up-uri: fantoma ajuta şi frica Puck. Fosta adaugă trei sportivi suplimentare jucătorului echipei de ceva timp, în timp ce acesta din urmă face adversarii fugă puck pentru cateva secunde.
Putere-up-uri sunt adăugate la ambele echipe, atunci când cineva partituri.
Punerea în aplicare a "Fantomă ajutor" putere-up
Deoarece toţi sportivii adăugat de fantoma ajuta pornirea sunt temporare, atlet clasa trebuie
modificate pentru a permite un atlet a marcat ca o "Fantoma". Dacă un atlet este o fantoma, se va elimina în sine la jocul după câteva secunde.
Mai jos este clasa de atlet
, subliniind doar completările făcute pentru a se potrivi funcţionalităţi fantoma:
public class Athlete { // (...) private var mGhost :Boolean; // tells if the athlete is a ghost (a powerup that adds new athletes to help steal the puck). private var mGhostCounter :Number; // counts the time a ghost will remain active public function Athlete(thePosX :Number, thePosY :Number, theTotalMass :Number) { // (...) mGhost = false; mGhostCounter = 0; // (...) } public function setGhost(theStatus :Boolean, theDuration :Number) :void { mGhost = theStatus; mGhostCounter = theDuration; } public function amIAGhost() :Boolean { return mGhost; } public function update() :void { // (...) // Update powerup counters and stuff updatePowerups(); // (...) } public function updatePowerups() :void { // TODO. } }
Proprietatea mGhost
este un boolean care spune daca sportivul este o fantoma sau nu, în timp ce mGhostCounter
conţine cantitatea de secunde sportivul trebuie să aştepte înainte de a se scoate din joc.
Aceste două proprietăţi sunt utilizate prin metoda updatePowerups():
private function updatePowerups():void { // If the athlete is a ghost, it has a counter that controls // when it must be removed. if (amIAGhost()) { mGhostCounter -= time_elapsed; if (mGhostCounter <= 2) { // Make athlete flicker when it is about to be removed. flicker(0.5); } if (mGhostCounter <= 0) { // Time to leave this world! (again) kill(); } } }
Metoda de updatePowerups()
, numit în rutina de update()
a sportivului, se va ocupa de toate de prelucrare de putere-up în atlet. Chiar acum tot it does este verifica dacă atletul curent este o fantomă sau nu. Dacă este, atunci proprietatea mGhostCounter
este salturi de timpul scurs de la Ultima actualizare.
Atunci când valoarea de mGhostCounter
ajunge la zero, înseamnă că sportivul temporară a fost activ pentru destul de mult, astfel că trebuie să eliminaţi în sine din joc. Pentru a face jucător conştienţi de că, atlet va începe pâlpâitoare ultimul două secunde înainte să dispară.
În cele din urmă, este timpul pentru a implementa procesul de Adăugare sportivi temporar, atunci când este activat de putere-up. Care se realizează în metoda powerupGhostHelp(),
disponibil în principal joc de logica:
private function powerupGhostHelp() :void { var aAthlete :Athlete; for (var i:int = 0; i < 3; i++) { // Add the new athlete to the list of athletes aAthlete = addAthlete(RINK_WIDTH / 2, RINK_HEIGHT - 100); // Mark the athlete as a ghost which will be removed after 10 seconds. aAthlete.setGhost(true, 10); } }
Această metodă iterează peste o buclă, care corespunde la cantitatea de sportivi temporar adăugate. Fiecare atlet nou este adăugat la partea de jos a patinoarului şi marcate ca o fantomă.
Descrise anterior, ghost sportivi se va elimina din joc.
"Frica Puck" Power-Up de punere în aplicare
Power-up de frica Puck face toţi adversarii fugă puck pentru cateva secunde.
La fel ca putere fantoma ajuta-up, atlet
clasa trebuie modificate pentru a acomoda această funcţionalitate:
public class Athlete { // (...) private var mFearCounter :Number; // counts the time the athlete should evade from puck (when fear powerup is active). public function Athlete(thePosX :Number, thePosY :Number, theTotalMass :Number) { // (...) mFearCounter = 0; // (...) } public function fearPuck(theDuration: Number = 2) :void { mFearCounter = theDuration; } // Returns true if the mFearCounter has a value and the athlete // is not idle or preparing for a match. private function shouldIEvadeFromPuck() :Boolean { return mFearCounter > 0 && mBrain.getCurrentState() != idle && mBrain.getCurrentState() != prepareForMatch; } private function updatePowerups():void { if(mFearCounter > 0) { mFearCounter -= elapsed_time; } // (...) } public function update() :void { // (...) // Update powerup counters and stuff updatePowerups(); // If the athlete is an AI-controlled opponent if (amIAnAiControlledOpponent()) { // Check if "fear of the puck" power-up is active. // If that's true, evade from puck. if(shouldIEvadeFromPuck()) { evadeFromPuck(); } } // (...) } public function evadeFromPuck() :void { // TODO } }
Prima metoda updatePowerups()
este schimbat pentru decrement proprietatea mFearCounter
, care conţine cantitatea de timp atlet ar trebui să evite puck. Proprietatea mFearCounter
este schimbat de fiecare dată când se numeşte metoda fearPuck().
În metoda update() atlet
, un test este adăugat
pentru a verifica dacă putere-up ar trebui să aibă loc. Dacă atletul este un adversar, controlate de AI (amIAnAiControlledOpponent
() returnează adevărat) şi atlet ar trebui să se sustrage puck (shouldIEvadeFromPuck
() returnează adevărat, de asemenea
), metoda evadeFromPuck
() este invocată.
EvadeFromPuck()
metoda foloseste comportamentul se sustrage, ceea ce face o entitate evita orice obiect şi traiectoria sa cu totul:
private function evadeFromPuck() :void { mBoid.steering = mBoid.steering + mBoid.evade(getPuck().getBoid()); }
Toate metoda de evadeFromPuck()
nu este de a adăuga o forţă se sustrage atlet curent pe direcţie vigoare. Acest fapt îl sustrage puck fără ignorând forțele de direcție deja adăugată, cum ar fi cel creat de statul AI în prezent activă.
Pentru a fi evadable, puck trebuie să se comporte ca o boid, ca toţi sportivii (mai multe informaţii despre faptul că în prima parte a seriei). În consecinţă, o proprietate de boid, care conţine pucul poziţia şi viteza, trebuie să fie adăugate la clasa de Puck
:
class Puck { // (...) private var mBoid :Boid; // (...) public function update() { // (...) mBoid.update(); } public function getBoid() :Boid { return mBoid; } // (...) }
În cele din urmă, vom actualiza principalele joc de logica pentru a face adversarii se tem puck atunci când este activat de putere-up:
private function powerupFearPuck() :void { var i :uint, athletes :Array = rightTeam.members, size :uint = athletes.length; for (i = 0; i < size; i++) { if (athletes[i] != null) { // Make athlete fear the puck for 3 seconds. athletes[i].fearPuck(3); } } }
Metoda iterează peste toţi sportivii adversarul (dreapta echipa, în acest caz), apela metoda fearkPuck()
de fiecare dintre ele. Acest lucru va declanşa logica care face sportivi tem puck în câteva secunde, a explicat anterior.
Congelare şi zguduitoare
Ultima Adăugare la joc este partea de congelare şi zguduitoare. Acesta se realizează în principal joc de logica, în cazul în care o rutina verifică dacă sportivi de echipa stânga sunt suprapuse cu sportivi de echipa de dreapta.
Această verificare se suprapun se face automat de motor de joc Flixel, care invocă un apel invers, de fiecare dată când se constată o suprapunere:
private function athletesOverlapped(theLeftAthlete :Athlete, theRightAthlete :Athlete) :void { // Does the puck have an owner? if (mPuck.owner != null) { // Yes, it does. if (mPuck.owner == theLeftAthlete) { //Puck's owner is the left athlete theLeftAthlete.shatter(); mPuck.setOwner(theRightAthlete); } else if (mPuck.owner == theRightAthlete) { //Puck's owner is the right athlete theRightAthlete.shatter(); mPuck.setOwner(theLeftAthlete); } } }
Acest apel primeşte ca parametri sportivi fiecărei echipe, care se suprapuneau. Un test verifică dacă puck pe care proprietarul nu este nulă, ceea ce înseamnă că este în curs de derulare cineva.
În acest caz, puck pe proprietar este în comparaţie cu sportivi care doar se suprapuneau. În cazul în care una dintre ele este transportă puck (asa ca el este proprietar de puck), el este spulberat şi proprietate pucul trece la celălalt atlet.
Metoda shatter
() din clasa atlet
va marca atlet ca inactivi şi puneţi-l în partea de jos a patinoarului după câteva secunde. Se va emite, de asemenea, mai multe particule reprezentând bucăţi de gheaţă, dar acest subiect va fi acoperit in alt post.
Concluzia
In acest tutorial, am implementat câteva elemente necesare pentru a transforma un joc jucabile pe deplin nostru prototip de hochei. Intenţionat am pus accentul pe conceptele din spatele fiecăruia dintre aceste elemente, în loc de modul de a le implementa efectiv în motor de joc, X sau Y.
Abordarea congela şi distruge folosit pentru jocul ar putea suna prea fantastic, dar acesta vă ajută să păstraţi proiectul uşor de gestionat. Regulile de sport sunt foarte specifice, şi implementarea acestora poate fi dificil.
Prin adăugarea de câteva ecrane şi unele elemente de HUD, puteţi crea propriul joc de hochei complet din acest demo!
Referințe
- Patinoar: Stadionul de hochei pe GraphicRiver
- Sprite: Jucătorii de hochei de Taylor J Glidden
- Icoane: Joc-icoane de Lorc
- Cursorul mouse-ului: cursorul de Iwan Gabovitch
- Chei de instruire: tastatura Pack de Nicolae Berbece
- Cruce: Crosshairs Pack de Bryan
- SFX/muzica: sparge de Michel Baradari, lovit puck şi majorete de gr8sfx, muzica de DanoSongs.com
Envato Tuts+ tutorials are translated into other languages by our community members—you can be involved too!
Translate this post