Crear un juego en 30 minutos con PyGame
Presentación de PyGame
PyGame es una librería de libre distribución que conecta la librería SDL a Python, cuyo objetivo es facilitar el desarrollo de videojuegos en tiempo real.
SDL son las siglas de Simple Direct media Layer y es una librería de referencia, escrita en C, que gestiona la representación de vídeo y de audio ofreciendo un sistema de gestión de eventos que incluye los eventos vinculados a dispositivos periféricos tales como teclados y ratones. Ofrece, a su vez, una gestión precisa del tiempo, indispensable cuando se está desarrollando aplicaciones en tiempo real, además de soporte a imágenes y tipos de letra.
La librería SDL es famosa por su fácil uso, permitiendo a los desarrolladores aplicar conceptos complejos sin apenas esfuerzo. Python aporta, a su vez, calidad en términos de simplicidad, de legibilidad, de portabilidad y ambos se conjugan perfectamente bien.
Más allá de la adaptación de la librería SDL, PyGame provee, a su vez, funciones específicas para el desarrollo de juegos (que no es el único uso de SDL, ni de PyGame: es perfectamente posible realizar una interfaz gráfica estándar con PyGame, si así se desea).
Las dificultades del desarrollo de juegos en tiempo real son, por un lado, gestionar el aspecto de tiempo real y, por otro, gestionar la representación. Para ello, PyGame...
Construcción de un juego Tetris
1. Presentación del juego
Tetris es uno de los grandes clásicos del videojuego y se ha adaptado incontables veces. Se trata de un juego donde se presenta al jugador un tablero que se completa con piezas que descienden inexorablemente desde la parte superior de la pantalla hasta la parte inferior.
Estas piezas son elementos «sólidos» formados por cuatro cubos que pueden girar sobre sí mismos y desplazarse de izquierda a derecha, además de acelerar su caída.
El único modo de vaciar el tablero es completar líneas, que desaparecen a continuación. Cuando se eliminan cuatro líneas ubicando una única pieza, el jugador ha conseguido realizar un tetris.
Algunas variantes permiten que las piezas que no se sostienen por otras piezas, tras la supresión de línea, caigan de nuevo. Esto permite completar más de cuatro líneas de una única vez. La manera de calcular la puntuación del jugador es, también, variable, así como el hecho de agregar interacciones entre varios jugadores, por ejemplo haciendo que cuando uno realiza un tetris, los «escombros» aparezcan en la pantalla de otro jugador.
Es realmente un juego donde prima la inventiva del desarrollador y donde es posible aportar novedades continuamente.
2. Presentación de la problemática
Si bien el principio del juego es muy sencillo, sus problemáticas no son triviales de resolver cuando no se está habituado a la programación de videojuegos.
Afortunadamente, la mayoría de las problemáticas puramente técnicas se gestionan gracias al módulo PyGame. Es el caso, por ejemplo, de la gestión del tiempo, de la visualización, de los retardos y de la captura de eventos.
A nivel de la representación, es necesario diseñar el tablero de juego, las piezas y el marcador. Decidimos comenzar el juego con una pantalla de inicio que aparece previamente y terminarlo con otra pantalla que indica que la partida ha terminado.
La problemática funcional consiste en escoger una pieza para hacerla descender por el tablero, permitirle descender de manera «natural» por gravedad, y permitir al usuario desplazarla a la derecha, a la izquierda o hacia abajo rápidamente, además de hacerla girar sobre sí misma. Todo ello, gestionando las colisiones con los bordes del tablero y con las piezas que ya existen.
El siguiente ejemplo utiliza únicamente funcionalidades de bajo nivel de PyGame.
Por último, todas las combinaciones posibles de cuatro cubos se describen en el siguiente vínculo y reciben la notación que vamos a utilizar (http://es.wikipedia.org/wiki/Tetris#Colores_de_los_tetriminos). Para simplificar las cosas, vincularemos un color a cada pieza.
3. Creación de constantes
No tenemos que inventar nada, todo se ha modelado previamente y se sabe cómo disponer todas las piezas y todas sus posiciones. De modo que vamos a declararlas en una variable PIEZAS (en mayúsculas, pues se trata de una constante).
Se representan de manera legible y que puede comprobarse en la consola:
PIEZAS = {
'O': [
'0000\n0110\n0110\n0000',
],
'S': [
'0000\n0022\n0220\n0000',
'0000\n0200\n0220\n0020',
],
'Z': [
'0000\n3300\n0330\n0000',
'0000\n0030\n0330\n0300',
],
'I': [
'0400\n0400\n0400\n0400',
'0000\n4444\n0000\n0000',
],
'J': [
'0000\n5000\n5550\n0000',
'0000\n0550\n0500\n0500',
'0000\n0000\n5550\n0050',
'0000\n0050\n0050\n0550',
],
'L': [
...