Contenidos
Contenido
- 1 Pygame
- 2 Instalación
- 3 Inicializar Pygame
- 4 Crear la ventana de juego
- 5 Bucle principal del juego
- 6 Color de fondo en mi ventana
- 7 Imágenes
- 8 Movimiento
- 9 Velocidad del movimiento
- 10 Control de los límites de la pantalla
- 11 Teclado
- 12 Movimiento con el ratón
- 13 FPS: Frames por segundo
- 14 Colisiones
- 15 Rebotes
- 16 Sonidos
- 17 Textos
- 18 Animaciones
- 19 Posición y velocidad
- 20 Gravedad=
Pygame
Pygame es una librería multiplataforma diseñada para facilitar la creación de software multimedia, sobre todo juegos. Funciona como interfaz a las bibliotecas SDL Pygame se encarga de gestionar:
- imágenes en distintos formatos (PNG, BMP, PCX, TGA, ...)
- sistemas de sonido (MOD, OGG, MP3, ...)
- operaciones relacionadas con el gestor de ventana.
- eventos de aplicación y dispositivos de entrada (mouse, teclado, joystick)
- temporizadores.
- colisiones entre objetos
Instalación
- Descarga el paquete apropiado al sistema operativo y versión de python de http://www.pygame.org/download.shtml.
- Aquí tienes más versiones compiladas para windows:
Si todo ha ido bien puedes probar los juegos de ejemplos:
python -m pygame.examples.aliens
Inicializar Pygame
import pygame
from pygame.locals import *
pygame.init()
Crear la ventana de juego
import pygame
from pygame.locals import *
ANCHO, ALTO = 640, 480
pygame.display.set_mode((ANCHO, ALTO))
pygame.display.set_caption("Mi primer juego con pygame")
Bucle principal del juego
Como en toda aplicación multimedia, en un juego pygame el bucle principal tiene que:
- comprobar los controles
- evaluar los eventos
- actualizar objetos en el juego
- refrescar la pantalla
while True:
# comprobar controles
# evaluar eventos
for eventos in pygame.event.get():
if eventos.type == QUIT:
sys.exit(0)
# actualizar los objetos (sprites)
# dibujar / refrescar la pantalla
Color de fondo en mi ventana
Cuando creamos la ventana principal, set_mode devuelve un objeto (surface) que podemos usar para colorear el fondo:
BG_COLOR = 150, 150, 80
pantalla = pygame.display.set_mode((ANCHO, ALTO))
pygame.display.set_caption("Mi primer juego con pygame")
while True:
for eventos in pygame.event.get():
if eventos.type == QUIT:
sys.exit(0)
pantalla.fill(BG_COLOR)
pygame.display.flip() # Ver referencia de flip más adelante
flip actualiza la pantalla. Pygame maneja la pantalla con Double Buffer. Primero dibuja la pantalla en segundo plano y después la hace visible.
Imágenes
Cargar imágenes
Podemos cargar un fondo así:
fondo = pygame.image.load('imagenes/escenario.jpg')
Transparencias
En Pygame se usan dos tipos de transparencias, la transparencia alpha y la de colorkey:
- Transparencia alfa (alpha)
- Se aplica a toda la imagen, es un valor que va desde 0 a 255 donde 0 es opaco y 255 es transparente, se puede hacer una imagen borrosa dandole valores intermedios
- Tranparencia colorkey
- Se aplica solo a un color de la imagen y hace ese color invisible
Una función interesante para cargar imágenes con transparencia alfa:
def cargar_imagen(nombre, optimizar=False):
ruta = os.path.join('imagenes', nombre)
imagen = pygame.image.load(ruta)
if optimizar:
return imagen.convert()
else:
return imagen.convert_alpha()
</source>
Sistemas de coordenadas
Pygame no usa el sistema de coordenadas cartesianas, con el (0,0) en el centro de la pantalla. http://thepythongamebook.com/_media/en:part2:pygame-coordinates2.png En pygame la esquina superior izquierda tiene la coordenada 0,0. La esquina inferior derecha tiene max_ancho-1, max_alto-1 .
Colocar la imagen en la pantalla
screen.blit(imagen, (posx, posy))
Si hay una imagen de fondo, se suele colocar:
screen.blit(fondo, (0, 0)
Sprites
Los distintos elementos de un juego tienen mucha información: imagen, posición, tipo y dirección de movimento, vidas, etc. Crearemos una clase, que hereda de Sprite para representar estos objetos. Un sprite en pygame tiene:
- self.image
- self.rect
- update(self)
Manejar los rectángulos
Atributos de un rectángulo:
top, left, bottom, right topleft, bottomleft, topright, bottomright midtop, midleft, midbottom, midright center, centerx, centery size, width, height w,h
Movimiento
El bucle principal del juego se ejecuta muchas veces por segundo. Si cambiamos la posición en que se dibuja un objeto (su rectángulo), generamos una sensación de movimento.
class Banana(Sprite):
def __init__(self, scr=None):
Sprite.__init__(self)
self.image = cargar_imagen('banana.png')
self.rect = self.image.get_rect()
self.scr = scr
self.velocidad = 1
def update(self):
self.rect.top += self.velocidad
def draw(self):
if self.scr: self.scr.blit(self.image, self.rect)
El movimiento puede ser automático, generado por un evento (teclado, joystick, webcam, wiimote, ...) o por interacción con otros objetos.
Velocidad del movimiento
Es importante controlar la velocidad a la que se refresca la pantalla:
# creación de reloj
clock = pygame.time.Clock()
# dentro del bucle del juego
while True:
# ...
tiempo = clock.tick(60)
El juego intentará hacer 60 fps (frames por segundo)
http://www.losersjuegos.com.ar/traducciones/pygame/time/clock
Control de los límites de la pantalla
Normalmente no dejaremos que los sprites se muevan fuera de la pantalla: desaparecen, rebotan, hacemos un scroll ... En cada ciclo del juego tendremos que comprobar que los objetos no se salgan de la pantalla. Recuerda que el límite superior e izquierdo es el 0, el límite derecho es la anchura definida al crear la pantalla y el límite inferior, la altura de la pantalla.
Teclado
¿Qué teclas se han pulsado?
keys = pygame.key.get_pressed()
# comprueba si se ha pulsado la tecla de flecha arriba
if keys[K_UP]:
self.rect.centery -= self.velocidad
Podemos detectar un evento de pulsar una tecla:
if event.type == pygame.KEYDOWN:
print event.key
Aquí tienes todo el catálogo de las teclas (keycodes): http://www.pygame.org/docs/ref/key.html
Movimiento con el ratón
if event.type == pygame.MOUSEBUTTONDOWN: # o MOUSEBUTTONUP o MOUSEMOTION
(mouseX, mouseY) = pygame.mouse.get_pos()
# ...
http://www.pygame.org/docs/ref/mouse.html
FPS: Frames por segundo
Un frame es un paso completo el bloque actualizar/mostrar/espera La velocidad de ejecución debería ser la misma en todas las plataformas, pero a veces va demasiado despacio y otras demasiado deprisa. Regla de oro: como mínimo debe de haber 30 actualizaciones por segundo. Pygame cuenta el tiempo en milisegundos.
clock = pygame.time.Clock()
clock.tick(30) # 30 veces por segundo
Clock devuelve el tiempo pasado desde el frame anterior.
milliseconds = clock.tick(FPS)
playtime += milliseconds / 1000.0
Colisiones
Para comprobar si dos objetos se tocan (sus rectángulos):
pygame.sprite.collide_rect(objeto1, objeto2) pygame.sprite.collide_circle(objeto1, objeto2)
Devuelven verdadero o falso.
Si se utilizan grupos de sprites (balas, naves, enemigos, ...):
pygame.sprite.spritecollideany(objeto, grupo) pygame.sprite.groupcollide(grupo1, grupo2)
http://www.losersjuegos.com.ar/traducciones/pygame/sprite
Rebotes
Cuando un objeto rebota, el ángulo de reflexión es el mismo que el ángulo de incidencia:
Sonidos
sonido = pygame.mixer.Sound(<ruta>) # soporta .wav, .mp3, .ogg
# ...
sonido.play()
Textos
font = pygame.font.Font(None, 28) # fuente por defecto
# ...
texto = font.render("Puntos: 1000", 1, (0, 0, 0)) # Texto, antialiasing, color en RGB
# ...
screen.blit(texto, (10, 10))
http://www.losersjuegos.com.ar/traducciones/pygame/font
Animaciones
Las animaciones se simulan. Se va cambiando la imagen. Hay que dejar unos ciclos (milisegundos) cada imagen para que se vea en pantalla.
Posición y velocidad
- ¿Dónde está un objeto en el instante x?
- La velocidad es la proporción entre la distancia recorrida y el tiempo. En el desplazamiento tenemos que tener en cuenta también la dirección del objeto.
- Dadas las variables: posición posición original (x, y), velocidad y ángulo:
desplazamiento_x = (velocidad * cos(angulo))
desplazamiento_y = (velocidad * sin(angulo))
posicion_x += desplazamiento_x
posicion_y += desplazamiento_y
Aceleración
Cuando movemos un objeto a una velocidad, se le puede añadir una aceleración continua a la velocidad
velocidad += aceleracion
desplazamiento_x = (velocidad * cos(angulo))
desplazamiento_y = (velocidad * sin(angulo))
posicion_x += desplazamiento_x
posicion_y += desplazamiento_y
Gravedad=
Es una aceleración hacia abajo. La gravedad de la tierra es de 9.81 metros por segundo. En un juego, la gravedad constante depende del frame rate. Lo utilizamos cuando un personaje salta, en los proyectiles, etc.