Examen Curso 2001-2002. Convocatoria de Febrero Página 1 Ejercicio 1. Desarrollar un pequeño juego para practicar mecanografía. Este ejercicio se divide en dos partes con el fin de que el alumno no intente afrontarlo en su totalidad ya que podría entrañar bastante dificultad. De esta manera la primera parte sirve como base de la segunda y con la primera completada el alumno conseguiría un notable en este ejercicio. Si se quiere conseguir la máxima nota, se tendrá que realizar la segunda parte (cosa no muy difícil ya que sólo hay que añadir ciertos detalles a lo ya implementado). Si se intenta hacer la segunda parte sin acabar la primera, el ejercicio resultará mucho más difícil de realizar. Paso 1. Introducción (Primera Parte) El juego consiste en una serie de letras que van cayendo desde la parte superior de la pantalla. El alumno tendrá que pulsar la tecla correspondiente de cada letra antes de que esta toque la línea límite dibujada en la parte inferior de la pantalla. En la Figura 1 se muestra una imagen de la ventana de la aplicación que hay que realizar en la primera parte. Se aconseja a los alumnos que practiquen con el fichero Meca_1.exe que se les proporciona. Hay que ejecutarlo las veces que haga falta hasta que se esté seguro de saber que tiene que hacer el programa. Eso significa jugar con la aplicación probando todos los posibles casos. Figura 1. Ventana de Meca_1 Cuando el alumno se haya familiarizado con el funcionamiento del programa, debería abrir el Visual Basic y crear un proyecto Meca.vsp. Se recomienda encarecidamente que cada vez que el alumno consiga algo nuevo (creación de la interfaz, conseguir que se mueva la letra, etc), haga una copia de seguridad en otro directorio. El ejercicio puede parecer complicado si se trata de abordar en su conjunto sin tener una idea clara de los pasos a seguir. Para evitar este problema se van a enumerar una serie de pasos que facilitan la resolución del ejercicio. Evidentemente no es imprescindible seguirlos, pero es la manera más rápida y más directa de hacerlo, porque tiene separados todos los problemas que presenta el ejercicio. Esto hace que en cada paso haya que solventar problemas muy sencillos. Además se debe tener en cuenta que el criterio de corrección está basado en estos pasos. Examen Curso 2001-2002. Convocatoria de Febrero Página 2 Paso 2. Creación de la interfaz gráfica En este apartado el alumno SÓLO tiene que preocuparse de conseguir una interfaz gráfica con el mismo aspecto que la dada en la Figura 1 (no hace falta programar todavía ningún evento). Los elementos de los que consta son los siguientes: - Un pictureBox en el que se dibujarán las letras y la línea que representa el límite. Las letras hay que representarlas como labels en las que se modifica el campo Caption para poner la letra que nos interesa. - Dos cajas de texto indicando cuántas letras se han pulsado correctamente y cuáles se han pulsado incorrectamente. - Otra caja de texto en la que hay que ir poniendo las letras que han llegado a la línea del límite permitido. - Varios etiquetas explicando el significado de cada caja de texto. - Tres botones: uno para empezar/parar, otro para resetear el juego y que todo vuelva al inicio, y otro para salir de la aplicación. - Por supuesto para conseguir el movimiento de las letras hace falta un timer. Paso 3. Inicialización En este paso hay que empezar a inicializar ciertos objetos. Lo principal que tiene que conseguir el alumno es poder mover la letra. De momento sin ninguna lógica, simplemente que se mueva en la dirección correcta. Para conseguir esto hay que inicializar antes ciertos controles: - El pictureBox hay que escalarlo desde el código y las coordenadas irán desde el (0, 0) hasta el (100, 100) - El intervalo del timer será de 200 milisegundos. A continuación sólo queda mover la letra (usar un valor de 2 unidades para ir incrementado la posición). Antes de pasar a los siguientes apartados el alumno debería haber conseguido esto último. Es mejor realizarlo ahora cuando el ejercicio acaba de comenzar. Para simplificar el juego sólo se va a tener en cuenta la segunda fila de letras del teclado (que va desde la ‘A’ hasta la ‘Ñ’). Para ir cambiando de letras a lo largo del juego, el alumno tiene que crear un vector de Strings de 10 elementos en el que en cada posición se guardará una letra distinta (más adelante se usará este vector para ir sacando aleatoriamente las letras). Este vector tiene que ser declarado de forma global, pero la inicialización irá en el Load() del formulario (como el resto de inicializaciones). Dim letras(10) as String Vector de letras ! 0 1 2 A S D 9 ------- Ñ Examen Curso 2001-2002. Convocatoria de Febrero Página 3 Paso 4. Botones Aquí se describe la funcionalidad de los botones: - Start/End: este botón simplemente activará o parará el timer del juego. Hay que tener en cuenta que el texto del botón también cambia según esté parado o no el juego. IMPORTANTE: Para que se pueda detectar las letras pulsadas, hay que poner el foco en el objeto pictureBox. - Salir: terminar la aplicación. - Reset: empezar de nuevo el juego. Esto implica poner a 0 las cajas de texto que llevan los contadores, poner el timer otra vez a 200 ms y llamar a una función que calcule una nueva posición para la letra. Esta función nuevaLetra() tiene que posicionar la letra otra vez en la parte superior del pictureBox. La coordenada ‘Y’ la conocemos gracias al margen del pictureBox pero la coordenada ‘X’ hay que sacarla aleatoriamente (para que la letra no salga siempre en la misma posición). Sabiendo que el pictureBox mide 100 y la función Rnd() te devuelve un número aleatorio entre 0 y 1, se puede calcular la nueva coordenada ‘X’ (hay que tener en cuenta la anchura del label de la letra). IMPORTANTE: siempre que se use Rnd(), en la línea anterior hay que poner la instrucción Randomize. Esto último sirve para posicionar la letra en la parte superior pero además hay que conseguir que salga una letra aleatoria cada vez. Para eso se tiene el vector de letras que se creo en la inicialización. Esta vez basta con sacar un número aleatorio entre 0 y 9 y acceder al vector creado (en el que se guardan letras). Paso 5. Detección de la línea límite Cada vez que se mueve la letra hay que mirar a ver si ha alcanzado la línea límite. Para eso habrá que hacer una función detectLine() en la cuál se compara la posición de la letra con la coordenada ‘Y’ de la recta. Si se detecta impacto, entonces hay que incrementar la caja de texto que lleva la cuenta de oportunidades. El juego sólo tiene 3 oportunidades, por lo que si se detecta que han ocurrido 3 impactos hay que parar el juego y sacar unos mensajes por pantalla (mirar el fichero Meca_1.exe para ver los mensajes). Para calcular el porcentaje se puede hacer fácilmente con la información de las cajas de texto. Paso 6. Control del Timer El juego tiene nivel de dificultad, así que cada 5 segundos hay que acelerar la velocidad del juego. Para ello se usará un segundo timer el cual tendrá que ser inicializado a 5000 milisegundos. Para acelerar el juego, sólo habrá que decrementar el timer de movimiento en el evento de este segundo timer. Por ejemplo, decrementar en 20 milisegundos el timer del movimiento. Cuidado con que el timer del movimiento no llegue a 0 porque en ese caso el juego se pararía, para arreglarlo se puede dejar de decrementar cuando el timer llegue a un valor mínimo de 20. Paso 7. Eventos del teclado Para terminar de desarrollar el juego sólo queda por gestionar los eventos del teclado que serán los que detecten si se ha pulsado la tecla correcta.. Sólo hace falta programar un evento: el de KeyPress correspondiente al pictureBox (como se ha dicho anteriormente, para que funcione se ha tenido que poner el foco en el pictureBox al pulsar el botón Start). Examen Curso 2001-2002. Convocatoria de Febrero - Página 4 KeyPress: con este evento hay que testear si la tecla que se ha pulsado corresponde con la letra que está moviéndose por la pantalla en ese momento. Si corresponde hay que incrementar el número de aciertos y llamar a la función nuevaLetra() y si se falla en la tecla entonces habrá que incrementar el número de fallos. La dificultad aquí está en saber EL CÓDIGO de la letra que se está moviendo en ese momento por la pantalla. Si se averigua ese código, se puede comparar con el código de la letra pulsada que lo sabemos gracias al argumento del evento. Para solucionar esto hay que recordar que en la inicialización el alumno ha tenido que crear un vector que contiene 10 letras (cada posición es una letra). Ahora se podría crear un segundo vector de 10 elementos pero en esta ocasión se va a guardar en cada posición el código ascii de esas mismas letras. El esquema será el siguiente: Vector de letras ! Vector de códigos ! 0 1 2 A S D 1 2 0 Cod_A Cod_S Cod_D 9 ------- Ñ 9 ------- Cod_Ñ Con estos dos vectores construidos es fácil gestionar el problema del evento del teclado. Como se recuerda, en la función nuevaLetra() se calculaba un índice aleatorio (entre 0 y 9) para coger una letra del vector de letras. Basta con que se guarde ese índice en una variable global, de este modo cuándo suceda el evento del teclado se puede acceder al vector de códigos gracias a este índice. Para dar valores al vector de códigos (al igual que al vector de letras) se hace en la inicialización. Los códigos a introducir son los siguientes: a ! 97 g ! 103 l ! 108 s ! 115 h ! 104 ñ ! 241 d ! 100 j ! 106 f ! 102 k ! 107 IMPORTANTE: estos códigos corresponden a las letras minúsculas así que hay que tener cuidado de NO tener activado el bloque de mayúsculas mientras se juega ya que no funcionará en ese caso. Examen Curso 2001-2002. Convocatoria de Febrero Página 5 Paso 8. Introducción (Segunda Parte) Si el alumno ha conseguido realizar todo lo que se pedía en la primera parte, entonces está en condiciones de hacer esta segunda parte que no es más que una ampliación del juego para que aparezcan más letras. Tal y como aparece en la Figura 2, el aspecto de la interfaz es el mismo salvo que en lugar de una letra, ahora aparecen tres letras. Figura 2. Ventana de Meca_2 Para ver cómo funciona el programa, el alumno puede ejecutar el archivo Meca_2.exe que se facilita. Como se puede comprobar rápidamente, el funcionamiento es exactamente el mismo pero con tres letras. Entonces, lo que antes se hacía con un solo label (por ejemplo la función detectLine()) ahora hay que hacerlo para los tres labels. De todas formas, no todo es tan simple como copiar tres veces lo que ya se hacía antes. Aquí se dan unas pistas para orientar al alumno hacia una posible solución (se puede hacer con matriz de controles o con controles independientes, a elección del alumno): - La función nuevaLetra() cambia un poco y ahora necesita un argumento de entrada en el que se le indica la letra (1, 2 ó 3) que hay que cambiar de posición. nuevaLetra (numero As Integer) - Ahora cuándo se pulse una tecla, el evento del teclado tiene que mirar las tres letras que se están moviendo. Si antes era necesario llevar una variable global que guardaba el índice del vector de letras (para saber que letra estaba moviéndose), ahora será necesario llevar 3 variables índices (una para cada letra que se está moviendo).