Seguir el camino es un problema frecuente en el desarrollo del juego. Este tutorial cubre el camino que sigue comportamiento de la dirección, que permite a los personajes seguir un camino predefinido hecho de puntos y líneas.
Nota: Aunque este tutorial está escrito con AS3 y Flash, debería poder utilizar las mismas técnicas y conceptos en casi cualquier entorno de desarrollo de juegos. Debes tener una comprensión básica de vectores matemáticos.
Una ruta que sigue el comportamiento se puede implementar de varias maneras. La implementación original de Reynolds utiliza un camino hecho de líneas, donde los personajes las siguen estrictamente, casi como un tren sobre rieles.
Dependiendo de la situación, tal precisión puede no ser requerida. Un personaje puede moverse a lo largo de un camino siguiendo las líneas, pero usándolos como un referencia, en lugar de como rieles.
La implementación de la ruta siguiendo el comportamiento en este tutorial es una simplificación del original propuesto por Reynolds. Todavía produce buenos resultados, pero no se basa en cálculos matemáticos pesados como las proyecciones vectoriales.
Una ruta se puede definir como un conjunto de puntos (nodos) conectados por líneas. Aunque las curvas también se pueden usar para describir una ruta, los puntos y las líneas son más fáciles de manejar y producen casi los mismos resultados.
Si necesita utilizar curvas, se pueden reducir a un conjunto de puntos conectados:
La clase Camino
Se utilizará para describir la ruta. Básicamente, la clase tiene un vector de puntos y algunos métodos para administrar esa lista:
ruta de clase pública nodos var privados: Vector.; Función pública Path () this.nodes = new Vector. (); función pública addNode (nodo: Vector3D): void nodes.push (nodo); función pública getNodes (): vector. nodos de retorno;
Cada punto en el camino es un Vector3D
representando una posición en el espacio, de la misma manera que el personaje posición
obras de propiedad.
Para navegar por el camino, el personaje se moverá de nodo en nodo hasta que llegue al final de la ruta..
Cada punto en el camino se puede ver como un objetivo, por lo que se puede usar el comportamiento de búsqueda:
Buscar un punto tras otro.El personaje buscará el punto actual hasta que se alcance, luego el siguiente punto en la ruta se convertirá en el actual, y así sucesivamente. Como se describió anteriormente en el tutorial para evitar colisiones, las fuerzas de cada comportamiento se vuelven a calcular cada actualización del juego, por lo que la transición de un nodo a otro es perfecta y fluida.
La clase del personaje necesitará dos propiedades adicionales para instrumentar el proceso de navegación: el nodo actual (el que busca el personaje) y una referencia a la ruta que se está siguiendo. La clase se verá como la siguiente:
clase pública Boid public var path: Path; public var currentNode: int; (…) Ruta de función privadaSiguiendo (): Vector3D var target: Vector3D = null; if (ruta! = nulo) var nodos: Vector.= ruta.getNodos (); target = nodes [currentNode]; si (distancia (posicion, objetivo) <= 10) currentNode += 1; if (currentNode >= nodes.length) currentNode = nodes.length - 1; devolver nulo; distancia de la función privada (a: Objeto, b: Objeto): Número return Math.sqrt ((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y)); (…)
los rutaSiguiendo ()
El método es el responsable de generar la ruta siguiendo la fuerza. Actualmente no produce fuerza, pero sí selecciona los objetivos correctamente..
los camino! = nulo
prueba comprueba si el personaje está siguiendo alguna ruta. Si ese es el caso el nodo actual
La propiedad se utiliza para buscar el objetivo actual (el que debe buscar el personaje) en la lista de puntos..
Si la distancia entre el objetivo actual y la posición del personaje es menor que 10
, significa que el personaje ha alcanzado el nodo actual. Si eso pasa, nodo actual
se incrementa en uno, lo que significa que el personaje buscará el siguiente punto en la ruta. El proceso se repite hasta que el camino se queda sin puntos..
La fuerza utilizada para empujar al personaje hacia cada nodo en el camino es la fuerza de búsqueda. los rutaSiguiendo ()
El método ya elige el nodo apropiado, por lo que ahora debe devolver una fuerza que empujará al personaje hacia ese nodo:
Función privada pathFollowing (): Vector3D var target: Vector3D = null; if (ruta! = nulo) var nodos: Vector.= ruta.getNodos (); target = nodes [currentNode]; si (distancia (posicion, objetivo) <= 10) currentNode += 1; if (currentNode >= nodes.length) currentNode = nodes.length - 1; return target! = null? buscar (objetivo): nuevo Vector3D ();
Una vez que se calcula la trayectoria que sigue a la fuerza, debe agregarse al vector de velocidad del personaje como de costumbre:
dirección = nada (); // el vector nulo, que significa "magnitud de fuerza cero" dirección = dirección + trayectoriaSiguiendo (); dirección = truncar (dirección, fuerza máxima) dirección = dirección / velocidad de la masa = truncar (velocidad + dirección, velocidad máxima) posición = posición + velocidad
El camino que sigue a la fuerza de dirección es extremadamente similar al comportamiento de persecución, donde el personaje ajusta constantemente su dirección para atrapar al objetivo. La diferencia radica en cómo el personaje busca un objetivo inamovible, que se ignora a favor de otro tan pronto como el personaje se acerca demasiado..
El resultado es el siguiente:
Ruta que sigue en acción. Haga clic para mostrar fuerzas.La implementación actual requiere que todos los caracteres "toquen" el punto actual en la ruta para seleccionar el siguiente objetivo. Como consecuencia, un personaje puede realizar patrones de movimiento no deseados, como moverse en círculos alrededor de un punto hasta que se alcanza.
En la naturaleza, cada movimiento tiende a obedecer el principio del menor esfuerzo. Por ejemplo, una persona no caminará en medio de un corredor todo el tiempo; Si hay un giro, la persona caminará cerca de las paredes mientras gira para acortar la distancia..
Ese patrón se puede recrear agregando un radio a la ruta. El radio se aplica a los puntos y se puede ver como la ruta "ancho". Controlará qué tan lejos puede moverse un personaje de los puntos a lo largo del camino:
Influencia del radio en el recorrido siguiente..Si la distancia entre el carácter y el punto es menor o igual que el radio, el punto se considera alcanzado. Como consecuencia, todos los personajes se moverán usando las líneas y puntos como guías:
Ruta que sigue con el radio. Haga clic en el botón "Forzar" para mostrar las fuerzas. Haga clic en los botones "+" y "-" para ajustar dinámicamente el tamaño del radio.Cuanto mayor sea el radio, más ancha será la ruta y mayor será la distancia que los personajes mantendrán de los puntos al girar. El valor del radio se puede ajustar para producir diferentes patrones siguientes.
A veces es útil que un personaje se siga moviendo después de llegar al final del camino. En un patrón de patrulla, por ejemplo, el personaje debe volver al principio de la ruta después de que llegue al final, siguiendo los mismos puntos..
Esto se puede lograr mediante la adición de la pathDir
propiedad a la clase del personaje; este es un número entero que controla la dirección en la que el personaje se mueve a lo largo del camino. Si pathDir
es 1
, significa que el personaje se está moviendo hacia el final del camino; -1
Denota un movimiento hacia el inicio..
los rutaSiguiendo ()
El método se puede cambiar a:
Función privada pathFollowing (): Vector3D var target: Vector3D = null; if (ruta! = nulo) var nodos: Vector.= ruta.getNodos (); target = nodes [currentNode]; si (distancia (posicion, objetivo) <= path.radius) currentNode += pathDir; if (currentNode >= nodos.longitud || nodo actual < 0) pathDir *= -1; currentNode += pathDir; return target != null ? seek(target) : new Vector3D();
A diferencia de la versión anterior, el valor de pathDir
ahora se agrega a la propiedad nodo actual
(en lugar de simplemente añadir 1
). Esto permite que el personaje seleccione el siguiente punto en el camino en función de la dirección actual.
Después de eso, una prueba verifica si el personaje ha llegado al final de la ruta. Si ese es el caso, pathDir
se multiplica por -1
, que invierte su valor, haciendo que el personaje invierta la dirección del movimiento también.
El resultado es un patrón de movimiento de ida y vuelta:
Ruta que sigue con el radio y el patrón de ida y vuelta. Haga clic en el botón "Forzar" para mostrar las fuerzas. Haga clic en los botones "+" y "-" para ajustar dinámicamente el tamaño del radio.El siguiente comportamiento de ruta permite que cualquier personaje se mueva a lo largo de una ruta predefinida. La ruta está guiada por puntos y se puede ajustar para que sea más ancha o más estrecha, produciendo patrones de movimiento que se sienten más naturales..
La implementación cubierta en este tutorial es una simplificación de la ruta original siguiendo el comportamiento propuesto por Reynolds, pero todavía produce resultados convincentes y atractivos..