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.
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:
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).
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.
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.
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:
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+.