"""
Use sprites to pick up bloques
Sample Python/Pygame Programs
Simpson College Computer Science
http://programarcadegames.com/
http://simpson.edu/computer-science/
Explanation video: http://youtu.be/iwLj7iJCFQM
"""
import pygame
import random
# Definimos algunos colores
NEGRO = (0, 0, 0)
BLANCO = (255, 255, 255)
ROJO = (255, 0, 0)
class Bloque(pygame.sprite.Sprite):
"""
Esta clase representa al bloque que será recogido.
Se deriva de la clase "Sprite" en Pygame.
"""
def __init__(self, color, largo, alto):
""" Constructor. Pasa el color del bloque, así como
su posición x,y. """
# Llama al constructor de la clase padre (Sprite)
super().__init__()
# Crea una imagen del bloque, y lo rellena con color.
# También podríamos usar una imagen cargada desde el disco duro.
self.image = pygame.Surface([largo, alto])
self.image.fill(color)
# Extrae el objeto rectángulo que tiene las dimensiones de la imagen.
# Actualiza la posición de este objeto, estableciendo los valores de
# rect.x y rect.y
self.rect = self.image.get_rect()
class Protagonista(Bloque):
""" Esta clase representa al protagonista. Deriva de bloque y por eso tiene el mismo
método ___init___ que definimos arriba. """
# Lista de todos los bloques que nos llevamos
lista_de_bloques_acarreados = []
def update(self):
""" Método llamado al actualizar un sprite. """
# Obtiene la posición actual del ratón. La devuelve como
# una lista de dos números.
pos = pygame.mouse.get_pos()
# Ahora veamos cómo la ubicación del ratón difiere de la posición actual del
# protagonista. (¿Cuán lejos nos hemos desplazado?)
diff_x = self.rect.x - pos[0]
diff_y = self.rect.y - pos[1]
# Iteramos a través de cada bloque que llevamos y ajustamos
# la cantidad de desplazamiento.
for bloque in self.lista_de_bloques_acarreados:
bloque.rect.x -= diff_x
bloque.rect.y -= diff_y
# Establecemos la posición del protagonista en la del ratón
self.rect.x = pos[0]
self.rect.y = pos[1]
# Inicializamos Pygame
pygame.init()
# Establecemos el alto y largo de la pantalla
largo_pantalla = 700
alto_pantalla = 400
pantalla = pygame.display.set_mode([largo_pantalla, alto_pantalla])
# Lista de los 'sprites.' Cada bloque en el programa se
# añade a la lista. La lista es gestionada por la clase 'Group.'
lista_de_bloques = pygame.sprite.Group()
# Lista de cada sprite.
# También de todos los bloques y del protagonista.
listade_todoslos_bloques = pygame.sprite.Group()
for i in range(50):
# Esto representa un bloque
bloque = Bloque(NEGRO, 20, 15)
# Establecemos una ubicación aleatoria para el bloque
bloque.rect.x = random.randrange(largo_pantalla)
bloque.rect.y = random.randrange(alto_pantalla)
# Añadimos el bloque a la lista de objetos.
lista_de_bloques.add(bloque)
listade_todoslos_bloques.add(bloque)
# Creamos un bloque protagonista ROJO.
protagonista = Protagonista(ROJO, 20, 15)
listade_todoslos_bloques.add(protagonista)
# Iteramos hasta que el usuario pulsa el botón de salida.
hecho = False
# Controla las veces que se refresca la pantalla.
reloj = pygame.time.Clock()
# Ocultamos el cursor del ratón.
pygame.mouse.set_visible(False)
# -------- Bucle Principal del Programa -----------
while not hecho:
for evento in pygame.event.get():
if evento.type == pygame.QUIT:
hecho = True
elif evento.type == pygame.MOUSEBUTTONDOWN:
# Cuando presionamos el ratón, observamos si estamos en contacto con otros sprites
lista_impactos_bloques = pygame.sprite.spritecollide(protagonista, lista_de_bloques, False)
# Establecemos que lista con los bloques con los que estamos en contacto, sea la lista de lo que llevamos recogido.
protagonista.lista_de_bloques_acarreados = lista_impactos_bloques
elif evento.type == pygame.MOUSEBUTTONUP:
# Cuando dejamos de pulsar el ratón, hacemos que la lista de los bloques recogidos se vacíe.
protagonista.lista_de_bloques_acarreados = []
listade_todoslos_bloques.update()
# Limpiamos la pantalla
pantalla.fill(BLANCO)
# Dibujamos todos los sprites
listade_todoslos_bloques.draw(pantalla)
# Limitamos a 60 fps
reloj.tick(60)
# Avanzamos y actualizamos la pantalla con todo aquello que hemos dibujado.
pygame.display.flip()
pygame.quit()