"""
Muestra la forma correcta de organizar un juego utilizando una clase juego
Sample Python/Pygame Programs
Simpson College Computer Science
http://programarcadegames.com/
http://simpson.edu/computer-science/
Vídeo explicativo: http://youtu.be/O4Y5KrNgP_c
"""
import pygame
import random
#--- Constantes Globales ---
NEGRO = (0, 0, 0)
BLANCO = (255, 255, 255)
VERDE = (0, 255, 0)
ROJO = (255, 0, 0)
LARGO_PANTALLA = 700
ALTO_PANTALLA = 500
# --- Clases ---
class Bloque(pygame.sprite.Sprite):
""" Este clase representa aun sencillo bloque que es recogido por el protagonista. """
def __init__(self):
""" Constructor; crea la imagen del bloque. """
super().__init__()
self.image = pygame.Surface([20, 20])
self.image.fill(NEGRO)
self.rect = self.image.get_rect()
def reset_pos(self):
""" La llamamos cuando el bloque es 'recogido' o se va fuera de
la pantalla. """
self.rect.y = random.randrange(-300, -20)
self.rect.x = random.randrange(LARGO_PANTALLA)
def update(self):
""" Se le llama automáticamente cuando necesitamos mover el bloque. """
self.rect.y += 1
if self.rect.y > ALTO_PANTALLA + self.rect.height:
self.reset_pos()
class Protagonista(pygame.sprite.Sprite):
""" Esta clase representa al protagonista. """
def __init__(self):
super().__init__()
self.image = pygame.Surface([20, 20])
self.image.fill(ROJO)
self.rect = self.image.get_rect()
def update(self):
""" Actualiza la posición del protagonista. """
pos = pygame.mouse.get_pos()
self.rect.x = pos[0]
self.rect.y = pos[1]
class Juego(object):
""" Esta clase representa una instancia del juego. Si necesitamos reiniciar el juego,
solo tendríamos que crear una nueva instancia de esta clase."""
def __init__(self):
""" Constructor. Crea todos nuestros atributos e inicializa
el juego. """
self.puntuacion = 0
self.game_over = False
# Creamos la lista de sprites
self.bloque_lista = pygame.sprite.Group()
self.listade_todoslos_sprites = pygame.sprite.Group()
# Creamos los bloques de sprites
for i in range(50):
bloque = Bloque()
bloque.rect.x = random.randrange(LARGO_PANTALLA)
bloque.rect.y = random.randrange(-300, ALTO_PANTALLA)
self.bloque_lista.add(bloque)
self.listade_todoslos_sprites.add(bloque)
# Creamos al protagonista
self.protagonista = Protagonista()
self.listade_todoslos_sprites.add(self.protagonista)
def procesa_eventos(self):
""" Procesa todos los eventos. Devuelve un "True" si precisamos
cerrar la ventana. """
for evento in pygame.event.get():
if evento.type == pygame.QUIT:
return True
if evento.type == pygame.MOUSEBUTTONDOWN:
if self.game_over:
self.__init__()
return False
def logica_de_ejecucion(self):
"""
Este método se ejecuta para cada fotograma.
Actualiza posiciones y comprueba colisiones.
"""
if not self.game_over:
# Mueve todos los sprites
self.listade_todoslos_sprites.update()
# Observa por si el bloque protagonista ha colisionado con algo.
lista_impactos_bloques = pygame.sprite.spritecollide(self.protagonista, self.bloque_lista, True)
# Comprueba la lista de colisiones.
for bloque in lista_impactos_bloques:
self.puntuacion += 1
print( self.puntuacion )
if len(self.bloque_lista) == 0:
self.game_over = True
def display_frame(self, pantalla):
""" Muestra todo el juego sobre la pantalla. """
pantalla.fill(BLANCO)
if self.game_over:
#fuente = pygame.font.Font("Serif", 25)
fuente = pygame.font.SysFont("serif", 25)
texto = fuente.render("Game Over, haz click para volver a jugar", True, NEGRO)
centrar_x = (LARGO_PANTALLA // 2) - (text.get_width() // 2)
centrar_y = (ALTO_PANTALLA // 2) - (text.get_height() // 2)
pantalla.blit(texto, [centrar_x, centrar_y])
if not self.game_over:
self.listade_todoslos_sprites.draw(pantalla)
pygame.display.flip()
def main():
"""Función principal del programa. """
# Iniciamos Pygame y disponemos la ventana
pygame.init()
dimensiones = [LARGO_PANTALLA, ALTO_PANTALLA]
pantalla = pygame.display.set_mode(dimensiones)
pygame.display.set_caption("Mi Juego")
pygame.mouse.set_visible(False)
# Crea los objetos y dispone los datos
hecho = False
reloj = pygame.time.Clock()
# Crea una instancia de la clase Juego
juego = Juego()
# Bucle principal
while not hecho:
# Procesa los eventos (pulsaciones del teclado, clicks del ratón, etc.)
hecho = juego.procesa_eventos()
# Actualiza las posiciones de los objetos y comprueba colisiones
juego.logica_de_ejecucion()
# Dibuja el fotograma actual
juego.display_frame(pantalla)
# Hace una pausa hasta el siguiente fotograma
reloj.tick(60)
# Cierra la ventana y sale
pygame.quit()
# Llama a la función principal y arranca el juego
if __name__ == "__main__":
main()