Oltre alla capacità di seguire un percorso, anche un personaggio (o un gruppo di essi) deve essere in grado di seguire un personaggio specifico (come un caposquadra). Questo può essere ottenuto usando il leader seguendo comportamento, che spiegherò in questo tutorial.
Nota: Sebbene questo tutorial sia scritto usando AS3 e Flash, dovresti essere in grado di utilizzare le stesse tecniche e concetti in quasi tutti gli ambienti di sviluppo di giochi. Devi avere una conoscenza di base dei vettori di matematica.
Il comportamento che segue il leader è una composizione di altre forze di governo, tutte disposte in modo che un gruppo di personaggi segua un personaggio specifico (il leader). Un approccio ingenuo userebbe la ricerca o il perseguimento per creare un modello di follow, ma il risultato non è abbastanza buono.
Nel comportamento di ricerca un personaggio viene spinto verso un bersaglio, occupando infine la stessa identica posizione di quel bersaglio. Il comportamento di inseguimento, d'altra parte, spinge un personaggio verso un altro personaggio, ma mira a prenderlo (basato sulle previsioni) invece di seguirlo semplicemente.
Nel comportamento che segue il leader, l'obiettivo è quello di stare abbastanza vicino al leader, ma leggermente dietro. Il personaggio dovrebbe anche muoversi più velocemente verso il leader quando è distante, ma dovrebbe rallentare quando la distanza è piccola. Tutto questo può essere raggiunto combinando tre comportamenti di guida:
Le sezioni successive spiegano come ciascuno di questi comportamenti viene combinato per creare il modello che segue il leader.
Un personaggio dovrebbe cercare di rimanere leggermente indietro rispetto al leader durante il seguente processo, come un esercito che sta dietro al suo comandante. Il punto da seguire (chiamato dietro a
) può essere facilmente calcolato in base alla velocità del bersaglio, poiché rappresenta anche la direzione del personaggio. Controlla lo pseudo-codice:
tv = leader.velocity * -1; tv = normalize (tv) * LEADER_BEHIND_DIST; dietro = leader.position + tv;
Se il vettore di velocità è moltiplicato per -1
, il risultato è il inverso del vettore di velocità. Quel vettore risultante (chiamato tv
) può quindi essere normalizzato, ridimensionato di conseguenza e aggiunto alla posizione corrente del personaggio.
Ecco una rappresentazione visiva del processo:
Operazioni vettoriali coinvolte nella ricerca del punto giusto da seguire.Il più grande LEADER_BEHIND_DIST
è, maggiore è la distanza tra il leader e il punto dietro. Dal momento che i personaggi seguiranno quel punto, il più distante è dal leader, più distanti saranno i personaggi dal leader.
Il prossimo passo è fare in modo che un personaggio segua il leader dietro a
punto. Proprio come tutti gli altri comportamenti, il seguente processo sarà guidato da una forza, generata dal followLeader ()
metodo:
private function followLeader (leader: Boid): Vector3D var tv: Vector3D = leader.velocity.clone (); var force: Vector3D = new Vector3D (); // Calcola il punto dietro tv.scaleBy (-1); tv.normalize (); tv.scaleBy (LEADER_BEHIND_DIST); dietro = leader.position.clone (). add (tv); // Crea una forza per arrivare al punto dietro force = force.add (arrive (behind)); forza di ritorno;
Il metodo calcola il dietro a
punta e crea una forza per arrivare a quel punto. Il followLeader
la forza può quindi essere aggiunta alla forza di sterzo del personaggio, proprio come tutti gli altri comportamenti:
steering = nothing (); // il vettore nullo, che significa "forza zero magnitudo", direzione = sterzo + followLeader (); sterzo = troncato (sterzo, max_force) sterzata = sterzo / velocità di massa = troncata (velocità + sterzata, max_velocità) posizione = posizione + velocità
Il risultato di tale implementazione è un gruppo di personaggi in grado di arrivare a quello del leader dietro a
punto:
Quando i personaggi sono molto vicini l'uno all'altro mentre seguono il leader, il risultato potrebbe sembrare innaturale. Poiché tutti i personaggi saranno influenzati da forze simili, tendono a muoversi in modo simile, formando un "blob". Questo modello può essere risolto utilizzando la separazione, una delle regole che guida il comportamento di floccaggio.
La forza di separazione impedisce a un gruppo di personaggi di affollarsi, quindi mantengono una certa distanza l'uno dall'altro. La forza di separazione può essere calcolata come:
private function separation (): Vector3D var force: Vector3D = new Vector3D (); var neighborCount: int = 0; per (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;
La forza di separazione può quindi essere aggiunta al followLeader
forza, rendendolo in grado di allontanare i personaggi l'uno dall'altro allo stesso tempo che cercano di arrivare al leader:
private function followLeader (leader: Boid): Vector3D var tv: Vector3D = leader.velocity.clone (); var force: Vector3D = new Vector3D (); // Calcola il punto dietro tv.scaleBy (-1); tv.normalize (); tv.scaleBy (LEADER_BEHIND_DIST); dietro = leader.position.clone (). add (tv); // Crea una forza per arrivare al punto dietro force = force.add (arrive (behind)); // Aggiungi forza di separazione force = force.add (separation ()); forza di ritorno;
Il risultato è un modello molto più naturale seguente:
Personaggi che seguono il leader usando la separazione. Muovi il cursore del mouse per guidare il leader. Clicca per mostrare le forze.Se il leader cambia improvvisamente la direzione corrente, c'è una possibilità che i personaggi finiscano per intralciare il leader. Dal momento che i personaggi seguono il leader, non ha senso permettere loro di rimanere di fronte al leader.
Se qualsiasi personaggio si mette in mezzo al leader, dovrebbe immediatamente allontanarsi per cancellare il percorso. Questo può essere ottenuto usando il comportamento di eludere:
Evadere la rotta del leaderPer verificare se un personaggio è nella vista del leader, usiamo un concetto simile a come rileviamo gli ostacoli nel comportamento di evitamento di collisione: in base alla velocità e direzione attuale del leader, proiettiamo un punto di fronte ad esso (chiamato avanti
); se la distanza tra i leader avanti
punto e il personaggio è inferiore a 30
, per esempio, allora il personaggio è nella vista del leader e dovrebbe muoversi.
Il avanti
il punto è calcolato esattamente come il dietro a
punto, con la differenza che il vettore di velocità non è invertito:
tv = leader.velocity; tv = normalize (tv) * LEADER_BEHIND_DIST; avanti = leader.position + tv;
Il followLeader ()
il metodo deve essere aggiornato per verificare se il personaggio si trova sulla vista del leader. Se ciò accade, la variabile vigore
(che rappresenta la seguente forza) è aggiunto dal ritorno di eludere (leader)
, che restituisce una forza per eludere la posizione del leader:
private function followLeader (leader: Boid): Vector3D var tv: Vector3D = leader.velocity.clone (); var force: Vector3D = new Vector3D (); // Calcola il punto avanti tv.normalize (); tv.scaleBy (LEADER_BEHIND_DIST); avanti = leader.position.clone (). add (tv); // Calcola il punto dietro tv.scaleBy (-1); dietro = leader.position.clone (). add (tv); // Se il personaggio è in vista del leader, aggiungi una forza // per eludere immediatamente il percorso. if (isOnLeaderSight (leader, ahead)) force = force.add (evade (leader)); // Crea una forza per arrivare al punto dietro force = force.add (arrive (behind, 50)); // 50 è il raggio di arrivo // Aggiungi forza di separazione forza = forza.add (separazione ()); forza di ritorno; private function isOnLeaderSight (leader: Boid, leaderAhead: Vector3D): Boolean return distance (leaderAhead, this) <= 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));
Ogni personaggio eluderà immediatamente la sua posizione attuale se è nella vista del leader:
Personaggi che seguono il leader usando la separazione ed evitando la vista del leader. Muovi il cursore del mouse per guidare il leader. Clicca per mostrare le forze.Di seguito una demo che mostra il comportamento del leader seguente. Il soldato blu (il leader) arriverà al cursore del mouse, mentre i soldati verdi seguiranno il leader.
Quando il giocatore fa clic in qualsiasi punto dello schermo, tutti i soldati dovranno affrontare il cursore del mouse e sparare. I mostri arriveranno in luoghi casuali, ogni pochi secondi.
Muovi il cursore del mouse per guidare il leader (i soldati seguiranno). Clicca per sparare ai mostri.Il comportamento seguente del leader consente a un gruppo di personaggi di seguire un obiettivo specifico, rimanendo leggermente dietro di esso. I personaggi evadono anche la loro posizione attuale se alla fine riescono a intralciare il leader.
È importante notare che il comportamento che segue il leader è a combinazione di molti altri comportamenti, come arrivare, sfuggire e separarsi. Dimostra che i comportamenti semplici possono essere combinati per creare schemi di movimento estremamente complessi.
Grazie per aver letto! Spero che tu possa iniziare a combinare i comportamenti precedentemente spiegati per creare il tuo comportamento complesso!