Programa de demostración

Videojuegos en Python: instalar y probar Pygame

Llega abril y con él vuelven los videojuegos a PItando: vamos a empezar la andadura de programar algún juego en Python usando las librerías Pygame.

Pygame es un proyecto que nació en el año 2000 y que permite desarrollar muy rápidamente (si se tiene experiencia) juegos en dos dimensiones. De hecho, hay competiciones de juegos desarrollados con límite de tiempo basadas en el uso de este desarrollo. De todas formas, Python y Pygame no son Scratch, así que trabajar con estos recursos va a requerir soltura con Python y cierta madurez que Scratch no requiere.

Por hoy lo que haremos será instalar el entorno, probar que funciona y examinar minuciosamente un primer ejemplo tomado de la web oficial.

Vamos a empezar, entonces.

Instalar Pygame en Windows para Python 3.4

Para instalar Pygame en Windows debemos tener instalada una versión 3.4 de Python: la 3.5 no sirve y, si lo intentamos, no funcionará. Si no tienes instalado Python en Windows sigue las instrucciones del artículo correspondiente de PItando.

  1. Descargamos Pygame de la página de descargas, actualmente alojada en Bitbucket: https://bitbucket.org/pygame/pygame/downloads.
    • En esta página, escogeremos de la lista la última versión de Pygame, identificando el sistema operativo, arquitectura (x86 para 32 bits, amd64 para 64 bits) y la versión de Python. Por ejemplo, la última versión (1.9.2) para windows de 64 bits y para Python 3.4 es pygame-1.9.2a0-hg_8d9e6a1f2635+.winamd64py3.4.msi:
      • win indica Windows
      • amd64 indica 64 bits
      • py3.4 indica Python 3.4
  2. Una vez descargado hacemos doble click en el instalador y seguiremos un asistente que recojo en esta galería (fíjate en la numeración de los pasos, bajo las imágenes):

El pase de diapositivas requiere JavaScript.

  • Con esto habremos terminado. Pasa a la sección “Probar Pygame y analizar un primer ejemplo” si no tienes más sistemas operativos donde instalarlo.

Instalar Pygame en Mac OS X para Python 3.4

Para Mac OS X la instalación es radicalmente diferente porque no existe un instalador preparado para los Mac modernos y compatible con Python 3.4. Así pues, lo que hay que hacer es instalarlo a mano compilándolo desde los archivos que manejan en pygame.org para desarrollar. De la misma forma, Pygame no va a funcionar en Python 3.5, por lo que asegúrate de instalar la versión 3.4.

Lo primero, para que no haya sorpresas durante el proceso, instalaremos (si no lo tenemos ya) XCode y XQuartz. XCode es la herramienta de desarrollo por excelencia del mundo Apple y nos hará falta para poder compilar Pygame desde un terminalXQuartz es un servidor de ventanas de tipo X11, muy parecido y totalmente compatible con el de cualquier Linux y, por supuesto, con el de la Raspbian de tu Raspberry Pi. Es un componente necesario para poder crear ventanas con Pygame.

Pantalla de descarga de XQuartz
Pantalla de descarga de XQuartz

La instalación es muy sencilla; sólo hay que avanzar por ella, aceptar la licencia e introducir la contraseña de Apple ID para otorgar permisos a hacer cambios en el Mac. Una vez termine tendremos que salir de la sesión y volver a entrar (o reiniciar el Mac) para que esta versión de X11 se ejecute por defecto con el sistema.

Si no lo has hecho, instala Python 3.4 usando el artículo de PItando dedicado a esta tarea.

Una vez hecho esto, instalaremos Homebrew, Mercurial y Git. Homebrew es un gestor de paquetes al estilo del apt-get de Raspbian; Mercurial y Git son sistemas de control de versiones de programas, usados para desarrollar en grupo. De repositorios Git y Mercurial es de donde nos tendremos que descargar el código de Pygame, las dependencias, y toda una suerte de cosas adicionales.

Cuanado hayas acabado de instalar Xcode, XQuartz y Python, escribe ahora estas sentencias en un terminal, de una en una. Si no encuentras el Terminal en el Launchpad, ábrelo desde Spotlight con ⌘ + Espacio, escribiendo “Terminal”.

usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)
brew install mercurial
brew install git
brew install sdl sdl_image sdl_mixer sdl_ttf smpeg portmidi
pip3 install hg+http://bitbucket.org/pygame/pygame

La primera de las sentencias anteriores instala Homebrew; las tres siguientes los prerrequisitos necesarios para Pygame, y la última descarga y compila Pygame usando pip3: un gestor de paquetes de Python que has instalado junto con Python 3.4.

Si todo ha ido bien, el proceso debería terminar con un mensaje “Successfully installed pygame-1.9.2a0 “. Con esto habremos terminado. Pasa a la sección “Probar Pygame y analizar un primer ejemplo” si no tienes más sistemas operativos donde instalarlo.

Pygame en la Raspberry Pi, para Python 3

En este caso, si tienes la distribución Raspbian Jessie actualizada, tendrás ya todo instalado. Pasa a la siguiente sección.

Probar Pygame y analizar un primer ejemplo

Vamos a copiar el ejemplo que hay en una de las páginas de introducción a Pygame, que hace rebotar una pelota en los bordes de una ventana. El código es el que pego a continuación, pero lo he modificado para limitar la velocidad del programa y para situarme en el directorio de trabajo, en donde tengo la imagen de la pelota. Además he puesto un control de excepciones (try:...except)para capturar el Ctrl + C con el que solemos interrumpir nuestros programas para terminar su ejecución.

En cualquier caso: si lo usas tal cual aparece en el listado del enlace superior, no verás gran cosa porque la pelota se mueve demasiado rápido. He marcado las líneas modificadas con comentarios.

# He incluido la librería "os" para manejar directorios
import sys, os, pygame
pygame.init()

# Me sitúo en el directorio de trabajo. Descomenta y edita la que corresponda
# según tu sistema operativo
# Windows
# os.chdir("c:\prog\python34\pitando")
# Mac OS X
# os.chdir("/Users/gvisoc/pitando")
# Raspberry Pi
os.chdir("/home/pi/pitando")

size = width, height = 320, 240
speed = [2, 2]
black = 0, 0, 0
screen = pygame.display.set_mode(size)
ball = pygame.image.load("ball.gif")
ballrect = ball.get_rect()

# Limitamos el número de cuadros por segundo de la animación
FRAMERATE = 60
# y cargamos un reloj que usará el valor anterior
clock = pygame.time.Clock()

try:
    while 1:
        # Esperamos al siguiente "tick", a intervalos de 1 / 60 segundos.
        clock.tick(FRAMERATE)
        
        for event in pygame.event.get():
            if event.type == pygame.QUIT: sys.exit()
        ballrect = ballrect.move(speed)
        if ballrect.left < 0 or ballrect.right > width:
            speed[0] = -speed[0]
        if ballrect.top < 0 or ballrect.bottom > height:
            speed[1] = -speed[1]

        screen.fill(black)
        screen.blit(ball, ballrect)
        pygame.display.flip()
except KeyboardInterrupt:
    print ("User exits")
    sys.exit()

Copia el listado superior a un editor de texto y guárdalo como texto plano con extensión py en tu directorio de trabajo. Yo lo he guardado como bota_pelota.py 🙂

Aquí tienes la imagen de la pelota, también. Te hará falta: descárgala al directorio de trabajo en donde vayas a guardar el programa de arriba.

Descárgate la imagen de la pelota
Descárgate la imagen de la pelota

Tu instalación de Pygame estará bien si, al cargar el listado anterior en un editor de IDLE y ejecutarlo, observas una ventana parecida a la siguiente, con una pelota rebotando:

Programa de demostración
Programa de demostración

Para probarlo, abre el intérprete IDLE para Python 3.4. Pulsa Ctrl + O si estás en Windows o Raspbian, y ⌘ + O si estás en Mac, para que el programa te permita buscar y abrir el fichero del programa que has guardado anteriormente. Cuando lo tengas abierto, pulsa F5 e IDLE lo ejecutará directamente.

Análisis del ejemplo

Vamos paso a paso, empezando por las primeras líneas del programa:

# He incluido la librería "os" para manejar directorios
import sys, os, pygame
pygame.init()

# Me sitúo en el directorio de trabajo. Descomenta y edita la que corresponda
# según tu sistema operativo
# Windows
# os.chdir("c:\prog\python34\pitando")
# Mac OS X
# os.chdir("/Users/gvisoc/pitando")
# Raspberry Pi
os.chdir("/home/pi/pitando")

Lo que estamos haciendo es:

  • pygame.init() inicializa el motor Pygame que nos proporcionará una forma fácil de modelar sprites (¿recuerdas?, como en Scratch), moverlos y gestionar el “mundo” por el cual se mueven.
  • Nos movemos al directorio de trabajo con os.chdir("...").
  • Generamos el “mundo”: una pantalla de dimensiones 320 píxels de ancho y 240 de alto. Creamos una variable que representa el color negro para usar de fondo (el cómo lo veremos luego) y cargamos la imagen de la pelota.
size = width, height = 320, 240
speed = [2, 2]
black = 0, 0, 0
screen = pygame.display.set_mode(size)
ball = pygame.image.load("ball.gif")
  • Mención especial merece la sentencia ballrect = ball.get_rect() , que obtiene el rectángulo contenedor de la pelota, esto es, el menor rectángulo posible que contiene todos y cada uno de los píxels que forman la imagen de la pelota. Para que te suene en lo sucesivo, en inglés este rectángulo se suele llamar bounding box.
# Limitamos el número de cuadros por segundo de la animación 
FRAMERATE = 60 
# y cargamos un reloj que usará el valor anterior 
clock = pygame.time.Clock()
  • Aquí hemos generado los objetos de control de tiempos que nos ayudarán a limitar la velocidad del programa de forma independiente a la velocidad del microprocesador, del chip de gráficos y de la memoria del ordenador que estemos usando.

Ya conocemos las sentencias try... except que rodean el resto del programa, así que vamos con el bucle:

    while 1:
        # Esperamos al siguiente "tick", a intervalos de 1 / 60 segundos.
        clock.tick(FRAMERATE)
        
        for event in pygame.event.get():
            if event.type == pygame.QUIT: sys.exit()
        ballrect = ballrect.move(speed)
        if ballrect.left < 0 or ballrect.right > width:
            speed[0] = -speed[0]
        if ballrect.top < 0 or ballrect.bottom > height:
            speed[1] = -speed[1]

        screen.fill(black)
        screen.blit(ball, ballrect)
        pygame.display.flip()

El bucle es infinito; en este caso, while 1:  es equivalente al más frecuente while True: .

  • Esperamos al siguiente tick, que Pygame nos proporciona a una frecuencia de 60 veces por segundo, con clock.tick(FRAMERATE)
  • Con el bucle que hay justo a continuación estaremos examinando los eventos que se hayan producido desde la anterior pasada del bucle. Si el usuario ha pulsado el aspa de la ventana (evento pygame.QUIT ), el programa se detendrá. Los eventos de Pygame son múltiples y variados, y los usaremos bastante en los artículos sucesivos.
  • Si no ha ocurrido eso, movemos la pelota con la simple sentencia ballrect = ballrect.move(speed) . Fíjate que para mover la pelota usaremos su bounding box, o rectángulo contenedor, y le proporcionaremos el objeto que hemos definido anteriormente con speed = [2, 2] . Como puedes imaginar, estamos dándole velocidades en los dos ejes: horizontal y vertical.
  • El siguiente fragmento realiza la detección de las paredes, comparando los límites del rectángulo contenedor con los límites de la ventana que hemos definido al principio del programa.
        if ballrect.left < 0 or ballrect.right > width:
            speed[0] = -speed[0]
        if ballrect.top < 0 or ballrect.bottom > height:
            speed[1] = -speed[1]
  • Observa lo sencillo que es hacer que la pelota rebote: sólo hay que cambiar de signo la velocidad. Esto quiere decir que si tenemos una velocidad 2 nos movemos “a ritmo 2” en sentido positivo del eje, horizontal o vertical, en el que nos movemos; velocidad -2 se moverá al mismo ritmo pero en dirección contraria.
  • El código del final actualiza la pantalla (incluyendo el relleno de fondo con el color negro) y permite que Pygame haga sus operaciones internas antes de pasar a la siguiente pasada del bucle. No te preocupes por sus significados concretos y por sus implicaciones; tendrán su turno en los artículos que vendrán a continuación.
        screen.fill(black)
        screen.blit(ball, ballrect)
        pygame.display.flip()

Y esto es todo por hoy. En breve publicaré en mi cuenta de Twitter el juego que vamos a programar “por fascículos” con esta librería, que espero que resulte interesante. ¡Estoy seguro de que aprenderemos bastantes cosas!

Puedes dejarme tus comentarios en este artículo, o bien escribirme a través del formulario de contacto.

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *