<-- Back to list of examples

"""
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()