Jesús Bosch

XNA, programación gráfica y desarrollo de videojuegos por un Microsoft Student Partner

[IA] Introducción a las máquinas de estado finito (Finite State Machines - FSM) - Parte II de II

En la primera parte vimos como una máquina de estados finitos permitía a una entidad de nuestro juego realizar una serie de acciones teniendo en cuenta algunos factores internos (hambre, cansancio, ganas de usar el WC...). Ahora veremos una versión mejorada de esta FSM, en la que entra en juego otra entidad, y la interacción entre ambas. Ahora pasaremos a tener la entidad Madre, además de la entidad Boy. Para que ambas FSM interactúen utilizaremos un sistema de mensajería entre objetos. Así pues la madre y el hijo se comunicarán entre sí (como tiene que ocurrir en toda buena familia).

En la primera versión, el niño, iba al WC cuando tenía ganas... ahora, además de eso, cuando haya terminado su estado de WCIng... volverá a la tarea a la que estaba anteriormente, fuera cual fuera (en la versión simplemente se ponía a jugar). Además, cuando tenga hambre, enviará un mensaje a su madre para que le haga la comida y seguirá con su tarea. Cuando la madre reciba el mensaje, dejará su tarea y se pondrá a hacer la comida, y cuando termine de hacerla, enviará un mensaje de notificación a su hijo, que ya podrá comer.

Esto podría implementarse sin sistema de mensajería... ignorando la estructura de la FSM y demás... pero es algo poco recomendable. Esta implementación (o cualquier mejora de ella), proporciona un código muy extensible, que encapsula muy bien la funcionalidad de la FSM, mejorando además su mantenibilidad. Observemos algunos cambios en el diseño de la entidad base:

Vemos que cada clase hija deberá implementar el método HandleMessage. Este lo que hará será llamar al método de manejo del mensaje en su instancia local de StateMachine. Esta, a su vez, enviará el mensaje al estado en el que se encuentre la clase. Hecho esto el mensaje será manejado... o no... esto dependerá de si el estado en el que se encuentra la entidad debe responder a ese mensaje.


Los mensajes son gestionados con la clase MessageDispatcher, que lo que permite es enviar estructuras del tipo Telegram entre entidades. Estos mensajes contienen el emisor/receptor, y el propio mensaje en sí mismo. Además contienen la propiedad "delay", por si queremos que la entidad receptora no reciba dicho mensaje hasta transcurrida X cantidad de milisegundos. Esto puede ser interesante por ejemplo en un juego en el que debemos esperar cierto tiempo (en un juego tipo command & conquer entrenaríamos un soldado y esperaríamos x tiempo a que finalizase el entrenamiento, transcurrido dicho tiempo, la unidad pasaría a estar disponible, notificándolo al sistema mediante uno de estos mensajes).

Otro cambio interesante es la clase StateMachine. Mediante la propiedad PreviousState puede volver a su estado anterior, si es necesario, tras finalizar la acción en su estado actual. Así, en el ejmplo que he implementado, el niño, tras usar el WC, volverá a la tarea en la que estaba anteriormente, fuera cual fuera. Esto dota de mayor dinamismo a la acción del juego.

Dejo el código disponible para quien quiera jugar con él o hacer propuestas de mejora!

Attachment: FSM_Test2.rar
Posted: 28/12/2009 13:46 por Jesús Bosch | con no comments |
Archivado en: ,,
Comparte este post: