Este capítulo está enfocado a desarrollar una aplicación basada en las funciones que permiten acceder a ficheros XML desde Revolution. El esbozo incial y casi todo el código son obra de Yolanda Perdiguero.
Los objetivos son:
Conocer cómo funciona el manejo de documentos XML en Revolution 2.0
Aprender a utilizar diferentes objetos y el lenguaje de programación de Revolution: Transcript.
Se ha propuesto utilizar como base de desarrollo un interfaz del estilo de la Figura 18-1:
Como no se ha impuesto ninguna restricción en el formato del archivo y con ánimo de hacer el planteamiento ameno las preguntas no serán de ningún temario académico, así que el fichero del "cuestionario" puede ser algo como:
<?xml version="1.0"?>
<Tipo1>
<cuestion>
<P>¿De que color era el caballo blanco de Satiago?</P>
<R tipo="ver">Blanco</R> <R tipo="fals">Negro</R> <R tipo="fals">Azul</R>
<R tipo="fals">Rojo</R>
</cuestion>
<cuestion>
<P>¿Cuantos años tengo?</P>
<R tipo="fals">20</R>
<R tipo="fals">30</R>
<R tipo="ver">29</R>
<R tipo="fals">43</R>
</cuestion>
</Tipo1>
Donde se recogen dos preguntas y sus posibles respuestas, indicando cuál de ellas es falsa y cuál es cierta, sólo una puede ser cierta. Con este enfoque la aplicación adquiere un aspecto de juego de preguntas. Con lo que el planteamiento inicial, con el toque particular de la autora, se puede reescribir como:
Pregunta por el nombre para ofrecer un diálogo más amable y da a elegir una actividad (un fichero XML) a realizar.
Al cargar el fichero crea dinámicamente las tarjetas y los respuestas en botones. Estos se situarán de manera aleatoria para que el "jugador" no se limite a aprender la opción correcta. De este modo, Acabada de cargar la última cuestión, se empieza a contestar desde ahí.
Al final nos dice la puntuación que se haya obtenido y nos preguntará si queremos volver a jugar o salir.
Tanto en un caso como en otro, se ha de borrar todo lo anterior y volver a empezar.
Nota: Hay que hacer notar que para la utilización de la función que posiciona de manera aleatoria (random) las respuestas nos hemos basado en una pila publicada en la web de Revolution llamada Multiple-Choice Tutorial™ .
Uso de la librería XML.
Creamos el árbol y vamos al nodo raiz (Tipo1)
# #Script Jugar : # global arbol global tipo global nombre on MouseUp ask "¿Cómo te llamas?" put it into nombre answer file "elige un archivo xml" put URL ("file:" &it)into field "fichero" put it put revCreateXMLTree(field "fichero",false, true, false) into arbol put revXMLRootNode (arbol) into tipo Set the script of first card to field "final" call "mouseUp" of button "empezar" end MouseUp
Vamos al primer hijo del nodo raiz (cuestión) y a los hermanos del hijo del nodo raiz (las otras "cuestion" ).
# #Script Empezar : # global arbol global tipo global boton on mouseUP put revXMLFirstChild (arbol, tipo) into cuestion put 1 into boton call "truca cuestion" to button "llamada2" REPEAT put revXMLNextSibling (arbol, cuestion) into cuestion if cuestion is not empty then send "truca cuestion" to button "llamada2" of first card else exit repeat END REPEAT end mouseUP
Vamos al primer hijo de una cuestion determinada (la pregunta) Ponemos el contenido de la pregunta en un fichero Vamos a cada hermana de la pregunta (que son cada una de las respuestas)
# #Script llamada2 : # global arbol global cuest on truca cuestion put cuest+1 into cuest call "posicion" of button "llamada" of first card put RevXMLFirstChild (arbol, cuestion) into pregunta put RevXMLNodeContents (arbol, pregunta) into fld "P" REPEAT put revXMLNextSibling (arbol, pregunta) into respuesta if respuesta is not empty then call "desor" of fld "des" of first card call "crear respuesta" of button "llamada1" of first card put respuesta into pregunta else exit repeat END REPEAT end truca
Introducimos dentro de una variable el contenido de una respuesta, también introducimos dentro de otra variable el valor de un determinado atributo (valor), de esa respuesta.
# #Script llamada1 : # global arbol on crear respuesta put revXMLNodeContents (arbol, respuesta) into prova put revXMLAttribute (arbol, respuesta, valor) into resul if resul = "ver" then put prova into fld "solu" end if put the number of items of fld "des" of first card into var put random (var) into aux create button prova set the script of it to field "orden" of card "primera" move it to 200, 20+(50*item aux of fld "des" of first card) delete item aux of fld "des" of first card end crear
Para tarjeta pone el contador boton a 1
# #Script llamada : # global boton on posicion create Card set the script of it to field card put 1 into boton end posicion
Random.
Para tarjeta pone el contador "boton" a 1
# #Script llamada : # global boton on posicion Create Card Set the script of it to field "contador" of first card put 1 into boton end posicion
Para cada respuesta llama a la función que está en el field "des"
# #Script llamada2 : # ... REPEAT put revXMLNextSibling (arbol, pregunta) into respuesta If respuesta is not empty then call "desor" of fld "des" of first card ... else exit repeat END REPEAT end truca
Cada vez que se le llama suma al contador botón 1 y lo escribe en el propio cuadro de texto, separado por ",".
# # Script field des : # global boton on desor put boton+1 into boton put field "des" of first card && boton & "," into field "des" of first card end desor
Aquí es donde se desordenan las respuestas cambiando su posición. Son los valores (items) del field "des" los que se desordenan utilizando la orden random. Pero teniendo la preocupación de borrar dicho item si ya ha sido utilizado.
# # Script llamada1 : # on crear respuesta ... put the number of items of fld "des" of first card into var put random (var) into aux create button prova set the script of it to field "orden" of card "primera" move it to 200, 20+(50*item aux of fld "des" of first card) delete item aux of fld "des" of first card end crear
Resultado y salida.
Los botones.
Si no hemos contestado ninguna pregunta mal nos pondrá 0 donde está el nulo. Un mensaje nos indica cuántas hemos hecho bien y cuántas mal. Un mensaje final nos da la opción de salir o de volver a jugar.
global nombre on mouseUp If the value of field "mal" is empty then\ put "0" into field "mal" answer "Tu resultado ha sido: " &&\ the value of field "bien" & " bien" &\ " y "&& the value of field "mal"& " mal" answer "¿Que quieres hacer ahora?, "&& nombre \ with "Jugar" or "Salir" if it="Jugar" then call "mouseUp" of button "borrar" of first card call "mouseUp" of button "Jugar" else call "MouseUp" of button "exit" end if end mouseUp end borrar
Tanto si se sale o se vuelve a jugar hay que borrar todas las tarjetas creadas y poner el contador de tarjetas (cuest) como está cuando se entra por primera vez (a 1).
# #Script botón Borrar : # global cuest on mouseUp repeat with i = cuest down to 1 if i=1 then exit repeat else delete card i end if end repeat put 1 into cuest end mouseUp
En el caso de salir se borran las tarjetas, como hemos visto anteriormente; pero ya no hay que poner el contador a 1, se pondrá a 1 cuando se abra la stack.
# #Script botón Exit : # on mouseUp answer "Ha sido un placer" call "mouseUp" of button "borrar" of first card close this stack end mouseUp
Los campos de texto.
# # Final # on preOpenCard hide background "group semaf" put the value of fld "bien" of second card into fld "bien" put the value of fld "mal" of second card into fld "mal" hide button "Jugar" show button "Ver" end preOpenCard on closeCard show background "group semaf" End closeCard # # Contador # on openCard put the value of fld "bien" of next card into fld "bien" put the value of fld "mal" of next card into fld "mal" end openCard # # Orden # on mouseUp if (the short name of me) = (the value of fld "solu") then call "bien" to graphic "bien" else call "mal" to graphic "mal" end if end mouseUp # # Graphic Bien # on bien put the value of fld "bien"+1 into fld "bien" show graphic "verde" send "beep" wait 1 seconds hide graphic "verde" visual effect scroll left go to prev card end bien # # Graphic Mal # on mal put the value of fld "mal" +1 into fld "mal" show graphic "rojo" play "glass.wav" wait 1 seconds hide graphic "rojo" end mal # # Stack # global cuest on preOpenStack put empty into fld "bien" put empty into fld "mal" hide background "group semaf" hide button "Ver" of first card show button "Jugar" put 1 into cuest end preOpenStack on closeStack set the script of first card to empty end closeStack
Unas notas finales:
Hay que pensarse más detenidamente el nombre que se le da a los objetos y a las diferentes variables.
Respecto a XML: crear la DTD correspondiente y que la aplicación lo valide antes de ejecutarlo. Se tendrá que crear otro nivel para separar tipos de ejercicios cuando ampliemos estos con el ahorcado, unir con flechas y el puzzle.
Respecto a la Interfaz: conocer mejor las propiedades de cada objeto para poderlas cambiar mediante scripts y así el diseño sea más seguro y más agradable.
Respecto a Revolution: plantearnos si queremos sólo una pila de Revolution, si se puede aprovechar parte del planteamiento para crear una aplicación.
Como ejemplo de la utilización de esta aplicación la secuencia de la Figura 18-3 muestra un posible recorrido. Empezando por la primera fila y de izquierda a derecha se puede observar: la pantalla de presentación, la entrada del nombre del usuario, un momento de la creación dinámica de las preguntas donde se observa la creación de una de las preguntas, la primera cuestión a la que se va a responder con los marcadores incializados, la forma de señalar la aplicación la elección de una respuesta incorrecta y el modo de indicar que la respuesta elegida es la correcta.
Una de las ventajas de que todo gire en torno a un fichero XML que contiene las preguntas y las respuestas, en lugar de que sea algo estático en la pila es la corrección de errores. Poe ejemplo, durante la fase de pruebas se ha observado que existen algunos errores de sintáxis en el texto de una de las preguntas (Figura 18-4a). Podemos editar el fichero con cualquier editor de texto y corregirlo, a la próxima vez que se ejecute la aplicación (Figura 18-4b) el problema estará resuelto. Así de fácil también es añadir más cuestiones o desarrollar nuevos cuestionarios.
En el presente caso de estudio se ha desarrollado una aplicación capaz trabajar con un fichero XML utilizando las funciones de Revolution.
Al cargar el fichero se observa claramente la carga de las preguntas y la preparación de las tarjetas ...
Al salir ... no se sale
Tanta orden call, ¿es necesaria?
Por supuesto el tema no se agota aquí, es posible pensar en ampliaciones como:
El enunciado no incluye la posibilidad de incorporar datos de partida en formatos diferentes del texto. Sería interesante incluir información que permita incorporar ficheros de audio, imágenes o vídeo, como parte de la pregunta.
Sería posible medir el tiempo que tarda el usuario en recorrer y responder al cuestionario y a cada pregunta en particular. Estas puede ser una medida más a tener en cuenta, para el docente principalmente, de cara a identificar las preguntas donde los alumnos se detienen más o cualquier otra circunstancia
Sería posible guardar cuántas veces se ha pasado por una pregunta y se ha cambiado la respuesta, así como también impedirlo si se desea.
Se puede ampliar el formato actual a otros tipos de ejercicios: "unir con flechas", ahorcado, puzzle. Para ello la descripción XML debería incorporar información al respecto del tipo de la pregunta o del cuestionario.
Toda la aplicación se puede realizar sobre una misma tarjeta si se rediseña el código utilizado, no necesariamente la interfaz.
Las respuestas finales, junto a los datos que se consideren de interés se podrían enviar por correo electrónico desde la propia aplicación ...