Introducción a Pygame
Por Nacho Cabanes, versión 0.10

4. Temporización básica

Hasta ahora, nuestro "proyecto de juego" se mueve a toda la velocidad que permite el sistema. Eso no suele ser lo más razonable: es más "jugable" si en todos los ordenadores se mueve a una misma velocidad, por ejemplo a "50 fotogramas por segundo".

No es difícil conseguirlo con pygame: podemos crear un reloj (clock) antes de que comience la parte repetitiva de nuestro programa:

reloj = pygame.time.Clock()

Y luego, al final de esa parte repetitiva haremos que espere (si fuera necesario), de forma que la velocidad sea de un máximo de 40 fotogramas por segundo:

reloj.tick(40)

De paso, vamos a ir completando esa parte "repetitiva", lo que llamaremos el "bucle de juego", que realizará las siguientes tareas:

En nuestro caso, ya podemos hacer 4 de esas 5 cosas (la comprobación de colisiones la dejamos para la siguiente entrega):

while not terminado:
    # Comprobar acciones del usuario
    # Actualizar estado
    # Dibujar elementos en pantalla
    # Ralentizar hasta 40 fotogramas por segundo 

De paso, haremos que aparezcan ya 3 elementos en el juego: un "marciano" que se mueva solo y rebote en todos los lados, un "ufo" que se mueva de izquierda a derecha y vuelva a aparecer por la izquierda cuando desaparezca por el extremo derecho, y una "nave" que controlemos con el teclado:

pygame - ejemplo 004

El fuente completo podría ser así:

# Mini-invaders, version 0.04
# (Temporizacion estable)
# Parte de la intro a Pygame, por Nacho Cabanes
 
import pygame
from pygame.locals import *
 
pygame.init()
 
ancho = 800
alto = 600
velocidadX = 3
velocidadY = 3
terminado = False
 
pantalla = pygame.display.set_mode( (ancho, alto) )
pygame.key.set_repeat(1,25)
reloj = pygame.time.Clock()        # Nuevo en la versión 0.04
 
imagenMarciano = pygame.image.load("spaceinvader.png")
rectanguloMarciano = imagenMarciano.get_rect()
rectanguloMarciano.left = 200
rectanguloMarciano.top = 100
 
imagenNave = pygame.image.load("nave.png")      # Nuevo en 0.04
rectanguloNave = imagenNave.get_rect()          # Nuevo en 0.04
rectanguloNave.left = ancho/2                   # Nuevo en 0.04
rectanguloNave.top = alto-50                    # Nuevo en 0.04
 
imagenUfo = pygame.image.load("ufo.png")
rectanguloUfo = imagenUfo.get_rect()
rectanguloUfo.top = 20
 
while not terminado:
    # ---- Comprobar acciones del usuario ----
    for event in pygame.event.get():
        if event.type == pygame.QUIT: terminado = True
 
    keys = pygame.key.get_pressed()
    if keys[K_LEFT]:
        rectanguloNave.left -= 4
    if keys[K_RIGHT]:
        rectanguloNave.left += 4
 
    # ---- Actualizar estado ----
    rectanguloMarciano.left += velocidadX
    rectanguloMarciano.top += velocidadY
    if rectanguloMarciano.left < 0 or rectanguloMarciano.right > ancho:
        velocidadX = -velocidadX
    if rectanguloMarciano.top < 0 or rectanguloMarciano.bottom > alto:
        velocidadY = -velocidadY
 
    rectanguloUfo.left += 2                      # Nuevo en 0.04
    if rectanguloUfo.right > ancho:              # Nuevo en 0.04
        rectanguloUfo.left = 0                   # Nuevo en 0.04
 
    # ---- Dibujar elementos en pantalla ----
    pantalla.fill( (0,0,0) )
    pantalla.blit(imagenMarciano, rectanguloMarciano)
    pantalla.blit(imagenUfo, rectanguloUfo)      # Nuevo en 0.04
    pantalla.blit(imagenNave, rectanguloNave)
    pygame.display.flip()
 
    # ---- Ralentizar hasta 40 fotogramas por segundo  ----
    reloj.tick(40)
 
pygame.quit()