În plus față de abilitatea de a urma o cale, un personaj (sau un grup de aceștia) trebuie, de asemenea, să poată urma un anumit caracter (cum ar fi un lider al echipei). Acest lucru se poate realiza folosind următorul lider comportament, pe care îl voi explica în acest tutorial.
Notă: Deși acest tutorial este scris folosind AS3 și Flash, ar trebui să puteți utiliza aceleași tehnici și concepte în aproape orice mediu de dezvoltare a jocului. Trebuie să aveți o înțelegere de bază a vectorilor de matematică.
Următorul comportament de conducător este o compoziție a altor forțe de conducere, toate aranjate pentru a face un grup de personaje să urmeze un caracter specific (liderul). O abordare naivă ar folosi căutarea sau urmărirea pentru a crea un model următor, dar rezultatul nu este suficient de bun.
În comportamentul căutării, un personaj este împins către o țintă, ocupând în cele din urmă aceeași locație ca acea țintă. Comportamentul de urmărire, pe de altă parte, împinge un personaj spre un alt personaj, dar urmărește să-l prindă (pe baza predicțiilor), în loc să îl urmeze.
În conducătorul care urmează comportamentul, obiectivul este să rămână destul de aproape de lider, dar ușor în spatele ei. Personajul ar trebui să se deplaseze mai rapid spre lider atunci când este îndepărtat, dar ar trebui să încetinească când distanța este mică. Acest lucru se poate realiza prin combinarea a trei comportamente de direcție:
Următoarele secțiuni explică modul în care fiecare dintre aceste comportamente sunt combinate pentru a crea lider după model.
Un personaj ar trebui să încerce să rămână ușor în spatele liderului în timpul următorului proces, ca o armată care se află în spatele comandantului său. Punctul următor (numit in spate
) poate fi ușor calculată pe baza vitezei țintă, deoarece reprezintă și direcția de caractere. Verificați pseudo-codul:
tv = leader.velocity * -1; tv = normaliza (tv) * LEADER_BEHIND_DIST; în spatele = leader.position + tv;
Dacă vectorul de viteză este înmulțit cu -1
, rezultatul este invers din vectorul de viteză. Acest vector care rezultă (numit televizor
) poate fi apoi normalizat, scalat corespunzător și adăugat poziției curente a personajului.
Iată o reprezentare vizuală a procesului:
Operații vectoriale implicate în găsirea locului potrivit de urmat.Cu cât e mai mare LEADER_BEHIND_DIST
cu cât distanța dintre lider și punctul din spate este mai mare. Deoarece personajele vor urma acel punct, cu cât este mai îndepărtat de la conducător, cu atât mai îndepărtate personajele vor rămâne de la conducător.
Următorul pas este ca un personaj să urmeze liderului in spate
punct. La fel ca toate celelalte comportamente, următorul proces va fi condus de o forță generată de followLeader ()
metodă:
funcția privată followLeader (leader: Boid): Vector3D var tv: Vector3D = leader.velocity.clone (); var force: Vector3D = Vector3D () nou; // Calculați punctul din spatele tv.scaleBy (-1); tv.normalize (); tv.scaleBy (LEADER_BEHIND_DIST); în spatele = leader.position.clone (). add (tv); // Creează o forță pentru a ajunge la forța din spatele forței = force.add (ajunge (în spate)); forță de întoarcere;
Metoda calculează in spate
punct și creează o forță pentru a ajunge la acel moment. followLeader
Forța poate fi apoi adăugată forței de direcție a personajului, la fel ca toate celelalte comportamente:
direcție = nimic (); // vectorul nul, adică "magnitudinea forței zero" direcție = direcție + followLeader (); direcție = trunchi (direcție, max_force) direcție = direcție / viteză masă = trunchiat (viteză + direcție, max_speed) poziție = poziție + viteză
Rezultatul acestei implementări este un grup de personaje capabile să ajungă la lider in spate
punct:
Când personajele sunt foarte apropiate unul de celălalt în timp ce îl urmăresc pe lider, rezultatul poate părea nenatural. Deoarece toate personajele vor fi influențate de forțe similare, ele tind să se miște în mod similar, formând o "pată". Acest tipar poate fi stabilit prin separare, una dintre regulile care ghidează comportamentul flocking.
Forța de separare împiedică aglomerarea unui grup de caractere, astfel încât acestea să păstreze o anumită distanță una față de cealaltă. Forța de separare poate fi calculată astfel:
separarea funcției private (): Vector3D var force: Vector3D = Vector3D () nou; var vecCount: int = 0; pentru (var i: int = 0; i < Game.instance.boids.length; i++) var b :Boid = Game.instance.boids[i]; if (b != this && distance(b, this) <= SEPARATION_RADIUS) force.x += b.position.x - this.position.x; force.y += b.position.y - this.position.y; neighborCount++; if (neighborCount != 0) force.x /= neighborCount; force.y /= neighborCount; force.scaleBy( -1); force.normalize(); force.scaleBy(MAX_SEPARATION); return force;
Forța de separare poate fi apoi adăugată la followLeader
forță, făcându-l capabil să împingă personajele unul de celălalt in acelasi timp că încearcă să ajungă la conducător:
funcția privată followLeader (leader: Boid): Vector3D var tv: Vector3D = leader.velocity.clone (); var force: Vector3D = Vector3D () nou; // Calculați punctul din spatele tv.scaleBy (-1); tv.normalize (); tv.scaleBy (LEADER_BEHIND_DIST); în spatele = leader.position.clone (). add (tv); // Creează o forță pentru a ajunge la forța din spatele forței = force.add (ajunge (în spate)); // Adăugați forța forței de separare = force.add (separarea ()); forță de întoarcere;
Rezultatul este un model mult mai natural următor:
Caracterele care urmează liderul folosind separarea. Deplasați cursorul mouse-ului pentru a ghida liderul. Faceți clic pentru a afișa forțele.Dacă liderul schimba brusc direcția actuală, există șansa ca personajele să ajungă în calea liderului. Din moment ce personajele urmează liderul, nu are niciun sens să le permită să rămână în fața conducătorului.
Dacă un caracter devine în calea conducătorului, ar trebui să se îndepărteze imediat pentru a șterge traseul. Acest lucru se poate realiza utilizând comportamentul de evadare:
Evitarea rutei lideruluiPentru a verifica dacă un personaj este în vizorul liderului, folosim un concept similar cu modul în care detectăm obstacolele în comportamentul de evitare a coliziunii: pe baza vitezei și direcției actuale a liderului, proiectăm un punct în fața acestuia (numit înainte
); dacă distanța dintre lider este înainte
punct și caracterul este mai mic decât 30
, de exemplu, atunci caracterul este în vizorul liderului și ar trebui să se miște.
înainte
punct este calculat exact ca in spate
punct, cu diferența că vectorul de viteză nu este inversat:
tv = leader.velocity; tv = normaliza (tv) * LEADER_BEHIND_DIST; înainte = lider.position + tv;
followLeader ()
metoda trebuie actualizată pentru a verifica dacă caracterul se află pe vizorul liderului. Dacă se întâmplă acest lucru, variabila forta
(reprezentând următoarea forță) se adaugă prin returnarea lui se sustrage (lider)
, care returnează o forță pentru a evita locația liderului:
funcția privată followLeader (leader: Boid): Vector3D var tv: Vector3D = leader.velocity.clone (); var force: Vector3D = Vector3D () nou; // Calculați punctul de pornire tv.normalize (); tv.scaleBy (LEADER_BEHIND_DIST); înainte = leader.position.clone () adăugați (tv); // Calculați punctul din spatele tv.scaleBy (-1); în spatele = leader.position.clone (). add (tv); // Dacă caracterul se află pe vizorul liderului, adăugați o forță // pentru a evita imediat traseul. dacă (isOnLeaderSight (lider, înainte)) force = force.add (evade (leader)); // Crează o forță pentru a ajunge la forța din spatele forței = force.add (ajunge (în spatele, 50)); // 50 este raza de sosire // Adăugați forța forței de separare = force.add (separarea ()); forță de întoarcere; funcția privată isOnLeaderSight (leader: Boid, leaderAhead: Vector3D): Boolean retur distanță (leaderAhead, this) <= LEADER_SIGHT_RADIUS || distance(leader.position, this) <= LEADER_SIGHT_RADIUS; private function distance(a :Object, b :Object) :Number return Math.sqrt((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y));
Orice personaj va scăpa imediat de poziția sa actuală dacă este în vizorul liderului:
Caracterele care urmează liderul folosind separarea și evitarea viziunii liderului. Deplasați cursorul mouse-ului pentru a ghida liderul. Faceți clic pentru a afișa forțele.Mai jos este un demo care arată comportamentul liderului următor. Soldierul albastru (liderul) va ajunge la cursorul mouse-ului, în timp ce soldații verzi vor urma liderul.
Când jucătorul face clic pe oriunde pe ecran, toți soldații se vor confrunta cu cursorul mouse-ului și vor trage. Monstrii vor ajunge în locații aleatorii, la fiecare câteva secunde.
Mutați cursorul mouse-ului pentru a ghida liderul (soldații vor urma). Faceți clic pentru a trage monștrii.Comportamentul următor al liderului permite unui grup de caractere să urmeze o anumită țintă, rămânând în spatele ei. Caracterele se sustrag, de asemenea, localizării lor curente, dacă în cele din urmă ajung în calea liderului.
Este important să rețineți că liderul următor comportament este a combinaţie a altor comportamente, cum ar fi sosirea, evitarea și separarea. Aceasta demonstrează că comportamentele simple pot fi combinate pentru a crea modele de mișcare extrem de complexe.
Vă mulțumim pentru lectură! Sper că puteți începe să combinați comportamentele explicate anterior pentru a vă crea propriul comportament complex!