Înțelegerea comportamentelor de direcție Deplasați-vă

Metodele de conducere urmăresc să ajute personajele autonome să se miște într-o manieră realistă, folosind forțe simple care se combină pentru a produce navigație improvizată similară vieții. În acest tutorial, voi acoperi umbla comportament, care face ca personajul să se miște în mod aleatoriu.

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ă.


Rătăcind în jur

Adesea, personajele unui joc trebuie să se miște în mod aleatoriu în jurul mediului. De obicei, acele personaje așteaptă doar să se întâmple ceva (ca o bătălie împotriva jucătorului) sau căutând ceva. Atunci când jucătorul este capabil să vadă acel comportament, capacitatea de rătăcire a personajului trebuie să fie suficient de vizuală și suficient de realistă.

Dacă jucătorul este capabil să identifice linii de traseu puternic definite sau comportament de mișcare nerealist, acesta va genera frustrare. În cel mai rău caz, jucătorul își va da seama cum să anticipeze mișcările personajului, ceea ce are ca rezultat o experiență de joc plictisitoare.

umbla conducerea comportamentală urmărește să producă o mișcare realistă "casuală", care va face jucătorul să creadă că personajul este cu adevărat viu și că se plimba.


Căutați și aleatoriu

Există mai multe moduri de a implementa modelul rătăcirii folosind comportamentele de direcție. Cea mai simplă este folosirea comportamentului de căutări descris anterior. Atunci când un personaj efectuează căutarea, acesta se va deplasa spre o țintă.

Dacă poziția țintei se schimbă la fiecare câteva secunde, atunci caracterul nu va fi niciodată capabil să atingă țintă (și chiar dacă o va face, ținta se va mișca din nou). Plasarea țintei în mod aleatoriu în zona de joc va face ca personajul să se deplaseze în jurul întregului mediu alungând ținta. Demo-ul de mai jos arată această abordare în acțiune:


Comportamentul căutării și o țintă aleatorie. Faceți clic pe demo pentru a afișa vectori de forță.

Codul pentru această implementare ar fi:

 // Calculați funcția privată a forței de rătăcire (): Vector3D var now: Number = (new Date ()) getTime (); dacă (acum> = nextDecision) // Alegeți o poziție aleatorie pentru "target" // returnează o forță de direcție care împinge caracterul // spre țintă (comportamentul de căutare) returnează (țintă);  // în buclele jocului, mânerul forțelor și mișcările doar // cum ar fi înainte: public function update (): void steering = rătăcit () direcție = truncă (direcție, max_force) direcție = direcție / viteză masă = direcție, max_speed) poziție = poziție + viteză

Chiar dacă aceasta este o abordare simplă și bună, rezultatul final nu este atât de convingător. Uneori caracterul își inversează complet traseul, deoarece ținta se află în spatele ei. Caracterul comportamentului pare mult mai mult "La naiba, mi-am uitat cheile!" decât "Bine, voi urma această direcție acum".


Umbla

O altă implementare a comportamentului de rătăcire a fost propusă de Craig W. Reynolds când a inventat aceste comportamente. Ideea de bază este să producem deplasări aleatorii mici și să aplicăm vectorului direcției actual al personajului (viteza, în cazul nostru) fiecărui cadru de joc. Deoarece vectorul de viteză definește unde se îndreaptă caracterul și cât de mult se mișcă fiecare cadru, orice interferență cu acel vector va schimba ruta curentă.

Folosind deplasări mici, fiecare cadru împiedică personajul să-și schimbe brusc traseul. Dacă personajul se mișcă în sus și se întoarce spre dreapta, de exemplu, în următorul cadru de joc se va deplasa în continuare și se va întoarce la dreapta, dar la un unghi ușor diferit.

Această abordare poate fi pusă în aplicare și în moduri diferite. Unul dintre ele este de a folosi un cerc în fața personajului, folosind pentru a calcula toate forțele implicate:

forța de deplasare  are originea la centrul cercului și este constrânsă de raza cercului. Cu cât este mai mare raza și distanța de la caracter la cerc, cu atât mai puternic va fi "împinge" caracterul care va primi fiecare cadru de joc.

Această forță de deplasare va fi utilizată pentru a interfera cu traseul personajului. Este folosit pentru a calcula rătăcesc forța.


Calculul poziției cercului

Prima componentă necesară pentru calcularea forței de deplasare este poziția centrală a cercului. Deoarece cercul trebuie plasat în fața caracterului, vectorul de viteză poate fi folosit ca ghid:

 // Conform CIRCLE_DISTANCE de mai jos este // un număr definit în altă parte. // Codul pentru calcularea centrului cercului: var circleCenter: Vector3D; cercCentrul = viteza.clone (); circleCenter.normalize (); circleCenter.scaleBy (CIRCLE_DISTANCE);

circleCenter vectorul de mai sus este o clonă (copie) a vectorului de viteză, ceea ce înseamnă că ele indică aceeași direcție. Este normalizată și înmulțită cu o valoare scalară (CIRCLE_DISTANCE, în acest caz), care va avea ca rezultat vectorul următor:


Forța de deplasare

Următoarea componentă este forța de deplasare, care este responsabilă de virajul din dreapta sau din stânga. Deoarece aceasta este o forță folosită pentru a produce perturbări, ea poate indica oriunde. Să folosim un vector aliniat cu axa Y:

 var displacement: Vector3D; deplasare = Vector3D (0, -1) nou; displacement.scaleBy (CIRCLE_RADIUS); // // Schimbați în mod aleatoriu direcția vectorului // modificând setul de unghi curent (deplasare, deplasare); // // Schimba wanderAngle doar un pic, asa ca // nu va avea aceeasi valoare in // urmatorul frame de joc. wanderAngle + = (Math.random () * ANGLE_CHANGE) - (ANGLE_CHANGE * .5);

Forța de deplasare este creată și scalată de raza cercului. După cum am descris mai devreme, cu cât raza este mai mare, cu atât forța de rătăcire este mai puternică. wanderAngle este o valoare scalară care definește cât trebuie "înclinată" forța de deplasare; după ce se folosește o valoare aleatorie este adăugată pentru a face diferența pentru următorul cadru de joc. Ea produce caracterul arbitrar necesar în mișcare.

Din motive de înțelegere, să presupunem că forța de deplasare calculată mai sus este plasată în centrul cercului. Deoarece a fost scalată de valoarea radială a cercului, ar fi ceva de genul:

Bacsis: Amintiți-vă că vectorii de matematică nu au o poziție în spațiu, ei au o direcție și o magnitudine (lungime). În consecință, ele pot fi plasate oriunde.

Umblați Forța

După ce se calculează centrul cercului și vectorul de deplasare, acestea trebuie combinate pentru a produce rătăcesc forța. Această forță se calculează prin adăugarea celor doi vectori:

 var wanderForce: Vector3D; wanderForce = circleCenter.add (deplasare);

Putem să reprezentăm vizual aceste forțe cum ar fi:

Forța de rătăcire poate fi imaginată ca un vector care merge de la caracter la un punct de pe circumferința cercului. În funcție de poziția acelui punct, forța de rătăcire va împinge caracterul spre stânga sau spre dreapta, puternic sau slab:

Cu cât forța de rătăcire este mai apropiată de vectorul de viteză, cu atât caracterul va schimba ruta actuală. Forța de rătăcire va funcționa exact ca forțele de căutare și de fugă: va împinge caracterul spre o direcție.

Similar căutării și fugării în cazul în care direcția forței este calculată pe baza unei ținte, direcția de deplasare este calculată pe baza unui punct aleatoriu pe circumferința cercului. Codul final pentru forța de rătăcire este:

 funcția privată rătăcește (): Vector3D // Calculați centrul cercului var circleCenter: Vector3D; cercCentrul = viteza.clone (); circleCenter.normalize (); circleCenter.scaleBy (CIRCLE_DISTANCE); // Calculați forța de deplasare var displacement: Vector3D; deplasare = Vector3D (0, -1) nou; displacement.scaleBy (CIRCLE_RADIUS); // // Schimbați în mod aleatoriu direcția vectorului // modificând setul de unghi curent (deplasare, deplasare); // // Schimba wanderAngle doar un pic, asa ca // nu va avea aceeasi valoare in // urmatorul frame de joc. wanderAngle + = Math.random () * ANGLE_CHANGE - ANGLE_CHANGE * .5; // // Calculați și returnați în final forța de rătăcire var wanderForce: Vector3D; wanderForce = circleCenter.add (deplasare); întoarcere wanderForce;  funcția publică setAngle (vector: Vector3D, valoare: Număr): void var len: Number = vector.length; vector.x = Math.cos (valoare) * len; vector.y = Math.sin (valoare) * len; 

Adăugarea forțelor

După ce forța de rătăcire a fost calculată, trebuie să fie adăugată la viteza personajului, astfel încât să poată afecta mișcarea. Adăugarea acelei forțe se face în același mod ca înainte:

 direcție = rătăcire () direcție = trunchiat (direcție, max_force) direcție = direcție / viteză masă = trunchiat (viteză + direcție, max_speed) poziție = poziție + viteză

Forța de rătăcire va afecta traseul personajului în același mod ca și comportamentele descrise anterior, cu diferența că împinge caracterul într-o direcție aleatorie în fiecare cadru de joc:


Comportamentul de rătăcire. Faceți clic pe demo pentru a afișa vectori de forță.

Demo-ul de mai sus arată mai multe personaje rătăcind în mediul înconjurător. Dacă părăsesc ecranul, sunt respawn în centru.


Concluzie

Comportamentul de rătăcire este un mod excelent de a implementa mișcări aleatorii. Este controlată de un cerc imaginar plasat în fața personajului, care poate fi modificat pentru a produce modelul dorit de mișcare.

Acest tutorial descrie comportamentele de direcție, explicând comportamentul de rătăcire. În următorul post, vom afla despre mai multe comportamente. Fiți la curent cu noi pe Twitter, Facebook sau Google+.