Esempio n. 1
0
class BlueSky:
    """Makes a Pygame window with a blue background."""

    def __init__(self):
        """Initialize the game."""
        pygame.init()
        self.settings = Settings()
        self.screen = pygame.display.set_mode ((0, 0), pygame.FULLSCREEN)
        self.settings.screen_width = self.screen.get_rect().width
        self.settings.screen_height = self.screen.get_rect().height
        pygame.display.set_caption("Blue Sky")
        self.stats = GameStats(self)
        self.rocket = Rocket(self)
        self.bullets = pygame.sprite.Group()
        self.ufos = pygame.sprite.Group()
        self._create_fleet()

    def run_game(self):
        """Start the main loop for the game."""
        while True:
            self._check_events()
            if self.stats.game_active:
                self.rocket.update()
                self._update_bullets()
                self._update_ufos()        
            self._update_screen()

    def _check_events(self):
        """Respond to keypresses and key releases."""
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                sys.exit()
            elif event.type == pygame.KEYDOWN:
                self._check_keydown_events(event)
            elif event.type == pygame.KEYUP:
                self._check_keyup_events(event)

    def _check_keydown_events(self, event):
        """Respond to keypresses."""
        if event.key == pygame.K_UP:
            self.rocket.moving_up = True
        elif event.key == pygame.K_DOWN:
            self.rocket.moving_down = True
        elif event.key == pygame.K_q:
            sys.exit()
        elif event.key == pygame.K_SPACE:
            self._fire_bullet()

    def _check_keyup_events(self, event):
        """Respond to key releases."""
        if event.key == pygame.K_DOWN:
            self.rocket.moving_down = False
        elif event.key == pygame.K_UP:
            self.rocket.moving_up = False

    def _fire_bullet(self):
        """Create a new bullet and add it to the bullets group."""
        if len(self.bullets) < self.settings.bullets_allowed:
            new_bullet = Bullet(self)
            self.bullets.add(new_bullet)

    def _update_bullets(self):
        """Update position of bullets and get rid of old bullets."""
        self.bullets.update()
        for bullet in self.bullets.copy():
            if bullet.rect.left >= self.rocket.screen_rect.right:
                self.bullets.remove(bullet)
        self._check_bullet_ufo_collisions()

    def _check_bullet_ufo_collisions(self):
        """Respond to bullet-UFO collisions."""
        # Remove any bullets and aliens that have collided.
        collisions = pygame.sprite.groupcollide(
                self.bullets, self.ufos, True, True)
        if not self.ufos:
            # Destroy existing bullets and create new fleet.
            self.bullets.empty()
            self._create_fleet()

    def _update_ufos(self):
        """Update the position of all UFOs in the fleet."""
        self._check_fleet_edges()
        self.ufos.update()
        # Look for UFO-rocket collisions.
        if pygame.sprite.spritecollideany(self.rocket, self.ufos):
            self._rocket_hit()
        self._check_ufos_left()

    def _rocket_hit(self):
        """Respond to the rocket being hit by an UFO."""
        if self.stats.rockets_left > 0:
            # Decrement rockets left.
            self.stats.rockets_left -= 1
            # Get rid of any remaining UFOS and bullets.
            self.ufos.empty()
            self.bullets.empty()
            # Create a new fleet and center the rocket.
            self._create_fleet()
            self.rocket.center_rocket()
            sleep(1)
        else:
            self.stats.game_active = False

    def _check_ufos_left(self):
        """Check if any UFOS have reached the left side of the sceen."""
        screen_rect = self.screen.get_rect()
        for ufo in self.ufos.sprites():
            if ufo.rect.left <= screen_rect.left:
                self._rocket_hit()
                break

    def _create_fleet(self):
        """Create the fleet of UFO."""
        # Create an UFO and find the number of UFOs in a row.
        ufo = Ufo(self)
        ufo_width, ufo_height = ufo.rect.size
        rocket_width = self.rocket.rect.width
        available_space_x = (self.settings.screen_width - 
                                (3 * ufo_width) - rocket_width)
        number_ufo_x = available_space_x // (2 * ufo_width)
        # Determine the number of rows of UFOs that fit on the screen.
        available_space_y = self.settings.screen_height - (2 * ufo_height)
        number_rows = available_space_y // (2 * ufo_height)
        # Create the full fleet of UFOs.
        for row_number in range(number_rows):
            for ufo_number in range(number_ufo_x):
                self._create_ufo(ufo_number, row_number)

    def _create_ufo(self, ufo_number, row_number):
        """Create and UFO and place it in the row."""
        ufo = Ufo(self)
        ufo_width, ufo_height = ufo.rect.size
        ufo.x = 5 * ufo_width + 2 * ufo_width * ufo_number
        ufo.rect.x = ufo.x
        ufo.y = ufo_height + 2 * ufo_height * row_number
        ufo.rect.y = ufo.y
        self.ufos.add(ufo)

    def _check_fleet_edges(self):
        """Respond appropriately if any UFO reached an edge."""
        for ufo in self.ufos.sprites():
            if ufo.check_edges():
                self._change_fleet_direction()
                break

    def _change_fleet_direction(self):
        """Drop the entire fleet and change the fleet's direction."""
        for ufo in self.ufos.sprites():
            ufo.rect.x -= self.settings.fleet_drop_speed
        self.settings.fleet_direction *= -1 

    def _update_screen(self):
        """Update images on the screen, and flip to the new screen."""
        self.screen.fill(self.settings.bg_color)
        self.rocket.blitme()
        for bullet in self.bullets.sprites():
            bullet.draw_bullet()
        self.ufos.draw(self.screen)
        pygame.display.flip()
class SidewaysRocket:
    """overrall class to manage assets and behavior"""

    def __init__(self):
        """intialize the game, and create resources"""
        pygame.init()
        self.settings = Settings()

        #Sets the window size and caption
        self.screen = pygame.display.set_mode(
            (self.settings.screen_width, self.settings.screen_height))
        pygame.display.set_caption("Sideways Rocket Game")

        #Create an instance to store game statistics
        self.stats = GameStats(self)

        #import the rocket and make an instance of it
        self.rocket = Rocket(self)
        #import the laser sprites
        self.lasers = pygame.sprite.Group()
        #import the enemy sprites
        self.enemies = pygame.sprite.Group()

        self._create_enemies()

    def run_game(self):
        """Start the main loop of the game."""
        while True:
            #watch for keyboard and mouse events
            self._check_events()
            if self.stats.game_active:
                self.rocket.update()
                self._update_lasers()
                self._update_enemy()
            self._update_screen()

    def _check_events(self):
        """Respond to keypresses and mouse events."""
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                sys.exit()
            elif event.type == pygame.KEYDOWN:
                self._check_keydown_events(event)
            elif event.type == pygame.KEYUP:
                self._check_keyup_events(event)

    def _update_screen(self):
        """Update images on the screen and flip to a new screen"""
        #Redraw the screen during each pass through the loop
        self.screen.fill(self.settings.bg_color)
        #draw the rocket
        self.rocket.blitme()
        #draw lasers
        for laser in self.lasers.sprites():
            laser.draw_laser()
        
        #draw the enemies
        self.enemies.draw(self.screen)
        #Make the most recently drawn screen visible
        pygame.display.flip()

    def _check_keydown_events(self, event):
        """Respond to keypress down events"""
        if event.key == pygame.K_w:
            #move the rocket up
            self.rocket.moving_up = True
        elif event.key == pygame.K_s:
            #move the rocket down
            self.rocket.moving_down = True
            #move the rocket to the right
        elif event.key == pygame.K_d:
            self.rocket.moving_right = True
            #move the rocket to the left
        elif event.key == pygame.K_a:
            self.rocket.moving_left = True
        elif event.key == pygame.K_SPACE:
            self._fire_laser()
        elif event.key == pygame.K_q:
            sys.exit()

    def _check_keyup_events(self, event):
        """Respond to keypress releases"""
        #stop moving the rocket
        if event.key == pygame.K_w:
            self.rocket.moving_up = False
        if event.key == pygame.K_s:
            self.rocket.moving_down = False
        if event.key == pygame.K_d:
            self.rocket.moving_right = False
        if event.key == pygame.K_a:
            self.rocket.moving_left = False

    def _fire_laser(self):
        """Create a new laser and add it to the lasers group"""
        if len(self.lasers) < self.settings.lasers_allowed:
            new_laser = Laser(self)
            self.lasers.add(new_laser)
        
    def _update_lasers(self):
        """Update the position of lasers and get rid of old lasers"""
        #update laser positions
        self.lasers.update()
        #Get rid of bullets that have disappeared
        for laser in self.lasers.copy():
            if laser.rect.left >= self.rocket.screen_rect.right:
                self.lasers.remove(laser)
        
        self._check_laser_enemy_collisons()
    
    def _create_enemies(self):
        """Create an enemy ship"""
        enemy_number = random.randint(1,5)
        for _ in range(enemy_number):
            enemy = Enemy(self)
            enemy.rect.y = random.randint(1, self.settings.screen_height - 50)
            self.enemies.add(enemy)
            
    def _update_enemy(self):
        """move the enemy to the left"""
        self.enemies.update()
        for enemy in self.enemies.copy():
            if enemy.rect.right <= 0:
                self.enemies.remove(enemy)
        
        #look for enemy-rocket collision
        if pygame.sprite.spritecollideany(self.rocket, self.enemies):
            self._rocket_hit()
    
    def _check_laser_enemy_collisons(self):
        #check for any lasers that have hit enemies
        #if so get rid of the alien and the bullet
        collisions = pygame.sprite.groupcollide(self.lasers, self.enemies, True, True)

        if not self.enemies:
            #destroy lasers and create a new fleet.
            self.lasers.empty()
            self._create_enemies()
    
    def _rocket_hit(self):
        if self.stats.rockets_left > 0:
            #decreaset the remaining rockets
            self.stats.rockets_left -= 1
            #get rid of any remaining
            self.enemies.empty()
            self.lasers.empty()

            #Pause
            sleep(0.5)

            #restore the ship
            self.rocket.center_rocket()
            self._create_enemies()
        
        else:
            self.stats.game_active = False
Esempio n. 3
0
class SpaceBattle:
    """Main class that manages game's assets"""

    def __init__(self):
        """Initialize the game, and create game resources."""
        pygame.init()

        # Get game's settings
        self.settings = Settings()

        # Create a main display
        self.screen = pygame.display.set_mode((1200, 800))

        # Set a main display's name
        pygame.display.set_caption("Space Battle")

        # Create an instance to store game statistics
        self.stats = GameStats(self)

        # Create a scoreboard
        self.scoreboard = Scoreboard(self)

        # Create a rocket
        self.rocket = Rocket(self)

        # Create a list of bullets
        self.bullets = pygame.sprite.Group()

        # Create a fleet of spaceships
        self.spaceships = pygame.sprite.Group()
        self._create_fleet()

        # Make the Start button.
        self.start_button = PlayButton(self, "Start")

    def run_game(self):
        """Start game's main loop."""
        while True:
            # Monitors key presses and releases
            self._check_key_mouse_events()

            # Updates positions of game's moving elements
            self._update_positions()

            # Flipping the main screen
            self._update_screen()

    def _update_positions(self):
        """Update the position of a rocket, bullets, and spaceships."""
        if self.stats.game_active:
            self.rocket.update()
            self._update_bullets()
            self._update_spaceships()

    def _check_key_mouse_events(self):
        """Respond to key presses and mouse events."""
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                sys.exit()
            elif event.type == pygame.KEYDOWN:
                self._check_keydown_events(event)
            elif event.type == pygame.KEYUP:
                self._check_keyup_events(event)
            elif event.type == pygame.MOUSEBUTTONDOWN:
                mouse_pos = pygame.mouse.get_pos()
                self._press_play_button(mouse_pos)

    def _press_play_button(self, mouse_pos):
        """Start a new game when the player clicks Play."""

        # Returns true if the point of a mouse click overlaps
        # with the start button
        button_clicked = self.start_button.rect.collidepoint(mouse_pos)

        # If the button is clicked and the game has not started yet,
        # it means player starts a new game. So, reset the game.
        if button_clicked and not self.stats.game_active:
            self._reset_dynamic_settings()
            self._reset_games_stats()

            # Get rid of any remaining spaceships
            self.spaceships.empty()

            # Get rid of any remaining bullets
            self.bullets.empty()
            
            # Create a new fleet
            self._create_fleet()

            # Center the rocket
            self.rocket.center_rocket()

            # Hide the mouse cursor.
            pygame.mouse.set_visible(False)

    def _reset_games_stats(self):
        """Reset the game statistics."""
        self.stats.reset_stats()
        self.stats.game_active = True
        self.scoreboard.set_score()
        self.scoreboard.set_level()
        self.scoreboard.set_rockets()

    def _reset_dynamic_settings(self):
        """Reset the game's dynamic settings."""
        self.settings.initialize_dynamic_settings()

    def _check_keydown_events(self, event):
        """Respond to keypresses."""
        if event.key == pygame.K_RIGHT:
            self.rocket.moving_right = True
        elif event.key == pygame.K_LEFT:
            self.rocket.moving_left = True
        elif event.key == pygame.K_UP:
            self.rocket.moving_up = True
        elif event.key == pygame.K_DOWN:
            self.rocket.moving_down = True
        elif event.key == pygame.K_q:
            sys.exit()
        elif event.key == pygame.K_SPACE:
            self._fire_bullet()

    def _check_keyup_events(self, event):
        """Respond to key releases."""
        if event.key == pygame.K_RIGHT:
            self.rocket.moving_right = False
        elif event.key == pygame.K_LEFT:
            self.rocket.moving_left = False
        elif event.key == pygame.K_UP:
            self.rocket.moving_up = False
        elif event.key == pygame.K_DOWN:
            self.rocket.moving_down = False

    def _fire_bullet(self):
        """
        If the number of current bullets on the screen
        is less than number of bullets allowed to be fired, then
        create a new bullet and add it to the bullets group.
        """
        if len(self.bullets) < self.settings.bullets_allowed:
            new_bullet = Bullet(self)
            self.bullets.add(new_bullet)

    def _update_bullets(self):
        """Update position of bullets and get rid of old bullets."""
        # Update bullet positions.
        self.bullets.update()

        self._clean_off_screen_bullets()

        self._check_bullet_spaceship_collisions()

    def _clean_off_screen_bullets(self):
        """Get rid of bullets that are off screen."""
        for bullet in self.bullets.copy():
            if bullet.rect.bottom <= 0:
                self.bullets.remove(bullet)

    def _check_bullet_spaceship_collisions(self):
        """Respond to bullet-spaceship collisions."""

        # Returns dictionary containing bullets (key) and spaceships (values) that
        # were hit
        collisions = pygame.sprite.groupcollide(
                self.bullets, self.spaceships, True, True)

        self._update_total_score(collisions)

        self._increase_difficulty()

    def _increase_difficulty(self):
        """
        If there are no more spaceships on the screen, the
        increase the difficulty of the game
        """
        if not self.spaceships:
            # Destroy existing bullets and create new fleet.
            self.bullets.empty()
            self._create_fleet()
            self.settings.increase_speed()

            # Increase level.
            self.stats.level += 1
            self.scoreboard.set_level()

    def _update_total_score(self, collisions):
        """Update the total score on the game's screen"""
        # If collision dictionary exists, then add spaceships' total value to
        # a score.
        if collisions:
            for spaceships in collisions.values():
                self.stats.score += self.settings.spaceship_points * len(spaceships)

            # Create new image of updated total score
            self.scoreboard.set_score()
            self.scoreboard.check_high_score()

    def _update_spaceships(self):
        """
        Check if the fleet is at an border of a screen,
          then update the positions of spaceships' fleet.
        """
        self._check_fleet_edges()
        self.spaceships.update()

        # If the rocket touches an spaceship, then rocket is hit
        if pygame.sprite.spritecollideany(self.rocket, self.spaceships):
            self._rocket_hit()

        self._check_spaceships_bottom()

    def _check_spaceships_bottom(self):
        """Check if any spaceships have reached the bottom of the screen."""
        screen_rect = self.screen.get_rect()
        for spaceship in self.spaceships.sprites():
            if spaceship.rect.bottom >= screen_rect.bottom:
                # Treat this the same as if the rocket got hit.
                self._rocket_hit()
                break

    def _rocket_hit(self):
        """Respond to the rocket being hit by an spaceship."""
        if self.stats.rockets_left > 0:
            # Decrement rockets_left, and update scoreboard.
            self.stats.rockets_left -= 1
            self.scoreboard.set_rockets()
            
            # Get rid of any remaining spaceships and bullets.
            self.spaceships.empty()
            self.bullets.empty()
            
            # Create a new fleet and center the rocket.
            self._create_fleet()
            self.rocket.center_rocket()
            
            # Pause a game to let player see what happened
            sleep(0.5)
        else:
            self.stats.game_active = False
            pygame.mouse.set_visible(True)

    def _create_fleet(self):
        """Create the fleet of spaceships."""

        # Create an spaceship and find the number of spaceships in a row.
        # Spacing between each spaceship is equal to one spaceship width.
        spaceship = SpaceShip(self)
        spaceship_width, spaceship_height = spaceship.rect.size

        # Calculate the number of spaceships in a row
        # (2 * spaceship_width) creates margins on either side of a screen
        available_space_x = self.settings.screen_width - (2 * spaceship_width)
        number_spaceships_x = available_space_x // (2 * spaceship_width)
        
        # Determine the number of rows of spaceships that fit on the screen.
        rocket_height = self.rocket.rect.height
        available_space_y = (self.settings.screen_height -
                                (18 * spaceship_height) - rocket_height)
        number_rows = available_space_y // (2 * spaceship_height)
        
        # Create the full fleet of spaceships.
        for row_number in range(number_rows):
            for spaceship_number in range(number_spaceships_x):
                self._create_spaceship(spaceship_number, row_number)

    def _create_spaceship(self, spaceship_number, row_number):
        """Create an spaceship and place it in the row."""
        spaceship = SpaceShip(self)
        spaceship_width, spaceship_height = spaceship.rect.size
        spaceship.x = spaceship_width + 2 * spaceship_width * spaceship_number
        spaceship.rect.x = spaceship.x
        spaceship.rect.y = 3.5 * spaceship.rect.height + 2 * spaceship.rect.height * row_number
        self.spaceships.add(spaceship)

    def _check_fleet_edges(self):
        """
        If any spaceship touches screen's edges,
        then change the direction of a fleet.
        """
        for spaceship in self.spaceships.sprites():
            if spaceship.check_edges():
                self._change_fleet_direction()
                break
            
    def _change_fleet_direction(self):
        """Drop the entire fleet and change the fleet's direction."""
        for spaceship in self.spaceships.sprites():
            spaceship.rect.y += self.settings.fleet_drop_speed
        self.settings.fleet_direction *= -1

    def _update_screen(self):
        """Update images on the screen, and flip to the new screen."""
        self.screen.fill(self.settings.bg_color)

        # Draw a rocket
        self.rocket.blitme()

        # Draw bullets
        for bullet in self.bullets.sprites():
            bullet.draw_bullet()

        # Draw spaceships
        self.spaceships.draw(self.screen)

        # Draw the score information.
        self.scoreboard.show_score()

        # Draw the play button if the game is inactive.
        if not self.stats.game_active:
            self.start_button.draw_button()

        pygame.display.flip()