Herramientas de usuario

Herramientas del sitio


estados_de_las_criaturas

Estados de las criaturas

En la sección sobre temporización vimos cómo funcionaba el modelo de tiempo de AGE, basado en unidades de tiempo y en propiedades cuyo método update se activa cuando su contador de tiempo llega a cero. En esa sección, vimos algunos ejemplos de cómo usar ese mecanismo para definir entidades con comportamientos que dependieran del tiempo. Pero, además de los que nosotros añadamos, en AGE ya existen comportamientos definidos por defecto que dependen del tiempo, que son los asociados a las acciones de las criatura, como coger un objeto o moverse en una dirección. Todas las acciones que llevan a cabo las criaturas consumen un tiempo, y la cuenta de este tiempo se lleva en el temporizador de una propiedad llamada “state”.

Por ejemplo, como jugadores, cuando AGE nos acepta una orden de entrada, es porque ha llegado a cero el temporizador de “state” de nuestro personaje jugador. Si tecleamos “ir norte”, AGE cambiará el valor de “state” a un valor de estado (que se verá más adelante) que indica que nos estamos moviendo, y fijará el temporizador al número de unidades de tiempo que nos consuma ir hacia el norte. Una vez llegado el temporizador a cero, esto significa que ya hemos terminado de ir hacia el norte y AGE esperará otra orden de entrada, que de nuevo cambiará el valor y temporizador de “state”, y así sucesivamente.

Por lo tanto, el método update que define AGE por defecto para la propiedad “state” de los jugadores es muy importante, porque es nada menos que el que consigue que al ejecutar una aventura monojugador, ésta nos vaya pidiendo órdenes y ejecutándolas una por una. En una aventura multijugador o que cuente con personajes complejos que realicen acciones, el temporizador de esta propiedad será el que se encargue de entrelazar correctamente las acciones: por ejemplo, si ir al norte desde una localidad a otra consume tres unidades de tiempo y coger un objeto consume una unidad de tiempo, el jugador A podrá coger tres objetos en el tiempo en el que el jugador B va al norte (la manera concreta en la que los jugadores perciben esto en los modos síncrono y de tiempo real se trató en la sección de temporización).

En la presente sección veremos en detalle cómo funciona esta propiedad especial “state” (y otra asociada, llamada “target”) y qué podemos hacer con ellas.

Las propiedades "state" y "target"

Las criaturas (objetos de la clase Mobile) tienen una propiedad especialmente importante llamada “state” (estado). La importancia de la propiedad “state” radica en que esta propiedad es la que define qué cosa está haciendo una criatura en cada momento, y su temporizador es el que indica cuánto tiempo tardará en hacerlo.

Asociada a la propiedad “state” aparece a veces otra propiedad, llamada “target”, que nos proporciona información extendida sobre el estado. Así, por ejemplo, si en un instante dado del juego la criatura Pepito está yendo de la sala sur a la sala norte, su propiedad “state” en ese momento valdrá Mobile.MOVING (valor que indica que se está moviendo) y su propiedad “target” contendrá un identificador de la sala norte. 1)

El manejo de las propiedades “state” y “target” ha de considerarse un tema avanzado, pues en la mayoría de los juegos no hace falta manipularlas. Sólo debería ser necesario en aventuras en las que se quiera tener un control fino del combate o de la temporización de eventos.

En la siguiente tabla se muestran los valores que puede tomar, para cualquier criatura, la propiedad “state”, así como su significado y el uso de la propiedad “target” para ese estado. Nótese que gran parte de los estados, aunque no todos, están relacionados con el combate y se tratarán en más detalle en la sección Combate y armas de esta documentación.

Valor de “state” Significado de “state” Significado de “target”
Mobile.IDLE Estado por defecto. Ojo: el nombre (IDLE, ocioso) está mal puesto, pues no tiene por qué significar que la criatura esté ociosa. Se puede utilizar para denotar que la criatura está llevando a cabo cualquier acción no contemplada en los otros estados. Por ejemplo, es el estado que tiene una criatura que está cogiendo o dejando un objeto.
Mobile.MOVING La criatura está moviendose de una habitación a otra. El temporizador de “state” indica cuántas unidades de tiempo quedan hasta que se complete el movimiento. En el momento en que se completa es cuando la criatura cambia realmente de habitación, y se imprimen los mensajes como “Fulano se va al norte” o “Fulano llega desde el sur”. Habitación destino
Mobile.ATTACKING La criatura está lanzando un ataque contra otra criatura. Cuando el temporizador llegue a cero, el ataque impactará al enemigo (si no ha sucedido antes algo que lo impida, como que la criatura reciba un golpe). Criatura que recibirá el ataque
Mobile.BLOCKING La criatura está preparando un bloqueo. Cuando el temporizador llegue a cero, la criatura pasará a estar “en guardia” (Mobile.READY_TO_BLOCK) y si le llega un ataque, será bloqueado.
Mobile.READY_TO_BLOCK La criatura está bloqueándose, con un escudo o arma alzada para parar un ataque enemigo.
Mobile.DODGING La criatura está echándose a un lado para intentar esquivar un ataque. Si el temporizador llega a cero antes de que se reciba el ataque, se considerará que le ha dado tiempo a esquivar.
Mobile.READY_TO_DODGE La criatura está echándose a un lado para intentar esquivar un ataque, y ha pasado el tiempo suficiente para considerar que le da tiempo a esquivar, sin que el ataque haya llegado.
Mobile.ATTACK_RECOVER La criatura está recuperándose después de haber lanzado una estocada o golpe. Hasta que el temporizador del “state” llegue a cero, no podrá emprender otra acción.
Mobile.BLOCK_RECOVER La criatura está recuperándose después de haber parado un golpe. Hasta que el temporizador del “state” llegue a cero, no podrá emprender otra acción.
Mobile.DAMAGE_RECOVER La criatura está recuperándose después de haber recibido un golpe. Hasta que el temporizador del “state” llegue a cero, no podrá emprender otra acción.
Mobile.DODGE_RECOVER La criatura está recuperándose después de haber llevado a cabo una esquivada con éxito. Hasta que el temporizador del “state” llegue a cero, no podrá emprender otra acción.
Mobile.DYING La criatura está cayendo muerta. Este estado siempre dura una unidad de tiempo nada más, y luego se pasa al estado Mobile.DEAD.
Mobile.DEAD La criatura está muerta.
Mobile.SURPRISE_RECOVER La criatura está recuperándose de una sorpresa o interrupción.
Mobile.DISABLED La criatura está desactivada y no reaccionará ante nada, ni recibirá entradas si es un jugador. Este estado se usa, por ejemplo, cuando el jugador que controlaba un personaje en una aventura multijugador se ha caído o desconectado.
Mobile.CASTING La criatura está lanzando un conjuro. Entidad a la que se le lanza el hechizo, si la hay

Cambios de estado

He aquí lo que sucede por defecto en AGE cuando el temporizador del estado de una criatura llega a cero, a no ser que nosotros como programadores redefinamos el método update para que haga algo distinto con la propiedad “state”:

Valor de “state” Reacción de las criaturas
Mobile.IDLE Tomar decisión
Mobile.MOVING Tomar decisión
Mobile.ATTACKING Se lleva a cabo el ataque y se pasa a Mobile.ATTACK_RECOVER
Mobile.BLOCKING Se pasa a Mobile.READY_TO_BLOCK
Mobile.READY_TO_BLOCK Se refresca el estado hasta que llegue el ataque enemigo, y en ese momento se pasa a BLOCK_RECOVER o DAMAGE_RECOVER según el resultado
Mobile.DODGING Se pasa a Mobile.READY_TO_DODGE
Mobile.READY_TO_DODGE Se refresca el estado hasta que llegue el ataque enemigo, y en ese momento se pasa a DODGE_RECOVER o DAMAGE_RECOVER según el resultado
Mobile.ATTACK_RECOVER Tomar decisión
Mobile.BLOCK_RECOVER Tomar decisión
Mobile.DAMAGE_RECOVER Tomar decisión
Mobile.DODGE_RECOVER Tomar decisión
Mobile.DYING Se pasa a Mobile.DEAD
Mobile.DEAD Se mantiene el estado (salvo para jugadores, que se pasa a Mobile.IDLE, para que puedan teclear comandos desde el limbo si la aventura lo soporta)
Mobile.SURPRISE_RECOVER Tomar decisión
Mobile.DISABLED Se mantiene el estado
Mobile.CASTING Se pasa a IDLE

Los casos en los que esta tabla dice “Tomar decisión” quiere decir que la criatura tiene la iniciativa y puede en ese momento emprender una nueva acción. Esto tiene un significado distinto según si la criatura es un jugador o no:

  • Si se trata de un jugador, cuando llegue el momento de “Tomar decisión” se esperará una orden por parte del cliente del jugador, y se procesará dicha orden, ejecutando los comportamientos correspondientes.
  • Si se trata de una criatura que no es jugador, cuando llegue el momento de “Tomar decisión” se hará lo siguiente:
    • Si tiene enemigos presentes, se llama a la IA de combate que decide qué acción de combate tomará la criatura (atacar, bloquear, etc.)
    • Si no tiene enemigos presentes, la criatura simplemente no hará nada, quedando indefinidamente en estado Mobile.IDLE.

Por supuesto, podemos sobreescribir el método update de los personajes no jugadores definiendo comportamientos más complejos, y así obtener criaturas que se muevan, sigan rutas, cojan objetos, desempeñen tareas, etc.

Programación con estados

Como programadores de aventuras, el uso más evidente de la propiedad “state” es el de comprobar lo que está haciendo una criatura. Por ejemplo, si queremos saber si un personaje llamado Manolo que está en nuestra habitación ha empezado a irse hacia otra, podríamos hacer algo como:

if ( equals ( get(mobile("Manolo"),"state") , Mobile.MOVING ) )
{
  self.say("¡No te vayas aún, Manolo, que todavía me quedan cosas que contarte!\n");
}

Además, con room(get(mobile(“Manolo”),“target”)) podemos obtener la habitación a la que se está moviendo Manolo, y con getTime(mobile(“Manolo”),“state”) tendremos el número de unidades de tiempo que le faltan para llegar a ella (véase la sección sobre temporización).

Aparte de utilizar la propiedad “state” para comprobar el estado de una criatura, los programadores más osados pueden querer redefinir lo que sucede en el método update para la propiedad “state” y de ese modo cambiar la manera en la que se comporta una criatura en los cambios de estado. Estos cambios pueden potencialmente ir desde modificaciones puntuales hasta cambios radicales que, por ejemplo, modifiquen totalmente la manera en la que se resuelven los cambios de estado tipo “Tomar decisión” cambiando todo el sistema de parseado de AGE por otro sistema totalmente distinto. Por supuesto, sólo los programadores avanzados o con mucha práctica en AGE y con interés en personalizarlo deberían utilizar estas características, que no son para nada necesarias para hacer un buen juego con AGE.

1) Por motivos puramente históricos, el identificador contenido en “target” es un número entero en lugar del nombre único de la sala. Sin embargo, se puede utilizar igual que si fuera el nombre único (es decir, funcionarán cosas como room(fulano.get(“target”)). Probablemente la propiedad “target” pase a contener nombres únicos, en lugar de dichos identifiadores enteros, en futuras versiones de AGE.
estados_de_las_criaturas.txt · Última modificación: 2012/10/13 19:45 por al-khwarizmi