13 agosto 2012

Raspberry Pi y PyGame - Introducción

El fin de semana del 21 de julio (de 2012), un grupo de adolescentes decidió usar su Raspberry Pi y el lenguaje Python para hacer un marathon de programación colaborativa de 24 horas, que llamaron "Raspithon". Usaron la biblioteca de juegos Pygame (basada en SDL) para crear un juego de asteroides, que iban programando entre 4 personas, usando un repositorio Git como punto en el que centralizar todo lo que iban creando.

Puedes leer la propuesta que hicieron, el post que habla sobre los resultados e incluso descargar el programa resultante desde GitHub.

Si cuatro chavales de entre 12 y 16 años, que ni siquiera se conocen entre ellos, son capaces de crear un juego... ¿es que cualquiera puede hacer un juego con Pygame? Sí y no. Python es más fácil de aprender que otros lenguajes como C, pero aun así necesita algo de dedicación si se quiere tener soltura. SDL es una biblioteca de un nivel bastante bajo, de modo que no es especialmente sencilla; Pygame la "encapsula" y la hace un poco más accesible, pero aun así no es trivial. Además, no todo tipo de juegos se podrá hacer con una cantidad de esfuerzo razonable: Pygame puede ayudar para juegos en 2D (plataformas, matamarcianos simples, etc) pero no simplifica las tareas adicionales que conllevaría crear un juego en 3D, de modo que un juego de este tipo puede suponer una cantidad de trabajo desproporcionada.

¿Y basta con un Raspberry Pi? Sí. La instalación básica de Raspbian (de fecha 15-07-2012) incluye Pygame, aunque sólo para la versión 2.7 de Python, pero debería ser suficiente.

¿Y si no tengo un Raspberry Pi... no puedo? Claro que sí. Python es multiplataforma. Cualquier Linux podría bastar (tendremos que usar Synaptic o nuestro gestor de paquetes para instalar "python-pygame"). Incluso en Windows debería ser fácil de instalar... aunque yo lo he probado (¿aún?).

Un programa básico en Python, usando PyGame para que un "marciano" rebote en la pantalla podría ser así:

import pygame, sys
pygame.init()

ancho = 800
alto = 600
velocidadX = 3
velocidadY = 3

pantalla = pygame.display.set_mode( (ancho, alto) )

imagen = pygame.image.load("spaceinvader.png")
rectanguloImagen = imagen.get_rect()

while 1:
    for event in pygame.event.get():
        if event.type == pygame.QUIT: sys.exit()

    rectanguloImagen = rectanguloImagen.move( (velocidadX, velocidadY) )
    if rectanguloImagen.left < 0 or rectanguloImagen.right > ancho:
        velocidadX = -velocidadX
    if rectanguloImagen.top < 0 or rectanguloImagen.bottom > alto:
        velocidadY = -velocidadY

    pantalla.fill( (0,0,0) )
    pantalla.blit(imagen, rectanguloImagen)
    pygame.display.flip()


En mi caso, ha bastado con teclear esto en el editor Geany, guardarlo con el nombre "rebota1.py" y pulsar el botón "ejecutar".

El fuente debería ser fácil de seguir incluso si no conoces Python:
  • "Importamos" las bibliotecas que vamos a usar: pygame (por supuesto) y "sys", que usaremos para abandonar el programa cuando sea necesario: import pygame, sys
  • Inicializamos pygame: pygame.init()
  • Declaramos los que serán el ancho y el alto de la pantalla de juego, en puntos, porque los usaremos para preparar la pantalla pero también para que "rebote" nuestro "marciano": ancho = 800, alto = 600
  • Preparamos también la velocidad a la que se moverá el "marciano" (la cantidad de puntos que se desplazará en cada "fotograma" del supuesto "juego"): velocidadX = 3, velocidadY = 3
  • Preparamos la pantalla (el ancho y el alto se deben indicar entre paréntesis, porque no son dos números aislados, sino un "par"): pantalla = pygame.display.set_mode( (ancho, alto) )
  • Cargamos la imagen que representará nuestro marciano (esa imagen deberá existir y estar en la misma carpeta que se encuentra nuestro fuente): imagen = pygame.image.load("spaceinvader.png")
  • Cada imagen estará contenida en un "rectángulo", que será el que movamos: rectanguloImagen = imagen.get_rect()
  • Y empieza la parte que se va a repetir indefinidamente: while 1:
  • Revisamos todos los "sucesos" del sistema; si alguno de ellos es una petición de salir del programa (porque se pulse la X de la ventana), salimos al sistema:    for event in pygame.event.get():   if event.type == pygame.QUIT: sys.exit()
  • En cada fotograma, desplazamos el "marciano" a la que será su siguiente posición:      rectanguloImagen = rectanguloImagen.move( (velocidadX, velocidadY) )
  • Si se sale por un lado de la pantalla o por el opuesto, en horizontal, cambiamos su "velocidad", para que pase a moverse en dirección contraria:  if rectanguloImagen.left < 0 or rectanguloImagen.right > ancho:  velocidadX = -velocidadX
  • Y hacemos las mismas comprobaciones en vertical: if rectanguloImagen.top < 0 or rectanguloImagen.bottom > alto: velocidadY = -velocidadY
  • Rellenamos la pantalla de color negro (el color (0,0,0), sin nada de rojo, verde ni azul, es el negro):  pantalla.fill( (0,0,0) )
  • Volcamos la imagen a la pantalla: pantalla.blit(imagen, rectanguloImagen)
  • Y hacemos que lo que hemos preparado en pantalla sea visible:  pygame.display.flip()
  • Todo eso se repetirá hasta que abandonemos el programa.

El resultado será pobre, pero es un comienzo:



¿Quieres más?  Deja un comentario... ;-)

(Ese fuente se basa en uno tomado de uno de los muchos tutoriales de Pygame disponibles en la red; en concreto, en uno de Pete Shinners; si quieres ver más detalles, aquí tienes un texto paso a paso).