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:
- Comprobar si el usuario ha pulsado alguna tecla (o ha movido el joystick, o el ratón, o algún otro dispositivo de entrada)
- Mover los enemigos, el entorno y cualquier otro componente del juego que sea capaz de moverse por sí solo.
- Comprobar colisiones, para ver si hemos recogido algún objeto, tocado algún enemigo, si algún disparo ha impactado con algo, etc., y así poder actualizar los puntos, las vidas y el resto del estado actual del juego.
- Dibujar los elementos en pantalla
- Si queremos que la velocidad del juego sea "estable" (que no se mueva mucho más rápido en ordenadores más recientes, lo que lo haría injugable), quizá necesitemos hacer una pausa al final de cada "fotograma".
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:
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()