Förstå styrningsbeteenden utövande och undvikande

Hittills har vi tittat på att söka, fly, anlända och vandra styrningsbeteenden. I denna handledning täcker jag jakt och den undgå beteenden som gör att dina karaktärer följer eller undviker målet.

Notera: Även om denna handledning skrivs med AS3 och Flash, borde du kunna använda samma tekniker och begrepp i nästan vilken spelutvecklingsmiljö som helst. Du måste ha en grundläggande förståelse för matematiska vektorer.


Vad är en utmaning??

En strävan är processen att följa ett mål som syftar till fånga den. Det är viktigt att notera att ordet "fångst" gör skillnaden här. Om något bara följer ett mål är allt man behöver göra att upprepa målets rörelser och som en konsekvens kommer det att vara på spåret.

När man förföljer något måste förföljaren följa målet, men det måste också förutse var målet kommer att vara inom en snar framtid. Om du kan förutsäga (eller uppskatta) där målet kommer att vara inom de närmaste sekunderna, är det möjligt att justera den aktuella banan för att undvika onödiga vägar:


Förutspår framtiden

Som beskrivs i de första handledningarna beräknas rörelsen med hjälp av Euler-integration:

position = position + hastighet

Som en direkt följd, om den aktuella karaktärens position och hastighet är känd är det möjligt att förutsäga var det kommer att finnas inom det närmaste T speluppdateringar. Förutsatt att tecknet rör sig i en rak linje och den position vi vill förutsäga är tre uppdateringar framåt (T = 3) kommer karaktärens framtida position att vara:

position = position + hastighet * T

Nyckeln till en bra förutsägelse är det rätta värdet för T. Om värdet är för högt betyder det att förföljaren kommer att jaga ett spöke. Om T är för nära noll betyder det att förföljaren faktiskt inte förföljer målet, men det följer bara det (ingen förutsägelse).

Om förutsägelsen beräknas för varje spelram, fungerar den även om målet ändras ständigt. Varje uppdatering skapas en ny "framtida position" baserat på teckans aktuella hastighetsvektor (som också styr rörelsriktningen).


Sysslar

Förföljande beteende fungerar i stort sett på samma sätt som sökningen gör, den enda skillnaden är att förföljaren inte kommer att söka målet själv, men dess ställning inom en snar framtid.

Förutsatt att varje karaktär i spelet representeras av en klass som heter Boid, Följande pseudokod implementerar den grundläggande idén bakom strävan beteende:

 public function pursuit (t: Boid): Vector3D T: int = 3; futurePosition: Vector3D = t.position + t.velocity * T; retursökning (futurePosition); 

Efter sträckningskraftberäkningen måste den läggas till hastighetsvektorn precis som alla tidigare styrkor:

 public function update (): void styrning = strävan (mål) styrning = trunkera (styrning, max_force) styrning = styrning / masshastighet = trunkera (hastighet + styrning, max_speed) position = position + hastighet

Figuren nedan illustrerar processen:

Förföljaren (karaktären i botten) kommer att söka målets framtida position, efter en bana som beskrivs av den orangefärgade kurvan. Slutresultatet blir:


Förföljande beteende med T = 30. Klicka på demo för att visa kraftvektorer. Målet söker musen.


Förbättrad Pursuit Noggrannhet

Det finns ett problem när värdet av T är konstant: jaktsnoggrannheten tenderar att vara dålig när målet är nära. Detta beror på att när målet är nära, fortsätter förföljaren att söka förutspårning av målets position, vilket är T ramar "bort".

Det beteendet skulle aldrig hända i en verklig strävan eftersom förföljaren skulle veta att den är tillräckligt nära målet och bör sluta förutspå sin position.

Det finns ett enkelt trick som kan genomföras för att undvika det och drastiskt förbättra efterföljningsnoggrannheten. Tanken är väldigt enkel; istället för ett konstant värde för T, en dynamisk används:

 T = distanceBetweenTargetAndPursuer / MAX_VELOCITY

Den nya T beräknas baserat på avståndet mellan de två tecknen och den maximala hastighet målet kan uppnå. I enkla ord den nya T betyder "hur många uppdateringar målet behöver flyttas från sin nuvarande position till förföljarens position".

Ju längre avståndet desto högre är T kommer att vara, så förföljaren kommer att söka en punkt långt före målet. Ju kortare avståndet desto lägre T kommer att vara, vilket betyder att det kommer att söka en punkt som är mycket nära målet. Den nya koden för genomförandet är:

 public function pursuit (t: Boid): Vector3D varavstånd: Vector3D = t.position - position; var T: int = distance.length / MAX_VELOCITY; futurePosition: Vector3D = t.position + t.velocity * T; retursökning (futurePosition); 

Slutresultatet är:


Förföljandet beteende använder en dynamisk T. Klicka på demo för att visa kraftvektorer. Målet söker musen.


kringgå

Undviksbeteendet är motsatsen till strävan. I stället för att söka målets framtida position, kommer evakueringsbeteendet att flyga den positionen:

Koden för evading är nästan identisk, bara den sista raden ändras:

 allmän funktion undviks (t: Boid): Vector3D varavstånd: Vector3D = t.position - position; var updatesAhead: int = distance.length / MAX_VELOCITY; futurePosition: Vector3D = t.position + t.velocity * updatesAhead; returnera flyktning (futurePosition); 

Slutresultatet är följande:


Undvikande beteende. Klicka på demo för att visa kraftvektorer. Målet söker musen.

Slutsats

I denna handledning beskrivs strävan och olyckshändelserna, som är bra att simulera en mängd olika mönster, såsom en grupp djur som försöker fly från en jägare.

Jag hoppas att du har haft dessa tips så långt och kan börja använda alla dessa beteenden, kombinera dem för att skapa ännu bättre mönster! Håll dig uppdaterad genom att följa oss på Twitter, Facebook eller Google+.