Entendiendo Comportamientos de Direccionamiento: Escape y Llegada
() translation by (you can also view the original English article)
Los comportamientos de la dirección apuntan a ayudar a los personajes autónomos a moverse de una manera realista, usando fuerzas simples que se combinan para producir una navegación improvisada similar a la vida. En este tutorial, cubriré el comportamiento de huida, que hace que el personaje se aleje de un perseguidor, y el comportamiento de llegada, lo que hace que el personaje se detenga y se detenga cuando se acerca a un objetivo.
Nota: Aunque este tutorial está escrito con AS3 y Flash, debería ser capaz de usar las mismas técnicas y conceptos en casi cualquier entorno de desarrollo de juegos. Usted debe tener una comprensión básica de los vectores matemáticos.
Huyendo
El comportamiento de búsqueda descrito anteriormente se basa en dos fuerzas que empujan al personaje hacia el objetivo: la velocidad deseada y la dirección.
1 |
desired_velocity = normalize(target - position) * max_velocity |
2 |
steering = desired_velocity - velocity |
La desired_velocity
, en este caso, es la ruta más corta entre el personaje y el destino. Se calcula restando la posición del objetivo de la posición del personaje. El resultado es un vector de fuerza que va desde el personaje hacia el objetivo.

Comportamiento de Búsqueda
El comportamiento de huida utiliza esas mismas dos fuerzas, pero se ajustan para hacer que el personaje huya del objetivo:



Comportamiento de Huida
Ese nuevo vector desired_velocity
se calcula restando la posición del personaje de la posición del objetivo, que produce un vector que va desde el objetivo hacia el personaje.
Las fuerzas resultantes se calculan casi del mismo modo que en el comportamiento de búsqueda:
1 |
desired_velocity = normalize(position - target) * max_velocity |
2 |
steering = desired_velocity - velocity |
La desired_velocity
en ese caso representa la ruta de escape más fácil que el personaje puede utilizar para escapar del objetivo. La fuerza de dirección hace que el personaje abandone su ruta actual, empujándola hacia la dirección del vector de velocidad deseado.
Comparando el vector de velocidad deseada del comportamiento de huida con el vector de velocidad deseada del comportamiento de búsqueda, se puede establecer la siguiente relación:
1 |
flee_desired_velocity = -seek_desired_velocity |
En otras palabras, un vector es el negativo del otro.
Agregando fuerzas de escape
Después de calcular la fuerza de dirección, debe añadirse al vector de velocidad del personaje. Dado que esa fuerza está empujando al personaje lejos del objetivo, cada cuadro el personaje dejará de moverse hacia el objetivo y comenzará a alejarse de él, produciendo un camino de huida (la curva naranja en la figura de abajo):



La adición de esas fuerzas y el cálculo final de la velocidad / posición se manejan de la misma manera que antes. A continuación una demostración de varios personajes que realizan el comportamiento de huida:
Mueva el ratón para mover el objetivo
Cada personaje se coloca en el centro del área en movimiento con una velocidad aleatoria. Intentarán huir del objetivo (el cursor del ratón). La adición de todas las fuerzas hace a cada personaje suavemente abandonar su ruta actual y huir del objetivo.
Actualmente el objetivo afecta a cada personaje, ignorando la distancia de ellos; podría haberse limitado a una "zona de efectos", en la que el personaje huiría sólo si estuviera lo suficientemente cerca del objetivo.
Llegada
El comportamiento de búsqueda, como hemos visto, hace que un personaje se mueva hacia un objetivo. Cuando alcanza el destino, la fuerza de direccionamiento sigue actuando sobre ella basándose en las mismas reglas, haciendo que el personaje "rebote" de un lado a otro alrededor del objetivo.
El comportamiento de búsqueda. Mueva el ratón para mover el objetivo.
El comportamiento de llegada evita que el personaje se mueva a través del destino. Hace que el personaje se ralentice a medida que se acerca al destino, eventualmente deteniéndose junto al objetivo.
El comportamiento se compone de dos fases. La primera fase es cuando el personaje está muy lejos del objetivo y funciona exactamente de la misma manera que lo hace el comportamiento de búsqueda (se mueve a toda velocidad hacia el objetivo).
La segunda fase es cuando el personaje está cerca del objetivo, dentro del "área de desaceleración" (un círculo centrado en la posición del objetivo):



Cuando el personaje entra en el círculo, se ralentiza hasta que se detiene en el objetivo.
Ralentizando
Cuando el personaje entra en el área de desaceleración, su velocidad disminuye linealmente hasta cero. Esto se logra añadiendo una nueva fuerza de dirección (la fuerza de llegada) al vector de velocidad del personaje. El resultado de esta adición eventualmente se convertirá en cero, lo que significa que no se agregará nada a la posición del personaje en cada fotograma (por lo que no habrá movimiento):
1 |
// If (velocity + steering) equals zero, then there is no movement
|
2 |
velocity = truncate(velocity + steering, max_speed) |
3 |
position = position + velocity |
4 |
|
5 |
function truncate(vector:Vector3D, max:Number) :void { |
6 |
var i :Number; |
7 |
i = max / vector.length; |
8 |
i = i < 1.0 ? i : 1.0; |
9 |
vector.scaleBy(i); |
10 |
}
|
Con el fin de asegurar que el carácter disminuirá gradualmente antes de que se detenga, la velocidad no debe convertirse en cero inmediatamente. El proceso de ralentización gradual se calcula en función del radio del área de desaceleración y la distancia entre el personaje y el objetivo:
1 |
// Calculate the desired velocity
|
2 |
desired_velocity = target - position |
3 |
distance = length(desired_velocity) |
4 |
|
5 |
// Check the distance to detect whether the character
|
6 |
// is inside the slowing area
|
7 |
if (distance < slowingRadius) { |
8 |
// Inside the slowing area
|
9 |
desired_velocity = normalize(desired_velocity) * max_velocity * (distance / slowingRadius) |
10 |
} else { |
11 |
// Outside the slowing area.
|
12 |
desired_velocity = normalize(desired_velocity) * max_velocity |
13 |
}
|
14 |
|
15 |
// Set the steering based on this
|
16 |
steering = desired_velocity - velocity |
Si la distancia es mayor que slowingRadius
, significa que el personaje está muy lejos del objetivo y su velocidad debe permanecer max_velocity
.
Si la distancia es menor que la slowingRadius
, significa que el personaje ha entrado en el área de desaceleración y su velocidad debe ser reducida.
El término distance / slowingRadius
variará desde 1
(cuando distance
es igual a slowingRadius
) a 0
(cuando distance
es casi cero). Esta variación lineal hará que la velocidad disminuya suavemente:



Como se ha descrito anteriormente, el movimiento del personaje se realiza de la siguiente manera:
1 |
steering = desired_velocity - velocity |
2 |
velocity = truncate (velocity + steering , max_speed) |
3 |
position = position + velocity |
Si la velocidad deseada es reducida a cero, entonces la fuerza de direccionamiento se convierte en -velocity
. Como consecuencia, cuando se agrega esa fuerza de dirección a la velocidad, resultará en cero, haciendo que el personaje se detenga.
A continuación se muestra una demostración que muestra el comportamiento de llegada:
Mueva el ratón para mover el objetivo.
Lo que el comportamiento de la llegada hace realmente, es calcular una fuerza que será igual a -velocity
, impidiendo que el personaje se mueva mientras esa fuerza esté en su lugar. El vector de velocidad original del personaje no cambia y continúa funcionando, pero es anulado por la adición de dirección.
Si se eleva la fuerza de dirección de llegada, el personaje comenzará a moverse nuevamente, usando su vector de velocidad original.
Conclusión
El comportamiento de huida hace que el personaje se aleje del objetivo deseado mientras que el comportamiento de llegada hace que se ralentice y se detenga en la posición del objetivo. Ambos se pueden utilizar para crear escape suave o seguir patrones de movimiento, por ejemplo. También se pueden combinar para crear movimientos aún más complejos.
Este tutorial describió más acerca de los comportamientos de dirección, explicando los comportamientos de huida y llegada. En los próximos posts, aprenderemos sobre más comportamientos. Manténgase actualizado siguiéndonos en Twitter, Facebook o Google+.