Hace mucho tiempo dadas unas circustancias en las que quedé atrapado unas horas delante de un Windows XP, sin internet, y con sólo Microsoft Office instalado, terminé programando el videojuego Arkanoid en una hoja de cálculo de Microsoft Excel. Parafraseando a Arquímedes “Dadme un punto de apoyo y moveré el mundo», a mi me dieron un «XP» y sólo me alcanzó para mover mi propio videojuego. Lo cierto es que de esta pequeña prueba de concepto que realicé en tan sólo unas horas, se pueden extraer muchas conclusiones para aprender lo más básico en la programación de videojuegos. Y no es que haya programado muchos, tan sólo un par, pero la mecánica es la misma una vez aprendes.
La idea que me pasó por la cabeza fue utilizar las celdas de la hoja de cálculo de Excel como si se tratasen de píxeles y luego con la función de macros, que traen todos los programas de Microsoft Office, desarrollar el videojuego en sí. El lenguaje de programación para desarrollar las macros es Visual Basic.
El juego se puede descargar de este enlace.
Para jugar primero hay que habilitar la macro que ejecuta el juego desde el botón «Habilitar contenido» que se muestra en la imagen de debajo y para iniciar una nueva partida únicamente hay que ir a la Hoja 2 y volver a la Hoja 1. Mover con las flechas de dirección.
El juego lo programe en el año 2009 y como curiosidad llamé a la macro «Tetris» en vez de «Arkanoid», en un principio no sabía ni lo que iba a salir. Para entrar a destripar el código hay que ir en Microsoft Excel a la pestaña Vista, a continuación Macros y por último Ver Macros. Ahí aparece la macro «Tetris».
A partir de aquí voy a entrar a explicar el código fuente del juego, tan sólo ocupa 166 líneas de código así que es sencillo de analizar. Si no sabes programar no entenderás nada, si sabes programar el resto del código está en el enlace de descarga anterior. Continúa leyendo con el código en la mano y no tendrás problema en entender la explicación.
En primer lugar las declaraciones globales:
Option Explicit Private Declare Function GetTickCount& Lib "kernel32" () Private Declare Function GetAsyncKeyState Lib "user32" (ByVal vKey As Long) As Integer Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long) Public iTmpActual As Long, iTmpUltimo As Long Public bResult As Boolean, bPruebaFila As Boolean, bPruebaColumna As Boolean Public bSalir As Boolean
- Option Explicit para forzar la declaración de variables correctamente.
- Declaramos GetTickCount& de la API de Windows para controlar los tiempos en el juego.
- GetAsyncKeyState para recoger el estado de las teclas y poder mover el jugador.
- Sleep para ralentizar el juego.
A continuación unas variables publicas para controlar los tiempos y algunos indicadores para controlar lo que sucede en el juego.
La función principal del juego:
Sub Tetris() ' ' ' Macro grabada el 02/06/2009 por Alberto ' ' ComenzarJuego TemporizadorCrear While Not bSalir TemporizadorActualizado Debug.Print GetAsyncKeyState(&H14B) TemporizadorActivado bResult If bResult Then LeerTeclado Dibujar TemporizadorIncrementar Else TemporizadorEsperar End If Wend FinJuego bSalir = False End Sub
El cuerpo del videojuego similar a todos.
Las primeras funciones ComenzarJuego dibuja el escenario y TemporizadorCrear inicializa la variable iTmpUltimo con la cantidad de milisegundos que han pasado desde que se inició el sistema. Sirve para tener una referencia temporal.
A continuación entramos en un bucle mientras no se active la variable bSalir que hemos definido anteriormente. Esta variable únicamente se activará cuando maten al jugador.
Dentro del bucle lo primero que hacemos es llamar a TemporizadorActualizado que inicializa iTmpActual de la misma manera que iTmpUltimo.
La siguiente acción a realizar es comprobar cuánto tiempo ha pasado desde que comenzó el juego, esto se hace en TemporizadorActivado. En este caso se compara iTmpActual – iTmpUltimo y si es mayor a los 25 milisegundos el juego continuará, sino esperaremos (TemporizadorEsperar).
Seguimos en el bucle, si han pasado los 25 milisegundos que tarda en refrescarse el juego… pues vamos a jugar.
LeerTeclado recoge el estado del teclado y mueve al jugador a derecha o a izquierda según se pulse.
Acto seguido se llama a la función Dibujar que hace mover la bola aleatoriamente siempre dentro del rectángulo de juego.
Y por último se llama a TemporizadorIncrementar para que el juego continúe.
En caso de que no hayan transcurrido los 25 milisegundos de rigor para que el juego vaya a una velocidad humanamente jugable está la función TemporizadorEsperar que lo que hace es dormir la aplicación hasta que se cumplan los 25 milisegundos.
Por último cuando se activa la variable bSalir, cuando la bola toca la fila 49, se termina el juego llamando a la función FinJuego que dibuja un «Game Over» en pantalla.
Sencillo, ¿no?. Para dibujar únicamente se llama a funciones de Excel como Range(«Posición de la celda») y todas las opciones que brinda, colorear, cambiar el tamaño, seleccionar, etc. Con ActiveCell hacemos lo mismo con la celda activa y ya lo demás sólo es cuadrar filas y columnas haciendo números. De aquí a programar juegos en 2D sólo hay un paso, cambiar las celdas por librerías gráficas. En una próxima entrada explicaré como programar videojuegos en 2D desde un ejemplo que realicé.