Inzicht in stuurgedrag dwaal

Stuurgedrag is erop gericht om autonome personages op een realistische manier te laten bewegen, door eenvoudige krachten te gebruiken die leiden tot een levensechte, improviserende navigatie. In deze tutorial behandel ik de dwalen gedrag, waardoor het personage willekeurig beweegt.

Notitie: Hoewel deze tutorial geschreven is met behulp van AS3 en Flash, zou je in bijna elke game-ontwikkelomgeving dezelfde technieken en concepten moeten kunnen gebruiken. Je moet een basiskennis hebben van wiskundige vectoren.


Rond lopen

Vaak moeten de personages van een spel willekeurig door hun omgeving bewegen. Meestal wachten die personages gewoon op iets dat gebeurt (zoals een gevecht tegen de speler) of zoeken ze iets. Wanneer de speler dat gedrag kan zien, moet het zwervende vermogen van het personage visueel aangenaam en realistisch genoeg zijn.

Als de speler in staat is om sterk gedefinieerde padlijnen of onrealistisch bewegingsgedrag te identificeren, zal dit frustratie genereren. In het ergste geval zal de speler uitzoeken hoe hij kan anticiperen op de bewegingen van het personage, wat resulteert in een saaie spelervaring.

De dwalen stuurgedrag is gericht op het produceren van een realistische "toevallige" beweging, waardoor de speler denkt dat het personage echt leeft en rondloopt.


Zoek en willekeur

Er zijn verschillende manieren om het dwaalpatroon te implementeren met behulp van stuurgedrag. De eenvoudigste is het gebruik van het eerder beschreven zoekgedrag. Wanneer een personage zoekt, zal het naar een doel toe bewegen.

Als de positie van dat doel om de paar seconden verandert, kan het personage het doel nooit bereiken (en zelfs als dat het geval is, zal het doelwit opnieuw bewegen). Door het doel willekeurig in het spelgebied te plaatsen, zal het personage zich uiteindelijk door de hele omgeving bewegen en het doelwit achtervolgen. De onderstaande demo toont deze aanpak in actie:


Het zoekgedrag en een willekeurig doelwit. Klik op de demo om krachtvectoren te tonen.

De code voor deze implementatie zou zijn:

 // Bereken de dwaalkracht privé-functie dwaal (): Vector3D var now: Number = (new Date ()). GetTime (); if (now> = nextDecision) // Kies een willekeurige positie voor "target" // stuur een stuurkracht terug die het karakter // naar het doel (het zoekgedrag) duwt return seek (target);  // In de loop van het spel, behandel krachten en beweging net // zoals eerder: update van public function (): void steering = wander () steering = truncate (steering, max_force) steering = steering / mass velocity = truncate (velocity + sturen, max_snelheid) positie = positie + snelheid

Hoewel dit een eenvoudige en goede aanpak is, is het eindresultaat niet zo overtuigend. Soms keert het personage zijn route volledig om omdat het doelwit erachter wordt geplaatst. Het gedrag van het personage lijkt veel meer op "Verdomme, ik ben mijn sleutels vergeten!" dan "Oké, ik zal deze richting nu volgen".


Wander

Een andere implementatie van het wandelgedrag werd voorgesteld door Craig W. Reynolds toen hij dat gedrag uitvond. Het basisidee is om kleine willekeurige verplaatsingen te produceren en toe te passen op de huidige richtingsvector van het personage (de snelheid, in ons geval) op elk spelframe. Omdat de snelheidsvector definieert waar het personage naar toe gaat en hoeveel het elk frame beweegt, zal elke interferentie met die vector de huidige route wijzigen.

Door gebruik te maken van kleine verplaatsingen voorkomt elk frame dat het personage de route abrupt verandert. Als het personage omhoog gaat en naar rechts draait, bijvoorbeeld, zal het in het volgende gameframe nog steeds naar boven gaan en naar rechts draaien, maar in een iets andere hoek.

Die aanpak kan ook op verschillende manieren worden geïmplementeerd. Een daarvan is om een ​​cirkel voor het personage te gebruiken, waarmee je alle betrokken krachten kunt berekenen:

De verplaatsingskracht  heeft zijn oorsprong in het midden van de cirkel en wordt beperkt door de straal van de cirkel. Hoe groter de straal en de afstand van het karakter tot de cirkel, hoe sterker de "push" het karakter elk speelframe zal ontvangen.

Deze verplaatsingskracht wordt gebruikt om de route van het personage te verstoren. Het wordt gebruikt om het te berekenen zwervende kracht.


De positie van de cirkel berekenen

Het eerste onderdeel dat nodig is om de dwaalkracht te berekenen, is de middelste positie van de cirkel. Aangezien de cirkel voor het personage moet worden geplaatst, kan de snelheidsvector als richtlijn worden gebruikt:

 // De onderstaande constante CIRCLE_DISTANCE is // een getal dat ergens anders is gedefinieerd. // De code om het cirkelcentrum te berekenen: var circleCenter: Vector3D; circleCenter = velocity.clone (); circleCenter.normalize (); circleCenter.scaleBy (CIRCLE_DISTANCE);

De circleCenter vector hierboven is een kloon (kopie) van de snelheidsvector, wat betekent dat ze naar dezelfde richting wijzen. Het is genormaliseerd en vermenigvuldigd met een scalaire waarde (CIRCLE_DISTANCE, in dit geval), wat zal resulteren in de volgende vector:


Verplaatsingskracht

Het volgende onderdeel is de verplaatsingskracht, die verantwoordelijk is voor de draai naar rechts of naar links. Omdat dit een kracht is die wordt gebruikt om stoornis te veroorzaken, kan deze overal wijzen. Laten we een vector gebruiken die is uitgelijnd met de Y-as:

 var verplaatsing: Vector3D; verplaatsing = nieuwe Vector3D (0, -1); displacement.scaleBy (CIRCLE_RADIUS); // // Verander de vectorrichting // willekeurig door de huidige hoeksetAngle (displacement, wanderAngle) te wijzigen; // // Verander dwalen een beetje, dus het // zal niet dezelfde waarde hebben in het // volgende gameframe. wanderAngle + = (Math.random () * ANGLE_CHANGE) - (ANGLE_CHANGE * .5);

De verplaatsingskracht wordt gecreëerd en geschaald door de straal van de cirkel. Zoals eerder beschreven, hoe groter de straal, hoe sterker de dwaalkracht. De wanderAngle is een scalaire waarde die definieert hoeveel de verplaatsingskracht moet worden "gekanteld"; nadat het is gebruikt, wordt een willekeurige waarde toegevoegd om het anders te maken voor het volgende gameframe. Het produceert de vereiste willekeur in de beweging.

Laten we voor het begrip aannemen dat de hierboven berekende verplaatsingskracht in het midden van de cirkel is geplaatst. Omdat het werd geschaald door de cirkelradiuswaarde, zou het ongeveer zoiets zijn als dit:

Tip: Onthoud dat wiskundige vectoren geen positie in de ruimte hebben, ze hebben een richting en een grootte (lengte). Als gevolg hiervan kunnen ze overal worden geplaatst.

Wander Force

Nadat het cirkelmidden en de verplaatsingsvector zijn berekend, moeten ze worden gecombineerd om de zwervende kracht. Die kracht wordt berekend door die twee vectoren toe te voegen:

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

We kunnen deze krachten visueel representeren als:

De dwaalkracht kan worden voorgesteld als een vector die van het personage naar een punt op de cirkelomtrek gaat. Afhankelijk van de positie van dat punt, duwt de dwaalkracht het personage naar links of naar rechts, sterk of zwak:

Hoe meer de dwaalkracht is uitgelijnd met de snelheidsvector, hoe minder het teken zijn huidige route zal wijzigen. De dwaalkracht werkt precies zoals de zoek- en vluchtkrachten: het duwt het personage in een richting.

Vergelijkbaar met zoeken en vluchten waar de krachtrichting wordt berekend op basis van een doelwit, wordt de dwaalrichting berekend op basis van een willekeurig punt op de omtrek van de cirkel. De definitieve code voor de dwaalkracht is:

 private function wander (): Vector3D // Bereken de cirkel center var circleCenter: Vector3D; circleCenter = velocity.clone (); circleCenter.normalize (); circleCenter.scaleBy (CIRCLE_DISTANCE); // // Bereken de verplaatsingskracht var verplaatsing: Vector3D; verplaatsing = nieuwe Vector3D (0, -1); displacement.scaleBy (CIRCLE_RADIUS); // // Verander de vectorrichting // willekeurig door de huidige hoeksetAngle (displacement, wanderAngle) te wijzigen; // // Verander dwalen een beetje, dus het // zal niet dezelfde waarde hebben in het // volgende gameframe. wanderAngle + = Math.random () * ANGLE_CHANGE - ANGLE_CHANGE * .5; // // Eindelijk bereken en keer de zwervende kracht terug var dwalingForce: Vector3D; wanderForce = circleCenter.add (verplaatsing); terugkeer dwaalkracht;  public function setAngle (vector: Vector3D, waarde: Number): void var len: Number = vector.length; vector.x = Math.cos (waarde) * len; vector.y = Math.sin (waarde) * len; 

Krachten toevoegen

Nadat de dwaalkracht is berekend, moet deze aan de snelheid van het personage worden toegevoegd, zodat deze de beweging ervan kan beïnvloeden. De toevoeging van die kracht wordt op dezelfde manier uitgevoerd als voorheen:

 sturen = afdwalen () sturen = afhakken (sturen, max_kracht) sturen = sturen / massasnelheid = afkappen (snelheid + sturen, max_snelheid) stand = stand + snelheid

De dwaalkracht beïnvloedt de route van het personage op dezelfde manier als de eerder beschreven gedragingen, met dit verschil dat het personage in elk frame naar een willekeurige richting wordt geduwd:


Het wandelgedrag. Klik op de demo om krachtvectoren te tonen.

De demo hierboven toont verschillende personages die rondzwerven in de omgeving. Als ze het scherm verlaten, worden ze in het midden opnieuw uitgezet.


Conclusie

Het wandelgedrag is een uitstekende manier om willekeurige bewegingen te implementeren. Het wordt bestuurd door een denkbeeldige cirkel die voor het personage wordt geplaatst en die kan worden aangepast om het gewenste bewegingspatroon te produceren.

Deze tutorial beschreef stuurgedrag en legde het wandelgedrag uit. In de volgende post zullen we leren over meer gedrag. Blijf op de hoogte door ons te volgen op Twitter, Facebook of Google+.