import pygame
import random
 
# Define colors
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
RED = (255, 0, 0)
BLUE = (0, 0, 255)

# --- Classes 
class Block(pygame.sprite.Sprite):
    """ This class represents the block. """
    def __init__(self, color):
        # Call the parent class (Sprite) constructor
        super().__init__()
        self.image = pygame.image.load("timmy.png").convert()
        self.image.set_colorkey(WHITE)
        self.image = pygame.transform.scale(self.image, (20, 15))
        self.rect = self.image.get_rect()
    def update(self):
        """ Called each frame. """ 
        # Move block down one pixel
        self.rect.y += 1
        # If block is too far down, reset to top of screen.
        if self.rect.y > 410:
            self.rect.y = -20 
class Player(pygame.sprite.Sprite):
    """ This class represents the Player. """
    def __init__(self):
        """ Set up the player on creation. """
        # first, call the parent class (Sprite) constructor then setup image, background color, size, then set rect to it
        super().__init__()
        self.image = pygame.image.load("player.png").convert()
        self.image.set_colorkey(BLACK)
        self.image = pygame.transform.scale(self.image, (20, 20))
        self.rect = self.image.get_rect()

class Bullet(pygame.sprite.Sprite):
    """ This class represents the bullet . """
    def __init__(self):
        # first all the parent class (Sprite) constructor
        super().__init__()
        self.image = pygame.image.load("perfectBullet.png").convert()
        self.image.set_colorkey(WHITE)
        self.image = pygame.transform.scale(self.image, (4, 10))          
        self.rect = self.image.get_rect() 
    def update(self):
        """ Move the bullet. """
        self.rect.y -= 3

# Initialize Pygame
pygame.init()

# Set the height and width of the screen, along with background image
screen_width = 700
screen_height = 400
screen = pygame.display.set_mode([screen_width, screen_height])
background_image = pygame.image.load("saturn_family1.jpg").convert()

# setup all the sounds
click_sound = pygame.mixer.Sound("laser5.ogg")
hit_sound = pygame.mixer.Sound("auntjoni.ogg")

#setup the main font
font = pygame.font.SysFont('Calibri', 25, True, False)

# This is a list of every sprite. All blocks and the player block as well.
all_sprites_list = pygame.sprite.Group()
 
# List of each block in the game
block_list = pygame.sprite.Group()
 
# List of each bullet
bullet_list = pygame.sprite.Group()
 
# --- Create the sprites
for i in range(50):
    # This represents a block
    block = Block(BLUE)
    # Set a random location for the block
    block.rect.x = random.randrange(screen_width)
    block.rect.y = random.randrange(150)
    # Add the block to the list of objects
    block_list.add(block)
    all_sprites_list.add(block)
 
# Create the player block using the class defined above
player = Player()
all_sprites_list.add(player)
 
# boolean variable to indicate if we are done looping thru while loop
done = False
 
# Used to manage how fast the screen updates
clock = pygame.time.Clock()
 
# setup some basic variables
score = 0
player.rect.y = 370
x_speed = 0

# -------- Main Program Loop -----------
while not done:
    # --- Event Processing
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            done = True
        elif event.type == pygame.KEYDOWN:
            #if it was a spacebar, then fire a bullet
            if event.key == pygame.K_SPACE:
                bullet = Bullet()
                # Set the bullet so it is where the player is
                bullet.rect.x = player.rect.x
                bullet.rect.y = player.rect.y
                # Add the bullet to the lists
                all_sprites_list.add(bullet)
                bullet_list.add(bullet)
                click_sound.play()
            # if was a left key, then move player to left
            elif event.key == pygame.K_LEFT:
                x_speed = -3
            # if was right key, move player to right
            elif event.key == pygame.K_RIGHT:
                x_speed = 3
        elif event.type == pygame.KEYUP:
            if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT:
                x_speed = 0            
    # Call the update() method on all the sprites so that they all move appropiately
    all_sprites_list.update()  
    # update actual player position
    player.rect.x += x_speed   
    #don't let it get out of bounds
    if player.rect.x < 0:
        player.rect.x = 0  
    if player.rect.x > 675:
        player.rect.x = 675                
    # deal with each bullet appropiately
    for bullet in bullet_list:
        # See if it hit a block and put it into list after removing from screen
        block_hit_list = pygame.sprite.spritecollide(bullet, block_list, True)
        # For each block hit, remove the bullet and add to the score
        for block in block_hit_list:
            bullet_list.remove(bullet)
            all_sprites_list.remove(bullet)
            hit_sound.play()
            score += 1
            print(score)
        # Remove the bullet if it flies up off the screen
        if bullet.rect.y < -10:
            bullet_list.remove(bullet)
            all_sprites_list.remove(bullet)
    # See if player hit a block and put into list after removing from screen
    blocks_hit_player_list = pygame.sprite.spritecollide(player, block_list, False)
    # go thru this list
    for block in blocks_hit_player_list:
        # play boom
        hit_sound.play()        
        # stop game
        done = True         
    # now clear the screen, so that we can re-add all the stuff
    screen.blit(background_image, [0, 0])
    
    # add the score
    text = font.render("Score: " + str(score), True, RED)
    screen.blit(text, [550, 10])

    # Draw all the sprites
    all_sprites_list.draw(screen)
 
    # Go ahead and update the screen with what we've drawn.
    pygame.display.flip()
 
    # --- Limit to 20 frames per second
    #the higher the number the faster
    clock.tick(20)
pygame.quit()