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 ...