« Así, yo tampoco quiero ser Español | Inicio | [XP] Propiedad colectiva del código, tests, y coding standards »

Motor para aventuras gráficas en AS 2 y XML

Desde finales de Diciembre y hasta finales de febrero, he estado desarrollando un motor para la creación de aventuras gráficas, realizado íntegramente con ActionScript 2.0 .
Por requerimientos del cliente, las aventuras gráficas debían ser completamente ( tanto los objetos que aparecen en pantalla como la lógica del juego ) configurables desde archivos XML. Además, otros requerimientos eran la utilización de diferentes perspectivas visuales en las escenas ( la aventura gráfica no podía estar completamente realizada en una sola perspectiva, típicamente isométrica ) y además debía simular un "efecto de 3d" en las escenas en que fuese necesario.

Es decir, un motor en el que se carga la lógica de cada escena de un archivo xml, en el que debe funcionar la escena independientemente de que sea una perspectiva frontal, lateral, una habitación de dos pisos etc..., y en la que había que desarrollar un sistema que permitiese al personaje pasar por delante y/o detrás de los objetos que aparecen en pantalla ( por ejemplo una mesa en el medio de una habitación ) en función de su posición ( que claro, depende de la perspectiva ). Evidentemente, el motor se desarrolló antes que muchos diseños de escenas, por lo que debía ser lo suficientemente flexible como para permitir que en pantalla hubiese de 0 a n objetos, que cada uno de estos objetos pudiese estar en cualquier coordenada de pantalla ( objetos en primer plano, objetos a media distancia, objetos en línea del horizonte ) y que el personaje pudiese interactuar con ellos correctamente.

Por supuesto, el motivo para realizar un motor de estas características, es el hecho de poder crear numerosas aventuras gráficas con el mismo motor, por lo que supuestamente el esfuerzo de programación debe descender exponencialmente a medida que se van realizando aventuras gráficas.

Una vez programado el motor, para cada aventura gráfica, en el departamento de la empresa al que pertenezco, desarrollamos los archivos XML en el que indicamos qué objetos aparecen en cada escena, y lo que ocurre al interactuar con cada uno de ellos ( cambios que se producen en ese y en otros objetos, paso de objetos a inventario, formulación de preguntas, visualización de avisos, requerimiento de objetos de inventario etc... )

Cada cdrom, lleva unos 650 - 700 ficheros flash ( lo que supone unas 2000 animaciones/grafismos diferentes ), y tantos xml de configuración de escenas, como escenas hay en el juego ( aparte de un par de archivos xml de configuración general del juego ).
De lo que estoy más satisfecho es de los siguientes puntos.

1.Ninguno de estos 700 archivos fla/swf lleva una sola línea de programación ( a excepción del stop() final de las animaciones )

2.Debido a esto, cada archivo xml de configuración de una escena está siendo desarrollado por personas que no tienen conocimientos de flash. ( A la hora de empezar a montar las escenas de configuración del primer cdrom, estas personas nunca habían abierto flash, lo que no impide que creen una escena de dificultad media en unos 20 minutos ). Evidentemente estas personas sí tenían una amplia experiencia en desarrollo de aplicaciones que incluían el uso de archivos XML, por lo que trabajar con este tipo de archivos no era ninguna novedad para ellos.

3. El "módulo 3d" que permite que aunque la escena tenga una visualización frontal, o lateral, o dividida en dos pisos... el personaje protagonista de las aventuras pueda pasar por delante y por detrás de los objetos, bien sea objetos situados en primer plano, en el centro de la escena etc... De esto estoy muy satisfecho, pues dada las diferentes posibles formas de visualización había que encontrar un sistema lo suficientemente genérico como para funcionar en todas, y no en una sola ( Habitualmente los juegos de este tipo, se construyen con una perspectiva isométrica, pues la solución al z-sorting es conocida, permite una gran reutilización de objetos gráficos, algoritmos de pathfinder etc.., pero el cliente no quería esto, por lo que teníamos que encontrar la forma de hacerlo funcionar con las especificaciones dadas ).


La aplicación tiene unas 8000 líneas de código ( incluyendo las necesarias para las pantallas intermedias de selección de personje, introducción de datos, almacenamiento de los mismos, gestión de las puntuaciones etc...)

Está construida utilizando un diseño orientado a objetos( unos 65 ficheros entre clases e interfaces ) ( toda la aplicación está construida usando POO y se arranca llamando al método main de la clase base de la aplicación )

Esta clase base, gestiona las comunicaciones entre las demás clases, mediante la emisión y recepción de eventos, aislando así unas de otras, permitiendo la máxima independencia de cada una de ellas, de modo que una clase no se ve afectada por cambios en las demás.

Un ejemplo es la clase "proxy" desarrollada para el almacenamiento de los datos y puntuaciones del usuario. Actualmente, esta salvaguarda de datos se lleva a cabo mediante el uso de sharedObjects en la máquina del usuario. Así cada vez que el jugador llega a una situación en la que hay que mostrarle sus puntuaciones y almacenarlas en disco el proceso es el siguiente.

La clase base, recibe un evento desde otra clase, que le indica que el usuario ha llegado a la situación de mostrar/almacenar puntuaciones. Nuestra clase base indica mediante un evento a la clase encargada de mostrar las puntuaciones, que pinte los valores en pantalla. Cuando esta clase termina de hacerlo, no los almacena, sino que le devuelve un evento a la clase base indicándole que ya ha terminado de pintar los datos y que se puede proceder a grabarlos. Entonces la clase base, le envía un evento a nuestra clase "proxy", que se encargará de guardar los datos. Cuando los datos estén salvados, le enviará un evento a la clase base, indicándole que el proceso de salvaguarda está finalizado. Y una vez recibido este evento, nuestra clase base decidirá lo que hay que hacer, si llevar al usuario a otra pantalla ( emitiendo un evento que será recogido por el controlador de la vista de destino ) o bien cualquier otra acción. -El uso de estas clases "proxy" es muy habitual por mi parte, pues me permiten no tener que modificar nada de la aplicación en sí, si se produce un cambio de tecnología de servidor ( ASP, PHP, JSP que es la utilizada habitualmente en la empresa, ColdFusion, ...)y se pasa de utilizar una a utilizar otra-.

Uno de los requerimientos del cliente era que la aplicación fuese fácilmente portable a web. Cuando llegue el momento, no habrá que hacer más que cambiar los métodos "insertData" y "receiveData" de esta clase para que en lugar de almacenar los datos en un sharedObject, llamen a cualquier tecnología de servidor. ( Extender la clase y sobrescribir la parte necesaria de los métodos implicados, o bien utilizar otra clase que implemente la misma interfaz ).

Cada objeto de la aplicación tiene su propia máquina de estados, y cada objeto puede tener tantos estados y transiciones entre estados, como se le indique desde el archivo xml de configuración de la escena( un estado, dos, ......, n estados ). También desde este archivo, indicamos qué efectos en otros objetos ( cambios de estado en otros objetos ) se producen al interactuar con cada objeto ( en función de cuál sea su estado actual ).

Evidentemente, el primer cdrom fue como un parto para todos los departamentos implicados, pero una vez determinado a partir de esa experiencia el sistema de trabajo más adecuado, los cdroms se van haciendo a gran velocidad a pesar de las numerosas animaciones necesarias para cada uno de ellos. Además, la experiencia que se va adquiriendo con cada cdrom, hace que los departamentos de guión y de animación y grafismo, vayan cada vez exprimiendo más las posibilidades del juego, y sacándolas mayor provecho, haciendo que cada aventura sea más bonita gráficamente y en cuanto a nivel de animación que la anterior, y con unas "tramas" más complejas. Estamos todos muy satisfechos.

¿ Quién dijo que con flash no se podían hacer este tipo de cosas?

Comentarios

Enhorabuena Javier, se lo que se debe sentir al ser el responsable de crear un proyecto de este tipo dado que este fué también uno de mis sueños de siempre.

Los juegos que siempre me gustaron fueron las aventuras de LucasArts clasicas, como Monkey Island, Maniac Mansion, The Dig, etc... y por eso una de mis aspiraciones de siempre fué realizar un motor de aventuras de este tipo con Flash.

Todavía no descarto el tener algún día el tiempo suficiente para (como mínimo) ponerme manos a la obra...la ilusión nunca se pierde :)

Gracias Carlos,
la verdad es que ha sido duro, ha llevado mucho esfuerzo, mucho, pero ahora se ven los resultados, la creación rápida de los cd's, etc.. y es cuando por fin tengo tiempo para pararme a pensar que he hecho algo "chulo". Y sí, claramente Monkey Island y Maniac Mansion han sido referencias. De hecho durante el desarrollo estuve viendo varias veces información sobre el motor SCUMM ( en la wikipedia y por ahí ).

Un saludo.

Impresionante....

¿Se podría ver algunas pinceladas de código???

Si que pinta impresionante, si... felicidades por el esfuerzo.

Si algún día lo portáis a web ya sabes, dirección!! ;)

saludos,
gracias, lo siento nitro pero no puedo publicar códigos pues pertenecen a la empresa. Tampoco puedo poner un pantallazo de las aventuras pues el cliente ni siquiera las ha distribuido todavía ( no se si esperará a que estén todas terminadas ).
Y sí, danisan, si se porta a web, se lo enseñaré a todo el mundo.

Gracias, y un saludo.

Interesante sin duda la iniciativa, me ha entrado el gusanillo a mi ... jajaja

una pregunta... como aplicaste el path_finder? Flash no es muy potente que digamos y si te pones a buscar caminos.. en fin...

Quien sabe, quizas si que me decida a hacer un motor "libre" ,... asi que lo mismo vuelvo a por consejos!! ;D;D

Saludos,
pues no utilicé ningún algoritmo de pathfinder porque en las especificaciones que me dieron, no se quería que si el personaje está en un extremo de la escena, y quiere interactuar con un objeto que está en el otro extremo, no se quería que con pinchar sobre el objeto el personaje se desplazase hasta el a pesar de los obstáculos que hubiese en mitad del camino. Entonces no hay pathfinder, pero lo que sí que hay es que cada escena está divida en zonas, y desde el xml le indicas en cada estado a cada objeto en qué zona ha de estar el personaje para que el objeto esté activo. Es otra forma que cumple los requisitos, y ciertamente nos ahorra mucho consumo de cpu, que podemos revertir en enriquecer las animaciones y demás.
De todos modos, hay muchos ejemplos de pathfinder por ahí, un día vi que sephirot había hecho ( me llamó la atención ) un webservice con php, que te calculaba el camino y claro lo recogías desde flash, y mueves tu objeto. Muchas veces, aunque visualmente sea similar, dependiendo de lo que nos pidan usamos unas opciones u otras, y en este caso no hubo pathfinder ( si el juego hubiese sido completamente en isométrico, lo habría habido )

Un saludo.

Me parece muy interesante el proyecto en el que has trabajado y me gustaria poder verlo.

Un grupo de compañeros y yo estamos trabajando en un proyecto similar, pero es para fines educativos y nos gustaria obtener un poco de informacion de como manejar este tipo de aplicaciones, podrias recomendarnos algun sitio o algunos recursos para poder realizar las animaciones tercera dimension, por favor !