Naast het vermogen om een pad te volgen, moet een personage (of een groep) ook een specifiek personage (zoals een squadleader) kunnen volgen. Dit kan worden bereikt met behulp van de leider volgen gedrag, dat ik in deze tutorial zal uitleggen.
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.
Het leidende gedrag is een samenstelling van andere stuurkrachten, allemaal gearrangeerd om een groep karakters een specifiek karakter (de leider) te laten volgen. Een naïeve benadering zou zoeken of nastreven gebruiken om een volgpatroon te creëren, maar het resultaat is niet goed genoeg.
In het zoekgedrag wordt een personage naar een doelwit geduwd, en uiteindelijk bezet het dezelfde locatie als dat doelwit. Het achtervolgingsgedrag daarentegen duwt een personage naar een ander personage, maar streeft ernaar het te vangen (op basis van voorspellingen) in plaats van het alleen maar te volgen..
In het gedrag dat de leider volgt, is het doel om dicht genoeg bij de leider te blijven, maar iets erachter. Het personage moet ook sneller naar de leider toe bewegen wanneer deze ver weg is, maar moet langzamer rijden als de afstand klein is. Dit kan allemaal worden bereikt door drie stuurgedrag te combineren:
In de volgende secties wordt uitgelegd hoe elk van deze gedragingen wordt gecombineerd om het patroon van de volgende leider te creëren.
Een personage moet tijdens het volgende proces proberen enigszins achter de leider te blijven, zoals een leger dat achter zijn commandant blijft. Het punt om te volgen (genoemd achter
) kan eenvoudig worden berekend op basis van de snelheid van het doel, omdat het ook de richting van het teken aangeeft. Controleer de pseudo-code:
tv = leader.velocity * -1; tv = normaliseren (tv) * LEADER_BEHIND_DIST; achter = leader.position + tv;
Als de snelheidsvector wordt vermenigvuldigd met -1
, het resultaat is het omgekeerde van de snelheidsvector. Die resulterende vector (genaamd TV
) kan vervolgens worden genormaliseerd, dienovereenkomstig worden geschaald en worden toegevoegd aan de huidige positie van het personage.
Hier is een visuele weergave van het proces:
Vectorbewerkingen die betrokken zijn bij het vinden van de juiste plek om te volgen.Hoe groter LEADER_BEHIND_DIST
is, hoe groter de afstand tussen de leider en het achterste punt is. Aangezien de personages dat punt zullen volgen, zal de afstand van de leider groter zijn naarmate hij verder van de leider verwijderd is.
De volgende stap is om een personage de leider te laten volgen achter
punt. Net als alle andere gedragingen, zal het volgende proces geleid worden door een kracht, gegenereerd door de followLeader ()
methode:
private function followLeader (leider: Boid): Vector3D var tv: Vector3D = leader.velocity.clone (); var force: Vector3D = new Vector3D (); // Bereken het achterste punt tv.scaleBy (-1); tv.normalize (); tv.scaleBy (LEADER_BEHIND_DIST); behind = leader.position.clone (). add (tv); // Creëert een kracht om te komen tot het achterliggende punt force = force.add (aankomen (achter)); terugkeerkracht;
De methode berekent de achter
punt en creëert een kracht om op dat punt aan te komen. De followLeader
Kracht kan dan worden toegevoegd aan de stuurkracht van het personage, net als alle andere gedragingen:
besturing = niets (); // de nulvector, wat betekent "nulkrachtmagnitude" besturing = sturen + followLeader (); sturen = afbreken (sturen, max_kracht) sturen = sturen / massasnelheid = afbreken (snelheid + sturen, max_snelheid) positie = positie + snelheid
Het resultaat van die implementatie is een groep karakters die bij de leider kunnen komen achter
punt:
Wanneer personages erg dicht bij elkaar staan tijdens het volgen van de leider, kan het resultaat onnatuurlijk lijken. Omdat alle personages worden beïnvloed door soortgelijke krachten, hebben ze de neiging om op dezelfde manier te bewegen, waardoor ze een "blob" vormen. Dit patroon kan worden opgelost met behulp van scheiding, een van de regels die het stroomstijgingsgedrag sturen.
De scheidingskracht voorkomt dat een groep tekens samenvloeit, zodat ze op een bepaalde afstand van elkaar blijven. De scheidingskracht kan worden berekend als:
private function separation (): Vector3D var force: Vector3D = new Vector3D (); var neighborCount: int = 0; for (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;
De scheidingskracht kan dan worden toegevoegd aan de followLeader
kracht, waardoor het in staat is de personages van elkaar af te duwen tegelijkertijd dat ze proberen bij de leider aan te komen:
private function followLeader (leider: Boid): Vector3D var tv: Vector3D = leader.velocity.clone (); var force: Vector3D = new Vector3D (); // Bereken het achterste punt tv.scaleBy (-1); tv.normalize (); tv.scaleBy (LEADER_BEHIND_DIST); behind = leader.position.clone (). add (tv); // Creëert een kracht om te komen tot het achterliggende punt force = force.add (aankomen (achter)); // Voeg scheidingskracht toe = force.add (scheiding ()); terugkeerkracht;
Het resultaat is een veel natuurlijker volgpatroon:
Personages volgen de leider met behulp van scheiding. Verplaats de muisaanwijzer om de leider te leiden. Klik om krachten te tonen.Als de leider plotseling de huidige richting verandert, bestaat de kans dat de personages de leider in de weg lopen. Omdat de personages de leider volgen, heeft het geen zin hen toe te staan voor de leider te blijven.
Als een personage de leider hindert, moet het onmiddellijk weggaan om de route te wissen. Dit kan worden bereikt met behulp van het ontwijkgedrag:
De route van de leider ontwijkenOm te controleren of een personage in het zicht van de leider staat, gebruiken we een soortgelijk concept als hoe we obstakels detecteren in het botsingsvermijdingsgedrag: op basis van de huidige snelheid en richting van de leider projecteren we een punt ervoor (genaamd verder
); als de afstand tussen de leider verder
punt en het karakter is kleiner dan 30
, bijvoorbeeld, dan is het personage in het zicht van de leider en moet het bewegen.
De verder
punt wordt precies zo berekend als het achter
punt, met dit verschil dat de snelheidsvector niet is omgekeerd:
tv = leader.velocity; tv = normaliseren (tv) * LEADER_BEHIND_DIST; vooruit = leader.position + tv;
De followLeader ()
methode moet worden bijgewerkt om te controleren of het personage op het zicht van de leider staat. Als dat gebeurt, de variabele dwingen
(vertegenwoordigt de volgende kracht) wordt toegevoegd door de terugkeer van ontwijken (leider)
, die een kracht teruggeeft om de locatie van de leider te omzeilen:
private function followLeader (leider: Boid): Vector3D var tv: Vector3D = leader.velocity.clone (); var force: Vector3D = new Vector3D (); // Bereken het voorschot tv.normalize (); tv.scaleBy (LEADER_BEHIND_DIST); ahead = leader.position.clone (). add (tv); // Bereken het achterste punt tv.scaleBy (-1); behind = leader.position.clone (). add (tv); // Als het personage op het gezicht van de leider staat, voeg dan een kracht // toe om de route onmiddellijk te ontwijken. if (isOnLeaderSight (leider, vooruit)) force = force.add (ontwijken (leider)); // Creëert een kracht om te komen tot het achterliggende punt force = force.add (arrive (behind, 50)); // 50 is de aankomende straal // Voeg scheidingskracht toe = force.add (scheiding ()); terugkeerkracht; private function isOnLeaderSight (leader: Boid, leaderAhead: Vector3D): Boolean return distance (leaderhead, dit) <= 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));
Elk personage zal onmiddellijk zijn huidige positie ontwijken als het in het zicht van de leider staat:
Personages volgen de leider met behulp van afscheiding en ontwijken het zicht van de leider. Verplaats de muisaanwijzer om de leider te leiden. Klik om krachten te tonen.Hieronder vindt u een demo waarin het gedrag van de leider wordt weergegeven. De blauwe soldaat (de leider) komt aan bij de muiscursor, terwijl de groene soldaten de leider volgen.
Wanneer de speler ergens in het scherm klikt, zullen alle soldaten de muiscursor zien en schieten. De monsters komen op willekeurige locaties aan, om de paar seconden.
Verplaats de muiscursor om de leider te leiden (de soldaten zullen volgen). Klik om de monsters te schieten.Het gedrag dat de leider volgt, stelt een groep personages in staat een specifiek doelwit te volgen en er iets achter te blijven. De personages ontwijken ook hun huidige locatie als ze uiteindelijk de leider in de weg zitten.
Het is belangrijk om op te merken dat het gedrag dat de leider volgt, een is combinatie van verschillende andere gedragingen, zoals aankomen, ontwijken en scheiden. Het laat zien dat eenvoudig gedrag kan worden gecombineerd om extreem complexe bewegingspatronen te creëren.
Bedankt voor het lezen! Ik hoop dat je het eerder beschreven gedrag kunt combineren om je eigen complexe gedrag te creëren!