Le suivi de chemin est un problème fréquent dans le développement de jeux. Ce tutoriel couvre les chemin suivant comportement de pilotage, qui permet aux personnages de suivre un chemin prédéfini constitué de points et de lignes.
Remarque: Bien que ce tutoriel ait été écrit avec AS3 et Flash, vous devriez pouvoir utiliser les mêmes techniques et concepts dans presque tous les environnements de développement de jeux. Vous devez avoir une compréhension de base des vecteurs mathématiques.
Un comportement de suivi de chemin peut être implémenté de plusieurs manières. L’implémentation originale de Reynolds utilise un chemin composé de lignes, où les caractères les suivent strictement, presque comme un train sur rails.
Selon la situation, une telle précision peut ne pas être requise. Un personnage peut se déplacer le long d’un chemin suivant des lignes, mais en les utilisant comme référence, plutôt que comme des rails.
L’implémentation du comportement de suivi de chemin dans ce tutoriel est une simplification de l’original proposé par Reynolds. Il produit toujours de bons résultats, mais il ne repose pas sur des calculs mathématiques lourds tels que des projections vectorielles..
Un chemin peut être défini comme un ensemble de points (nœuds) connectés par des lignes. Même si les courbes peuvent également être utilisées pour décrire un tracé, les points et les lignes sont plus faciles à manipuler et produisent presque les mêmes résultats..
Si vous devez utiliser des courbes, elles peuvent être réduites à un ensemble de points connectés:
La classe Chemin
sera utilisé pour décrire l'itinéraire. En gros, la classe a un vecteur de points et quelques méthodes pour gérer cette liste:
Classe publique Path private var nodes: Vector.; fonction publique Path () this.nodes = nouveau vecteur. (); fonction publique addNode (node: Vector3D): void nodes.push (node); fonction publique getNodes (): Vector. retourne les noeuds;
Chaque point du chemin est un Vector3D
représentant une position dans l'espace, de la même manière que le personnage position
travaux immobiliers.
Pour naviguer dans le chemin, le personnage se déplace de noeud en noeud jusqu'à la fin de la route..
Chaque point du chemin peut être considéré comme une cible, ainsi le comportement de recherche peut être utilisé:
Cherchez un point après l'autre.Le personnage cherchera le point actuel jusqu'à ce qu'il soit atteint, puis le point suivant du chemin deviendra le point actuel et ainsi de suite. Comme décrit précédemment dans le didacticiel relatif à l'évitement des collisions, les forces de chaque comportement sont recalculées à chaque mise à jour du jeu. La transition d'un nœud à un autre est donc fluide et fluide..
La classe du personnage aura besoin de deux propriétés supplémentaires pour instrumenter le processus de navigation: le nœud actuel (celui que le personnage cherche) et une référence au chemin suivi. Le cours ressemblera à ceci:
classe publique Boid public var path: Path; public var currentNode: int; (…) Fonction privée pathFollowing (): Vector3D var target: Vector3D = null; if (path! = null) var noeuds: vecteur.= path.getNodes (); cible = noeuds [currentNode]; si (distance (position, cible) <= 10) currentNode += 1; if (currentNode >= noeuds.longueur) currentNode = noeuds.longueur - 1; return null; distance de fonction privée (a: objet, b: objet): nombre return Math.sqrt ((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y)); (…)
le pathFollowing ()
méthode est celle qui est responsable de la génération de la force qui suit le chemin. Actuellement, il ne produit aucune force, mais il sélectionne correctement les cibles.
le chemin! = null
test vérifie si le caractère suit un chemin. Si tel est le cas le currentNode
Cette propriété est utilisée pour rechercher la cible actuelle (celle que le personnage doit rechercher) dans la liste des points..
Si la distance entre la cible actuelle et la position du personnage est inférieure à dix
, cela signifie que le personnage a atteint le nœud actuel. Si cela se produit, currentNode
est incrémenté de un, ce qui signifie que le personnage cherchera le prochain point du chemin. Le processus est répété jusqu'à ce que le chemin manque de points.
La force utilisée pour pousser le personnage vers chaque nœud du chemin est la force de recherche. le pathFollowing ()
La méthode choisit déjà le nœud approprié, elle doit donc maintenant renvoyer une force qui poussera le caractère vers ce nœud:
fonction privée pathFollowing (): Vector3D var target: Vector3D = null; if (path! = null) var noeuds: vecteur.= path.getNodes (); cible = noeuds [currentNode]; si (distance (position, cible) <= 10) currentNode += 1; if (currentNode >= noeuds.longueur) currentNode = noeuds.longueur - 1; return target! = null? recherchez (cible): new Vector3D ();
Une fois que la force qui suit le chemin est calculée, elle doit être ajoutée au vecteur de vitesse du personnage comme d'habitude:
direction = rien (); // le vecteur nul, signifiant "magnitude zéro force" Steering = Steering + pathFollowing (); direction = troncature (direction, force max.) direction = direction / vitesse de la masse = troncature (vitesse + direction, vitesse maximale) position = position + vitesse
La trajectoire qui suit la force de direction est extrêmement similaire au comportement de poursuite, où le personnage ajuste constamment sa direction pour attraper la cible. La différence réside dans la manière dont le personnage cherche une cible immuable, qui est ignorée au profit d'une autre dès que le personnage s'approche trop.
Le résultat est le suivant:
Chemin suivant en action. Cliquez pour afficher les forces.L’implémentation actuelle nécessite que tous les caractères "touchent" le point actuel du chemin afin de sélectionner la cible suivante. En conséquence, un personnage peut effectuer des mouvements non souhaités, tels que tourner en rond autour d'un point jusqu'à ce qu'il soit atteint..
Dans la nature, chaque mouvement a tendance à obéir au principe du moindre effort. Par exemple, une personne ne marchera pas au milieu d'un couloir tout le temps; s'il y a un tournant, la personne marchera tout près des murs tout en se retournant afin de raccourcir la distance.
Ce motif peut être recréé en ajoutant un rayon au chemin. Le rayon est appliqué aux points et peut être considéré comme la "largeur" de la route. Il contrôlera à quelle distance un personnage peut se déplacer des points le long du chemin:
Influence du rayon sur le suivi du chemin.Si la distance entre le caractère et le point est inférieure ou égale au rayon, le point est considéré comme atteint. En conséquence, tous les personnages se déplaceront en utilisant les lignes et les points comme des guides:
Chemin suivi avec rayon. Cliquez sur le bouton "Force" pour afficher les forces. Cliquez sur les boutons "+" et "-" pour ajuster dynamiquement la taille du rayon..Plus le rayon est grand, plus la route est large et plus la distance que les personnages garderont à partir des points de virage sera grande. La valeur du rayon peut être modifiée pour produire différents modèles suivants.
Parfois, il est utile qu'un personnage continue à bouger une fois qu'il a atteint la fin du chemin. Dans un modèle de patrouille, par exemple, le personnage doit revenir au début de la route après avoir atteint la fin, en suivant les mêmes points..
Ceci peut être réalisé en ajoutant le pathDir
propriété à la classe du personnage; c'est un entier qui contrôle la direction dans laquelle le personnage se déplace le long du chemin. Si pathDir
est 1
, cela signifie que le personnage se déplace vers la fin du chemin; -1
dénote un mouvement vers le début.
le pathFollowing ()
la méthode peut être changée en:
fonction privée pathFollowing (): Vector3D var target: Vector3D = null; if (path! = null) var noeuds: vecteur.= path.getNodes (); cible = noeuds [currentNode]; si (distance (position, cible) <= path.radius) currentNode += pathDir; if (currentNode >= nodes.length || currentNode < 0) pathDir *= -1; currentNode += pathDir; return target != null ? seek(target) : new Vector3D();
Contrairement à l'ancienne version, la valeur de pathDir
est maintenant ajouté à la propriété currentNode
(au lieu d'ajouter simplement 1
). Cela permet au personnage de sélectionner le prochain point du chemin en fonction de la direction actuelle..
Après cela, un test vérifie si le personnage a atteint la fin de la route. Si c'est le cas, pathDir
est multiplié par -1
, qui inverse sa valeur, obligeant ainsi le personnage à inverser le sens du mouvement.
Le résultat est un mouvement de va-et-vient:
Chemin suivi avec le motif de rayon et de va-et-vient. Cliquez sur le bouton "Force" pour afficher les forces. Cliquez sur les boutons "+" et "-" pour ajuster dynamiquement la taille du rayon..Le comportement suivant le chemin permet à n'importe quel personnage de se déplacer le long d'un chemin prédéfini. L'itinéraire est guidé par des points et peut être ajusté pour être plus large ou plus étroit, produisant des schémas de mouvement plus naturels..
L'implémentation couverte dans ce tutoriel est une simplification du comportement de suivi de trajet d'origine proposé par Reynolds, mais elle produit toujours des résultats convaincants et attrayants..