¡Vamos a crear el juego Mole Mash para Desktop en menos de una hora! Todo lo que necesitamos es:
- Crear una nueva Clase Mole (Topo). Esta clase estará a cargo de animar la secuencia de nuestro personaje topo emergiendo de la tierra, reaccionar ante los clic realizados por el jugador sobre el personaje, y también de notificar al observador interesado de cuando se ha hecho clic sobre él, siempre y cuando sea sobre el fotograma de animación correcto.
Así, y en el caso de nuestro juego, añadirá 10 puntos al marcador cuando se haya hecho clic sobre el fotograma correcto, mientras que restará 10 puntos cuando se haga clic en un fotograma erróneo de la animación (piensa en estos fotogramas como el momento preciso en el que puedes “golpear” al Topo).
- Crear una Clase GameCoordinator. Esta clase estará a cargo de seleccionar la nueva posición en el escenario para que aparezca nuestro personaje (el Topo), y también de recibir las notificaciones cuando se haya hecho clic sobre el personaje, de modo que pueda modificar el marcador y seleccionar una nueva posición para el Topo (esto es, una nueva iteración del juego).
El Escenario. Esta es la tarea más sencilla, dado que todo lo que necesitamos es asignar la imagen a mostrar como el fondo perfecto para que aparezca nuestro topo. Tendrá un tamaño fijo; de hecho, el mismo ancho y altura de la ventana que lo contiene.
Puedes crear tus propios gráficos para el juego (archivos PNG), tanto para el personaje de Topo y el fondo… o bien descargar los originales utilizados en este tutorial desde este enlace.
Una vez que ya sabemos cuáles son todas las piezas necesarias… ¡vamos a empezar!
Nota: Puedes descargar tanto el Proyecto como el resto de archivos relacionados desde este enlace.
1. Crear el Escenario
Abre Xojo en el caso de que aun no lo tengas abierto, y selecciona Desktop desde el Selector de Proyectos. Escribe “Mole Mash” como el nombre de la aplicación (Application Name). Puedes dejar el resto de los campos con sus valores por omisión.
Con el elemento Window1 seleccionado en el Navegador de Proyectos (el panel situado más a la izquierda en el IDE de Xojo), haz clic en el botón Inspector para acceder a sus propiedades. Aquí es donde cambiaremos el título de la ventana, el tamaño de la ventana y también el nombre del elemento:
- Name: MoleWindow. Este es el nombre que utilizaremos desde nuestro código para referirnos a este elemento del proyecto (u objeto).
- Width, Height, Minimum Width, Minimum Height, Maximum Width, Maximum Height. La ventana del juego tendrá una resolución fija de 640 x 640 píxeles; esto es, la misma resolución de la imagen PNG que utilizaremos como fondo . Por tanto, indica “640” como el valor para todas estas propiedades.
- Title. Este es el texto mostrado en la barra de título de la ventana. Escribe “Mole Mash”.
2. Añadir el Fondo
Selecciona File > Import para añadir un nuevo archivo al proyecto Mole Mash y selecciona la imagen que quieras utilizar como fondo para el escenario del juego (asegúrate de que tenga una resolución de 640 x 640 píxeles). Si has descargado los materiales originales del tutorial, este se corresponde con el archivo background.
Una vez que se ha añadido la imagen al proyecto, selecciona MoleWindow desde el Navegador de Proyecto para acceder al Editor de Diseño (Layout Editor). A continuación, haz clic en el icon Librería (Library) para acceder a todos los controles de Interfaz de Usuario (UI) incluidos de serie en el Framework de Xojo.
Uno de estos controles es el Canvas, este te permitirá seleccionar cualquier imagen importada al proyecto para mostrarla sobre la superficie del control, y también te permitirá hacer cosas más interesantes, como por ejemplo crear tus propios controles de UI ¡o dibujar cualquier cosa que necesites!
Arrastra el Canvas desde la Librería y suéltalo en el Editor de Diseño. Observarás que se ha añadido un nuevo elemento al Navegador de Proyecto con el nombre por omisión de Canvas1, y situado bajo la jerarquía Controls del objeto MoleWindow.
Con el Canvas1 aun seleccionado en el Editor de Diseño, accede al Panel Inspector y cambia las siguientes Propiedades:
- Name: BackgroundCanvas.
- Left: 0.
- Top: 0.
- Width: 640.
- Height: 640.
- Locking: Haz clic sobre los cuatro pequeños iconos de candado para que todos estén cerrados.
- Backdrop: Selecciona la entrada background importada anteriormente al proyecto en el menú desplegable.
En este punto, la ventana MoleWindow debería tener el siguiente aspecto:
3. Crear la Clase Mole
Con el escenario del juego ya creado vamos a centrarnos ahora en crear la principal pieza de código para nuestro proyecto: el personaje Topo (Mole).
Este necesitará encargarse de animarse a sí mismo (la secuencia de fotogramas correspondientes al topo emergiendo de un agujero en la tierra… y de esconderse otra vez en el caso de que no haya sido golpeado por el jugador). También necesita detectar si el jugador hace clic sobre él en el punto indicado de la animación, y de enviar notificaciones cuando el jugador lo haga, ya sea de forma correcta o en el punto de animación incorrecto (golpear al topo en la posición errónea… o bien permitiendo que se vuelva a esconder por completo).
Y dado que el topo necesita tomar el control de sí mismo y de su estado… esto es algo que haremos creando una nueva Clase.
Por tanto, selecciona Insert > Class en el menú principal del IDE o bien desde el elemento Insert en la barra de herramientas del IDE de Xojo. Como resultado de esta acción se añadirá el elemento Class1 al Navegador de Proyecto.
Como puedes ver, el item Class1 queda seleccionado automáticamente en el Navegador de Proyecto proporcionando acceso al Panel Inspector asociado. Cambia las siguientes propiedades:
- Name: Mole
- Super: Canvas
Cambiar el campo Super del Canvas significa que nuestra clase Mole es una subclase de la clase Canvas, de modo que tendrá acceso y podrá utilizar todas las capacidades disponibles en la clase Canvas propiamente dicha. Después de todo, nuestra clase Mole necesita dibujar una secuencia de imágenes para crear la animación del personaje… y ya sabemos que el Canvas es el tipo de control que nos permite hacerlo (entre otras cosas).
A continuación, y dado que estaremos utilizando Timers para un par de cosas (la animación del Topo y también retrasar ligeramente la notificación del golpeo), nuestra clase Mole también necesita implementar una de las múltiples Interfaces de Clase disponibles en el Framework de Xojo.
Haz clic en el botón Choose… asociado con el campo Interfaces en el Panel Inspector, selecciona la entrada actionNotificationReceiver y confirma la selección haciendo clic en el botón OK.
Como resultado de la anterior acción se habrá añadido el método PerformAction a la Clase Mole. Dejemos esto por ahora.
4. Añadir los fotogramas de animación del Topo
Añadamos ahora todos los fotogramas correspondientes a la animación del topo, y también la imagen que mostrará nuestra clase Mole cuando el personaje haya sido golpeado.
El modo más rápido de hacerlo es seleccionado los siguientes archivos de tu disco (en el caso de que vayas a utilizar los materiales originales descargados con el enlace indicado anteriormente), o bien los archivos de tus propias imágenes en el caso de que hayas decidido utilizar tus propios dibujos. A continuación, arrástralos directamente desde el Finder al Navegador de Proyectos en la ventana del IDE de Xojo:
- Imágenes del Topo: Mole1, Mole2, Mole3, MoleA, MoleB, MoleC, MoleD, MoleSMASH
Otra opción consiste en importarlos uno a uno utilizando la opción File > Import disponible en el menú del IDE de Xojo.
Consejo: Siempre es buena idea mantener los elementos de tu proyecto bien organizados en el Navegador de Proyecto mediante el uso de Carpetas. Puedes añadir nuevas Carpetas (y cambiar sus nombres para que representen correctamente sus contenidos) utilizando la opción Insert > Folder.
Una vez hayas importado todos los archivos, y si has decidido mantenerlos organizados como parte de la clase Mole a la que pertenecen, utilizando para ello una Carpeta, el Navegador de Proyecto tendrá un aspecto similar al siguiente en este punto:
5. Añadir Propiedades a la Clase Mole
Las Propiedades son el mecanismo en OOP para que los objetos creados a partir de una clase puedan gestionar su estado, y nuestra clase Mole necesita ser consciente de un buen montón de cosas sobre sí misma. Por tanto, añadamos ahora las propiedades que necesitaremos para mantener el estado de nuestro Topo.
Asegúrate de que el item Mole esté seleccionado en el Navegador de Proyecto y selecciona Insert > Property. Como resultado de esta acción, la propiedad “Untitled” se añadirá bajo la sección Properties de la clase Mole en el Navegador de Proyecto, proporcionando así acceso al Panel Inspector asociado.
Con la propiedad Untitled aun seleccionada en el Navegador de Proyecto, utiliza los siguientes datos en el Panel Inspector asociado:
- Name: Animator.
- Type: Timer.
- Scope: Private.
La propiedad Animator estará a cargo de almacenar el objeto Timer a cargo de animar el personaje, cambiando el fotograma mostrado con la frecuencia indicada en el propio timer.
Consejo: Puedes aprender más sobre la clase Timer, como crearlos y utilizarlos, con este tutorial.
Repite la operación para añadir nuevas propiedades con los siguientes valores:
- Name: Increment.
- Type: Integer.
- Default: 1.
- Scope: Private.
La propiedad Increment tendrá unos valores de +1 y -1 para incrementar/decrementar la secuencia del fotograma mostrado.
- Name: MoleSequence().
- Type: Picture.
- Scope: Private.
El Array MoleSequence almacenará, en orden ascendente, las referencias a las imágenes (Pictures) que utilizaremos en la animación del Topo.
- Name: MoleSmashed
- Type: Boolean
- Scope: Private
La propiedad Booleana MoleSmashed almacenará el valor True en el caso de que se haya golpeado al Topo en el fotograma correcto, o bien False en caso contrario.
- Name: Offset
- Type: Integer
- Scope: Private
La propiedad Offset almacenará la posición del fotograma actual (o índice) de la animación.
- Name: Smashed
- Type: Picture
- Scope: Private
La propiedad Smashed almacenará una referencia a la imagen (Picture) que se mostrará cuando se haya golpeado al topo.
- Name: Speed
- Type: Integer
- Scope: Public
La propiedad Speed almacenará la frecuencia de animación del Topo (velocidad). Es decir, el intervalo con el que se dispara la acción asociada con el Timer.
- Name: Target
- Type: MoleDelegate
- Scope: Public
La propiedad Target almacenará una referencia al objeto al que se notificará cada vez que el jugador golpee al topo… ¡o falle! Como puedes ver, estamos usando MoleDelegate como el tipo de dato para esta propiedad, una que no existe en el Framework de Xojo. No te importe por ahora, la añadiremos a nuestra clase un poco más adelante.
Aun necesitamos convertir nuestras propiedades Speed y Target de propiedades normales a Computed Properties (Propiedades Calculadas), lo que significa que cada una de ellas tendrá su propio par de métodos Getter y Setter. Esto significa que tendremos oportunidad de modificar el valor recibido antes de asignarlo a la propiedad propiamente dicha o bien al devolverlo.
Por tanto, con las propiedades Speed y Target seleccionadas en el Navegador de Proyecto, accede al menú contextual y selecciona la opción Convert to Computed Property.
Selecciona el método Set asociado con la propiedad Speed y escribe el siguiente código en el Editor de Código asociado:
If value < 50 Then value = 300 mSpeed = value If Animator <> Nil Then Animator.Period = value
De forma resumida, cada vez que la aplicación asigne un nuevo valor a esta propiedad el método Set comprobará si el valor recibido es inferior a 50 y, en ese caso, ajustará el valor a 300 como el mínimo para la frecuencia de animación. Adicionalmente, también ajustará la propiedad Animator (Timer) al nuevo valor de modo que la frecuencia de animación del Topo cambiará en consecuencia.
6. Añadir un Tipo Delegado a la Clase Mole
Vamos a encargarnos ahora del tipo de dato MoleDelegate. ¡De hecho necesitaremos añadir un Delegado a la clase!
De forma resumida, un tipo de dato Delegate almacenará una referencia a la signatura de un método o función, y eso significa que podrá almacenar la dirección de memoria de cualquier método o función que deseemos… siempre y cuando su signatura (número y tipo de parámetros recibidos y, opcionalmente, tipo de dato devuelto), coincida con la definida para el tipo de Delegado.
La principal virtud y flexibilidad de esta técnica reside en que podremos Invocar la función original almacenada por el tipo de dato Delegado en cualquier punto durante la ejecución de la aplicación.
Consejo: Puedes saber más sobre cómo se usan los Delegados a través de este Tutorial, y la Documentación de Xojo.
Con la clase Mole aun seleccionada en el Navegador de Proyecto, selecciona Insert > Delegate usando a continuación los siguientes valores en el Panel Inspector asociado:
- Delegate Name: MoleDelegate
- Parameters: Status as MoleStatus
- Scope: Public
Nuevamente, estamos utilizando aquí el tipo de dato MoleStatus no disponible por omisión en el framework de Xojo, para el parámetro Status en la signatura de método para nuestro Delegado. Nos encargaremos de esto en el siguiente paso.
7. Añadir una Enumeración a la Clase Mole
Las enumeraciones son un mecanismo realmente útil del lenguaje para reducir los valores válidos para una acción, propiedad de estado, parámetro, etc. En nuestra clase Mole añadiremos una Enumeración para representar dos posibles estados para el “golpe”: Hitted y Failed. De este modo, podemos pasar dicho estado cuando enviemos la notificación a nuestro objeto Target, de modo que pueda ejecutar las líneas de código adecuadas para cualquiera de los posibles valores de la enumeración.
Con la clase Mole aun seleccionada en el Navegador de Proyecto, selecciona Insert > Enumeration utilizando los siguientes valores en el Panel Inspector:
- Name: MoleStatus.
- Type: Integer.
- Scope: Public.
Y añade los siguientes valores en el Enumeration Editor asociado (haz clic en el botón “+” en el Editor de Enumeraciones para añadir un nuevo valor de enumeración):
- Hitted
- Failed
8. Implementar el Método Constructor en la Clase Mole
Hemos terminado de añadir todas las partes involucradas en el estado de la clase Mole: Propiedades, Delegados y Enumeraciones. Ahora es el momento de añadir un método muy especial a la clase: el Constructor.
Este es el primer método que se ejecuta cada vez que se crea un nuevo objeto a partir de la clase, de modo que es un buen lugar para inicializar el estado del objeto y asignar todos los valores que pueda necesitar para que funcione correctamente.
Con la clase Mole aun seleccionada en el Navegador de Proyecto, selecciona Insert > Method utilizando los siguientes datos en el Panel Inspector asociado:
- Name: Constructor
- Scope: Public
Y escribe las siguientes líneas de código en el Editor de Código asociado con el método:
MoleSequence.AddRow mole1 MoleSequence.AddRow mole2 MoleSequence.AddRow mole3 MoleSequence.AddRow mole4 MoleSequence.AddRow moleA MoleSequence.addrow MoleB MoleSequence.AddRow MoleC MoleSequence.addrow MoleD Smashed = MoleSMASH animator = New timer animator.Period = mSpeed animator.addActionNotificationReceiver Me animator.Enabled = True animator.RunMode = timer.RunModes.Multiple
Como puedes ver, todo lo que hacemos es añadir todas las imágenes que vamos a utilizar en la animación, en orden, al array MoleSequence, así como la imagen correspondiente a la propiedad Smashed.
También utilizamos el método Constructor para crear una nueva instancia de la clase Timer y asignarla a la propiedad Animator, ajustando el periodo de disparo para el Timer al valor almacenado en la propiedad Speed (es decir, la frecuencia con la que se actualizarán los fotogramas de la animación), así como el destino que se invocará cada vez que se dispare el temporizador; siendo este la propia clase Mole mediante la línea:
Animator.addActionNotificationReceiver Me
Esto significa que el método PerformAction ejecutará su código cada vez que se dispare el temporizador con el intervalo almacenado en la propiedad Speed. Recuerda que este es el método que se ha añadido a nuestra clase porque hemos incorporado la Interfaz de Clase ActionNotificationReceiver como parte del tercer paso del tutorial.
Por tanto, selecciona el método PerformAction en la clase Mole y añade la siguiente línea de código en el Editor de Código asociado:
Me.Invalidate
Este es el modo en el que indicamos a cualquier objeto basado en Canvas que actualice el contenido mostrado, algo que realizamos a través del Evento Paint disponible para la clase Canvas o cualquier clase basada en Canvas… como es el caso de nuestra clase Mole.
Por tanto, implementa el Evento Paint en la clase Mole para que realicemos nuestro dibujado personalizado (en este caso, animando la secuencia del topo).
9. Animar el Topo mediante el evento Paint
Con la clase Mole aun seleccionada, elige la opción Insert > Event. Selecciona la entrada Paint en el listado y haz clic sobre el botón Ok para confirmar.
Se añadirá el Evento Paint a la clase Mole mostrando el Editor de Código asociado. Escribe las siguientes líneas de código:
If Not MoleSmashed Then g.drawPicture( MoleSequence(Offset),0,0,g.Width,g.Height ) Offset = Offset + Increment If Offset > MoleSequence.LastRowIndex Then Increment = -Increment Offset = MoleSequence.LastRowIndex Elseif Offset = -1 Then Increment = -Increment Offset = 0 End If Else g.drawPicture( Smashed,0,0,g.Width,g.Height ) End If
De forma resumida, el código se encarga de dibujar la próxima secuencia de la animación para el personaje topo en el caso de que aun no haya sido “golpeado”, y de mostrar la imagen Smashed en el caso de que haya sido golpeado en el fotograma correcto.
El código también comprueba si se ha alcanzado el último fotograma de la animación o bien el primero, cambiando el signo del incremento en consecuencia según el caso.
Consejo: Con esta implementación del evento Paint necesitarás asegurarte de que todas las instancias creadas a partir de la clase Mole tengan los mismos valores de Ancho y Altura que la resolución de las imágenes utilizadas para la animación (128 x 128 píxeles, en el caso de que se utilicen las proporcionadas junto con este tutorial). Si quieres que sea más flexible, sólo tienes que añadir al proyecto un nuevo Módulo con la Extensión de Clase CenterPicture explicada en este tutorial.
Si decides hacerlo, cambia las dos líneas g.DrawPicture del código en el Evento Paint a:
g.CenterPicture( MoleSequence(Offset) )
Y
g.CenterPicture( Smashed )
Respectivamente.
10. Probando la Clase Mole
Comprobemos si la animación del topo funciona como esperamos. Selecciona el item MoleWindow en el Navegador de Proyecto para que aparezca en el Editor de Diseño. A continuación, arrastra la clase Mole desde el Navegador de Proyecto y suéltalo dentro de MoleWindow en el Editor de Diseño. Como resultado se creará una nueva instancia Mole1 que se añadirá bajo la sección Controls de MoleWindow en el Navegador de Proyecto.
Con el control Mole1 seleccionado en el Editor de Diseño, cambia los siguientes valores utilizando el Panel Inspector:
- Name: MoleItem.
- Width: 128.
- Height: 128.
A continuación, haz clic en el botón Run de la barra de herramientas del IDE… y verás como el topo se anima a sí mismo en ambas direcciones. Pero aun tenemos trabajo por hacer. Por ejemplo, no ocurre nada si haces clic sobre el topo… además de que siempre está en la misma posición.
11. Detectar “clics” en el Topo
Para que los objetos creados a partir de nuestra clase Mole puedan detectar cuando el usuario hace clic sobre ellos, has de añadir un nuevo Evento: MouseDown.
Con la clase Mole seleccionada en el Navegador de Proyecto, selecciona Insert > EventHandler… y selecciona MouseDown en el listado de eventos. Confirma la selección haciendo clic en el botón “OK”. Como resultado se añadirá el Manejador de Evento MouseDown a la clase Mole. Escribe la siguientes líneas de código en el Editor de Código asociado:
If Offset = MoleSequence.LastRowIndex Then If Animator <> Nil Then Animator.Enabled = False MoleSMASHed = True Me.Invalidate timer.CallLater(1000, WeakAddressOf MoleCrushed, MoleStatus.Hitted) Else timer.CallLater(1000, WeakAddressOf MoleCrushed, MoleStatus.failed) End If
En resumen, comprueba si el jugador ha hecho clic sobre el topo cuando está mostrando el último fotograma. En ese caso se considera un “golpeo” válido y desactiva el objeto Timer a cargo de animar el topo, ajustando la propiedad MoleSmashed a True y forzando el dibujado de modo que muestre la imagen adecuada.
La línea de código interesante en este caso es:
timer.CallLater(1000, WeakAddressOf MoleCrushed, MoleStatus.Hitted)
Este es otro modo en el que puedes utilizar los Timer. En este caso se trata de un temporizador retardado que dispara su acción tras el periodo de tiempo (expresado en milisegundos) indicado como primer parámetro al método compartido CallLater.
El segundo parámetro es el método que se invocará, y el tercero es el parámetro que queremos pasar asociado al método invocado.
Si por el contrario el jugador ha hecho clic sobre el topo cuando este aun no mostraba el último fotograma… entonces se considera un “golpeo” fallido. En este caso también utilizamos el temporizador retardado, llamando al mismo método pero pasando como parámetro el valor enumerador MoleStatus.Failed).
Dado que en ambos casos el Timer llamará al método MoleCrushed, necesitamos implementarlo en nuestra clase.
Por tanto, y con la clase Mole aun seleccionada, elige la opción Insert > Method utilizando los siguientes valores en el Panel Inspector asociado:
- Method Name: MoleCrushed
- Parameters: status as Variant
- Scope: Private
Y escribiendo las siguientes líneas de código en el Editor de Código asociado con el método:
MoleSmashed = False If Target <> Nil Then Target.Invoke(status)
Como puedes ver, aquí es donde el objeto topo notificará a su target pasando el mismo valor recibido. (Recuerda que la propiedad Target contiene una referencia al método MoleDelegate, de modo que utilizamos Invoke para llamarlo).
¡Aun necesitamos añadir un par métodos más para completar nuestra clase Mole!
- Reset. Cuando se llama, este método “reiniciará” las propiedades de estado adecuadas para el objeto Mole.
- Destructor. Junto con el Constructor, este es otro método especial para cualquier clase. Este es el método que se llama para cualquier objeto cuando va a ser destruido (es decir, borrado de la memoria del ordenador). Utilizaremos este método para hacer algo de limpieza.
Por tanto, añade en primer lugar el método Reset utilizando los siguientes valores:
- Method Name: Reset
- Scope: Public
Y escribiendo las siguientes líneas de código en el Editor de Código asociado:
Increment = 1 Offset = 0 If Animator <> Nil Then Animator.Enabled = True Me.Invalidate
Y ahora el método Destructor con los siguientes valores:
- Method Name: Destructor
- Scope: Public
Y escribe las siguientes líneas de código en el Editor de Código asociado:
If Animator <> Nil Then Animator.removeActionNotificationReceiver Me End If
¡Hemos terminado de crear nuestra clase Mole!
12. Crear la Clase GameCoordinator
La clase Mole no sabe nada sobre el juego propiamente dicho. Sólo sabe como animarse a sí mismo y detectar si alguien ha hecho clic sobre él. Está claro que necesitamos “algo” que esté a cargo de establecer las reglas del juego. Por ejemplo, en este caso, estará a cargo de cambiar la posición del topo a una nueva… y también de cambiar los valores del Marcador según corresponda.
Para ello vamos a crear una clase GameCoordinator para el proyecto. Selecciona Insert > Class y utiliza los siguientes valores en el Panel Inspector asociado:
- Name: GameCoordinator.
A continuación, vamos a añadir algunas propiedades necesarias para que el GameCoordinator sea consciente de su estado:
- Property Name: ScoreTarget.
- Type: Label.
- Scope: Private.
Esta propiedad almacenará una referencia al control Label de interfaz de usuario, utilizada para mostrar el valor del Marcador.
- Property Name: ScoreValue.
- Type: Integer.
- Scope: Private.
Esta propiedad almacenará el valor actual del marcador en el juego.
- Property Name: GameArea.
- Type: Rect.
- Scope: Private.
Esta propiedad es un tipo de dato Rect con las coordenadas de origen y el tamaño del área de juego sobre la cual podrá aparecer el topo (no queremos que el topo aparezca en el área del cielo en la imagen utilizada como fondo).
- Property Name: MoleItem.
- Type: Mole.
- Scope: Private.
Esta propiedad almacena una referencia a la instancia Mole.
Selecciona ahora las propiedades GameArea y MoleItem y conviértelas a Propiedades Calculadas (Computed Properties).
A continuación, añadamos los métodos que nuestro GameCoordinator necesitará para funcionar:
- Method Name: Reset Game
- Scope: Protected
Y escribe las siguientes líneas de código en el Editor de Código asociado:
Var moleWidth As Integer = MoleItem.Width Var moleHeight As Integer = MoleItem.Height Var Rnd As New Random Var MolePosX As Integer = Rnd.InRange(mgamearea.Left, mGameArea.Width - moleWidth) Var MolePosY As Integer = Rnd.InRange(mgamearea.top, mGameArea.Height - moleHeight) MoleItem.Left = moleposx MoleItem.Top = MolePosY MoleItem.Reset MoleItem.Visible = True
Como puedes ver, este es el método a cargo de definir una nueva posición para la instancia del topo en el área jugable (Rect) de la MoleWindow.
- Method Name: Score
- Parameters: status as Mole.MoleStatus
- Scope: Public
Y escribe las siguientes líneas de código en el Editor de Código asociado:
If status = mole.MoleStatus.Hitted Then If MoleItem <> Nil Then MoleItem.Visible = False If ScoreTarget <> Nil Then ScoreValue = ScoreValue + 10 ScoreTarget.Value = scorevalue.tostring If ScoreValue Mod 100 = 0 Then MoleItem.Speed = MoleItem.Speed - 50 End If End If ResetGame Else ScoreValue = ScoreValue - 10 ScoreTarget.Value = ScoreValue.ToString End If
Este es el método que asignaremos como el Target para el objeto Mole, de modo que será invocado cada vez que el jugador “golpee” al topo.
Como puedes ver, comprueba el valor de estado recibido, de modo que incrementará el valor del Marcador (Score) si se trata de un “golpeo” legal, aumentando la velocidad del topo cada 100 puntos y seleccionando una nueva posición para que aparezca de nuevo. De lo contrario, reducirá la puntuación del marcador en 10 puntos en el caso de que se trate de un “golpeo” ilegal.
- Method Name: Start
- Parameters: Item as Mole, PlayArea as Rect, ScoreControl as Label
- Scope: Public
Y escribe las siguientes líneas de código en el Editor de Código asociado:
mMoleItem = Item mMoleItem.target = WeakAddressOf score ScoreTarget = ScoreControl ScoreTarget.Value = ScoreValue.ToString mGameArea = PlayArea resetGame
Como puedes ver, este es el método a cargo de iniciar el GameCoordinator (y, por tanto, el juego propiamente dicho). Recibe todo lo que puede necesitar el coordinador: un objeto Mole, las coordenadas y tamaño del área jugable, así como el control que utilizaremos para mostrar el valor del marcador.
¡Nuestra clase GameCoordinator está completa!
13. ¡Empieza el Juego!
Para añadir una nueva instancia de la clase GameCoordinator a la MoleWindow, selecciona el elemento MoleWindow en el Navegador de Proyecto y, a continuación, arrastra la clase GameCoordinator desde el Navegador de Proyecto sobre el área inferior (Tray) del Editor de Diseño.
Para completar nuestro juego, aun tenemos que hacer un par de cosas de modo que este pueda echar a rodar.
Selecciona el item MoleWindow en el Navegador de Proyecto y añádele el Manejador de Evento Open, escribiendo a continuación las siguientes líneas de código en el Editor de Código asociado:
Var r As New rect(0,220,background.Width,background.Height-100) GameCoordinator1.Start(MoleItem, r, scorelabel)
La primera línea de código crea una nueva instancia de la clase Rect describiendo el área jugable. A continuación, la segunda línea de código llama al método Start pasando todos los parámetros esperados: un objeto Mole, el rect describiendo el área jugable y el control de etiqueta ScoreLabel.
Ahora, selecciona MoleWindow para acceder al Editor de Diseño. A continuación, arrastra un control Label desde la Librería y suéltalo en la esquina superior derecha de la ventana. Utiliza el Panel Inspector para ajustar los siguientes valores sobre la etiqueta recién añadida:
- Name: ScoreLabel.
- Text Alignment: Right.
- Value: 0.
A continuación, haz clic en el icono con forma de rueda dentada en el Panel Inspector para ajustar algunos atributos de Font:
- Font: System, 30, Point
¡Eso es todo! Haz clic en el botón Run y comienza a jugar al juego Mole Mash!
Conclusión
En menos de una hora has podido crear un juego Desktop que puedes ejecutar en macOS, Windows y Linux, ¡creando tus propias clases!
Ahora es tu turno, y puedes mejorar la experiencia de juego. Por ejemplo, puedes decidir que cada clic sobre el topo sea considerado como válido… y no sólo el que coincida con el fotograma de la animación (pero en ese caso probablemente también querrás asegurarte de que el topo sea visible cuando el usuario haga clic, y no cuando la animación aun está mostrando los fotogramas en el que se abre o cierra el agujero sobre el terreno).
También puedes decidir que el marcador debería restar diez puntos cada vez que el topo se esconde sin que se haya hecho clic sobre él… o si el jugador alcanza un nivel determinado (medido en puntos, por ejemplo), entonces podrías considerar el mostrar más de un topo a la vez. Tienes la clase GameCoordinator para ello, donde puedes modificar y ampliar todo lo que necesites para cambiar las reglas del juego.