class AlienInvasion:
    '''Class to manage game assesst'''
    def __init__(self):
        ''' Start the game'''

        pygame.init()
        self.settings = Settings()

        self.screen = pygame.display.set_mode(
            (self.settings.screen_width, self.settings.screen_height))
        pygame.display.set_caption("Alien Invasion")

        #instance to store game stats
        self.stats = GameStats(self)
        self.sb = Scoreboard(self)
        self.ship = Ship(self)
        self.bullets = pygame.sprite.Group()
        self.aliens = pygame.sprite.Group()
        self.alien_bullet = pygame.sprite.Group()

        self._create_fleet()

        self.play_button = Button(self, 'Start')

    def run_game(self):
        ''' Start the main loop for the game'''

        while True:
            self._check_events()

            if self.stats.game_active:
                self.ship.update()
                self._update_bullets()
                self._update_aliens()
            self._update_screen()

    def _check_events(self):
        ''' Respond to keypress and moust 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._check_play_button(mouse_pos)

    def _check_keydown_events(self, event):
        ''' Updating for keydown events'''
        if event.key == pygame.K_RIGHT:
            # move the ship to the right
            self.ship.moving_right = True

        elif event.key == pygame.K_LEFT:
            self.ship.moving_left = True

        elif event.key == pygame.K_q:
            old_high_score = self.stats.high_score
            self.sb.save_high_score(str(old_high_score))
            #print(old_high_score)
            sys.exit()

        elif event.key == pygame.K_SPACE:
            self._fire_bullet()

        elif event.key == pygame.K_p:
            self._restart_game()

    def _check_keyup_events(self, event):
        ''' Updating for keyup events'''
        if event.key == pygame.K_RIGHT:
            self.ship.moving_right = False

        elif event.key == pygame.K_LEFT:
            self.ship.moving_left = False

    def _fire_bullet(self):
        '''creates a new bullet and adds it to the bullets group'''
        if len(self.bullets) < self.settings.bullet_allowed:

            new_bullet = Bullet(self)
            self.bullets.add(new_bullet)

    def _update_screen(self):
        ''' Updating images on the screen and flip to the new screen'''
        # Redraw screen with for the background color
        self.screen.fill(self.settings.bg_color)
        self.ship.blitme()

        for bullet in self.bullets.sprites():
            bullet.draw_bullet()
        self.aliens.draw(self.screen)

        #draw score info
        self.sb.show_score()

        if not self.stats.game_active:
            self.play_button.draw_button()

        # make the most recently drawn screen visible
        pygame.display.flip()

    def _update_bullets(self):
        ''' updating the position of the bullet
        and getting ride of those at the top of the screen'''
        #updating bullets position
        self.bullets.update()

        #remove the disappeared bullets
        for bullet in self.bullets.copy():
            if bullet.rect.bottom <= 0:
                self.bullets.remove(bullet)
        #print(len(self.bullets))
        self._check_bullet_alien_collision()

    def _check_bullet_alien_collision(self):
        '''response to impacts'''
        # check if any bullets hit the aliens
        # if so lets remove the bullet and alien
        collisions = pygame.sprite.groupcollide(self.bullets, self.aliens,
                                                True, True)

        if collisions:
            for aliens in collisions.values():
                self.stats.score += self.settings.alien_points + len(aliens)
            self.sb.prep_score()
            self.sb.check_high_score()

        if not self.aliens:
            self._start_new_level()

    def _create_fleet(self):
        '''creating the fleet of aliens!'''
        #creating an alien and find the number of of aliens in a row
        #spacing between each alien is the width of one alien
        alien = Alien(self)
        alien_width, alien_height = alien.rect.size
        alien_width = alien.rect.width
        available_space_x = self.settings.screen_width - (2 * alien_width)
        num_aliens_x = available_space_x // (2 * alien_width)

        #determine how many rows we can add
        ship_height = self.ship.rect.height
        available_space_y = (self.settings.screen_height - (3 * alien_height) -
                             ship_height)
        num_rows = available_space_y // (3 * alien_height)

        #create the full fleet!
        for row_num in range(num_rows):
            for alien_num in range(num_aliens_x):
                self._create_alien(alien_num, row_num)

    def _create_alien(self, alien_num, row_num):
        # creating an alien and then placing it in a row
        alien = Alien(self)
        alien_width, alien_height = alien.rect.size
        alien.x = alien_width + 2 * alien_width * alien_num
        alien.rect.x = alien.x
        alien.rect.y = alien.rect.height + 2 * alien.rect.height * row_num
        self.aliens.add(alien)

    def _update_aliens(self):
        '''Check if the fleet is at the edge
        and Update the position of the aliens in the fleet'''
        self._check_fleet_edges()
        self.aliens.update()

        #look for alien-ship collisions
        if pygame.sprite.spritecollideany(self.ship, self.aliens):
            #print('Ship hit!!!')
            self._ship_hit()
        self._check_aliens_bottom()

    def _check_fleet_edges(self):
        '''respond to the event of the fleet hitting the edge of the screen'''
        for alien in self.aliens.sprites():
            if alien.check_edges():
                self._change_fleet_direction()
                break

    def _change_fleet_direction(self):
        '''drop the fleet and change its direction'''
        for alien in self.aliens.sprites():
            alien.rect.y += self.settings.fleet_drop_speed
        self.settings.fleet_direction *= -1

    def _ship_hit(self):
        '''response if ship is hit by alien'''
        if self.stats.ships_left > 0:
            # you lose a ship
            self.stats.ships_left -= 1
            self.sb.prep_ships()

            # get rid of any remaining aliens and bullets
            self.aliens.empty()
            self.bullets.empty()

            # create a new fleet and center the ship
            self._create_fleet()
            self.ship.center_ship()

            #pause
            sleep(0.5)
        else:
            self.stats.game_active = False
            pygame.mouse.set_visible(True)

    def _check_aliens_bottom(self):
        '''see if there are any aliens on the bottom'''

        screen_rect = self.screen.get_rect()
        for alien in self.aliens.sprites():
            if alien.rect.bottom >= screen_rect.bottom:
                self._ship_hit()
                break

    def _check_play_button(self, mouse_pos):
        ''' start a new game when play is clicked'''
        button_clicked = self.play_button.rect.collidepoint(mouse_pos)
        if button_clicked and not self.stats.game_active:
            self.settings.initialize_dynamic_settings()
            self._restart_game()

    def _restart_game(self):
        # reset game stats

        self.stats.reset_stats()
        self.stats.game_active = True
        #load the  images for score, level, ships lives, and high score
        self.sb.prep_images()

        # remove any of the bullets and aliens
        self.aliens.empty()
        self.bullets.empty()

        # create new fleet
        self._create_fleet()
        self.ship.center_ship()

        # hide mouse cursor
        pygame.mouse.set_visible(False)

    def _start_new_level(self):
        # destroy existing bullets and create new fleet
        self.bullets.empty()
        self._create_fleet()
        self.settings.increase_speed()

        # increase the level indication
        self.stats.level += 1
        self.sb.prep_level()
예제 #2
0
class AlienInvasion:
    """Overall class to manage game assets and behavior"""
    def __init__(self):
        """initialize the game, and create game resources"""
        pygame.init()
        self.settings = Settings()

        self.screen = pygame.display.set_mode(
            (self.settings.screen_width, self.settings.screen_height))
        pygame.display.set_caption("YAKS! in Space")

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

        self.ship = Ship(self)
        self.bullets = pygame.sprite.Group()
        self.boomerangs = pygame.sprite.Group()
        self.aliens = pygame.sprite.Group()

        self._create_fleet()

        # set the background color
        self.bg_color = self.settings.bg_color

        # Make the Play Button
        self.play_button = Button(self, "Play")

        # Create an instance to store game statistics and create a scoreboard.
        self.stats = GameStats(self)
        self.sb = Scoreboard(self)

    def run_game(self):
        """Start the main loop for the game"""
        while True:
            # Watch for keyboard and mouse events
            self._check_events()

            if self.stats.game_active:
                self.ship.update()
                self._update_bullets()
                self._update_aliens()
                self._update_boomerangs()

            self._update_screen()

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

    def _check_aliens_bottom(self):
        """Check if any aliens have reached the bottom of the screen."""
        screen_rect = self.screen.get_rect()
        for alien in self.aliens:
            if alien.rect.bottom >= screen_rect.bottom:
                # Treat this the same as if the ship got hit.
                self._ship_hit()
                break

    def _check_bullet_alien_collions(self):
        """respond to bullet-alien collisions."""
        # Check for any bullets that have hit aliens.
        # if so, get rid of the bullet and the alien.
        bullet_collisions = pygame.sprite.groupcollide(self.bullets,
                                                       self.aliens, True, True)
        if bullet_collisions:
            for aliens in bullet_collisions.values():
                self.stats.score += self.settings.alien_points * len(aliens)
            self.sb.prep_score()
            self.sb.check_high_score()

        # do the same thing for the boomerangs
        boomerang_collisions = pygame.sprite.groupcollide(
            self.boomerangs, self.aliens, False, True)
        if boomerang_collisions:
            for aliens in boomerang_collisions.values():
                self.stats.score += self.settings.alien_points * len(aliens)
            self.sb.prep_score()
            self.sb.check_high_score()

        if not self.aliens:
            # Destroy existing bullets and create new fleet.
            self.bullets.empty()
            self._create_fleet()
            self.settings.increase_speed()

            # Increase the level
            self.stats.level += 1
            self.sb.prep_level()

    def _check_events(self):
        """response to keypress 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._check_play_button(mouse_pos)

    def _check_fleet_edges(self):
        """Response appropriately if any aliens have reached an edge."""
        for alien in self.aliens.sprites():
            if alien.check_edges():
                self._change_fleet_direction()
                break

    def _check_keydown_events(self, event):
        """respond to keypresses"""
        if event.key == pygame.K_RIGHT:
            self.ship.moving_right = True
        elif event.key == pygame.K_LEFT:
            self.ship.moving_left = True
        elif event.key == pygame.K_q:
            sys.exit()

    def _check_keyup_events(self, event):
        if event.key == pygame.K_RIGHT:
            self.ship.moving_right = False
        elif event.key == pygame.K_LEFT:
            self.ship.moving_left = False
        elif event.key == pygame.K_SPACE:
            self._fire_bullet()
        elif event.key == pygame.K_b:
            self._fire_boomerang()

    def _check_play_button(self, mouse_pos):
        """Start a new game when the player clicks play."""
        button_clicked = self.play_button.rect.collidepoint(mouse_pos)
        if button_clicked and not self.stats.game_active:
            # Reset the game statistics
            self.stats.reset_stats()
            self.stats.game_active = True
            self.sb.prep_score()
            self.sb.prep_level()
            self.sb.prep_ships()

            # Reset the game settings
            self.settings.initialize_dynamic_settings()

            # Get rid of any remaining aliens and bullets
            self.aliens.empty()
            self.bullets.empty()

            # Create a new fleet and center the ship
            self._create_fleet()
            self.ship.center_ship()

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

    def _create_alien(self, alien_number, row_number):
        """Create an alien and place it in the row"""
        alien = Alien(self)
        alien_width, alien_height = alien.rect.size
        alien.x = alien_width + 2 * alien_width * alien_number
        alien.rect.x = alien.x
        alien.rect.y = alien.rect.height + 2 * alien.rect.height * row_number
        self.aliens.add(alien)

    def _create_fleet(self):
        """Create the fleet of aliens."""
        # Create an alien and find the number of aliens in a row
        # Spacing between each alien is equal to one alien width
        alien = Alien(self)
        alien_width, alien_height = alien.rect.size
        available_space_x = self.settings.screen_width - (2 * alien_width)
        number_aliens_x = available_space_x // (2 * alien_width)

        # Determine the number of rows of aliens that fit on the screen.
        ship_height = self.ship.rect.height
        available_space_y = (self.settings.screen_height - (3 * alien_height) -
                             ship_height)
        number_rows = available_space_y // (2 * alien_height)

        # Create teh full fleet of aliens
        for row_number in range(number_rows):
            for alien_number in range(number_aliens_x):
                self._create_alien(alien_number, row_number)

    def _fire_boomerang(self):
        """Creates a boomerang and sends it out"""
        if len(self.boomerangs) < self.settings.boomerang_allowed:
            new_boomerang = Boomerang(self)
            self.boomerangs.add(new_boomerang)

    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 _ship_hit(self):
        """Respond to the ship being hit by an alien."""

        # Confirm the player still has ships, otherwise the game over
        if self.stats.ships_left > 0:
            # Decrement ships_left.
            self.stats.ships_left -= 1
            self.sb.prep_ships()

            # Get rid of any remaining aliens and bullets
            self.aliens.empty()
            self.bullets.empty()
            self.boomerangs.empty()

            #Create a new fleet and center the ship
            self._create_fleet()
            self.ship.center_ship()

            #pause
            sleep(0.5)
        else:
            self.stats.game_active = False
            pygame.mouse.set_visible(True)

    def _update_aliens(self):
        """Update the position of all aliens in the fleet."""
        self._check_fleet_edges()
        self.aliens.update()
        if pygame.sprite.spritecollideany(self.ship, self.aliens):
            self._ship_hit()

        # look for aliens hitting the bottom of the screen.
        self._check_aliens_bottom()

    def _update_boomerangs(self):
        """update the position of the boomerangs and get rid of any off the map"""
        # update boomerang positions
        self.boomerangs.update()

        # Get rid of boomerangs that have returned below the ship
        screen_rect = self.screen.get_rect()

        for boomerang in self.boomerangs.copy():
            if boomerang.rect.top > screen_rect.bottom:
                self.boomerangs.remove(boomerang)

        if pygame.sprite.spritecollideany(self.ship, self.boomerangs):
            self._ship_hit()

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

        # Get rid of bullets that have disappeared.
        for bullet in self.bullets.copy():
            if bullet.rect.bottom <= 0:
                self.bullets.remove(bullet)

        self._check_bullet_alien_collions()

    def _update_screen(self):
        """Update images on the scren, and flip to the new screen."""
        self.screen.fill(self.bg_color)
        self.ship.blitme()
        for bullet in self.bullets.sprites():
            bullet.draw_bullet()
        self.aliens.draw(self.screen)
        self.boomerangs.draw(self.screen)

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

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

        # Make the most recent drawn screen visible.
        pygame.display.flip()
예제 #3
0
class AlienInvasion:
    """Klasa służaca do zarzadzania zasobami i sposobem działania gry  """
    def __init__(self):
        """Inicjalizacja gry i utworzenie jej zasoboów"""
        pygame.init()  # wyswietlanie tła
        self.settings = Settings()

        self.screen = pygame.display.set_mode(
            (self.settings.screen_width, self.settings.screen_height))
        # self.screen = pygame.display.set_mode((0,0), pygame.FULLSCREEN)# krotka definiujaca fullscrena
        # self.settings.screen_width = self.screen.get_rect().width
        # self.settings.screen_height = self.screen.get_rect().height

        pygame.display.set_caption("Inwazja obcych")

        #utworzenie egzemplarza do przechowywania danych
        #dane statystyczne w grze
        self.stats = GameStats(self)
        self.sb = Scoreboard(self)

        self.ship = Ship(
            self
        )  # utworzenie egemplrza klasy SHIP, wymaga przekazania obiektu klasy alieninvasion
        self.bullets = pygame.sprite.Group()
        self.aliens = pygame.sprite.Group()

        self._create_fleet()

        #utworzenie przycisku
        self.play_button = Button(self, msg="Graj")

    def run_game(self):
        """Rozpoczecie petli głownej gry."""
        while True:
            self._check_events()

            if self.stats.game_active:
                self.ship.update()
                self._bullet_update()
                self._update_aliens()

            self._update_screen()

    def _ship_hit(self):
        """reakcaj na uderzenie obcego w statek"""
        if self.stats.ships_left > 0:
            #zmniejszenie wartosci ships_left
            self.stats.ships_left -= 1
            self.sb.prep_ships()

            #usuniecie obcych i pociskow
            self.aliens.empty()
            self.bullets.empty()

            #utworzenie zawartosci listy aliens i bullets
            self._create_fleet()
            self.ship.center_ship()

            sleep(0.5)

        else:
            self.stats.ships_left -= 1
            self.sb.prep_ships()
            self.stats.game_active = False
            pygame.mouse.set_visible(True)

    def _create_fleet(self):
        """Utworzenie pelnej floty obcych"""
        #utworzenie obcego, i okreslenei ile obcych miesci sie w rzedzie
        alien = Alien(self)
        alien_width, alien_height = alien.rect.size
        available_space_x = self.settings.screen_width - (4 * alien_width)
        number_aliens_x = available_space_x // (2 * alien_width)

        #usalenie ile rzedow obcych zmiesci sie na ekranie
        ship_height = self.ship.rect.height
        available_space_y = (self.settings.screen_height - (5 * alien_height) -
                             ship_height)
        number_rows = available_space_y // (2 * alien_height)

        #pierwszy rzad obcych
        for row_number in range(number_rows):
            for alien_number in range(number_aliens_x):
                #tworzymy obecego i umieszczamy w rzedzie
                self._create_alien(alien_number, row_number)

    def _create_alien(self, alien_number, row_number):
        """Utworzenie obcego i umieszczenie go w rzedzie"""
        alien = Alien(self)
        alien_width, alien_height = alien.rect.size
        alien.x = alien_width + 2 * alien_width * alien_number
        alien.rect.x = alien.x
        alien.rect.y = alien.rect.height + 2 * alien.rect.height * row_number
        self.aliens.add(alien)

    def _bullet_update(self):
        """Uaktualnienie polozenia pociskow i usniecie tych nie widocznych"""
        # uaktualnia polozenie
        self.bullets.update()

        # usuniecie pociskow poza ekranem
        for bullet in self.bullets.copy():
            if bullet.rect.bottom <= 0:
                self.bullets.remove(bullet)

        self._check_bullet_alien_collisins()

    def _check_aliens_bottom(self):
        """sprawdzenie czy ktory kolwiek obcy dotarl do dolnej krawedzi ekranu"""
        screen_rect = self.screen.get_rect()
        for alien in self.aliens.sprites():
            if alien.rect.bottom >= screen_rect.bottom:
                self._ship_hit()
                break

    def _check_bullet_alien_collisins(self):
        # sprawdzanie czy pocisk trafil obcego, jesli tak osuwamy i pocisk i obcego
        collisions = pygame.sprite.groupcollide(self.bullets, self.aliens,
                                                True, True)

        if collisions:
            for aliens in collisions.values():
                self.stats.score += self.settings.alien_points * len(aliens)
            self.sb.prep_score()
            self.sb.check_high_score()
            print(self.sb.stats.score)

        if not self.aliens:
            # pozbycie sie pociskow i utworzenie nowej floty
            self.bullets.empty()
            self._create_fleet()
            self.settings.increase_speed()

            #inkrementacja numeru poziomu
            self.stats.level += 1
            self.sb.prep_level()

    def _check_events(self):
        """_metoda pomocnicza nie do wywołania dla egemplarza klasy"""
        """Reakcja na zdarzenie klawiatury i myszy"""

        for event in pygame.event.get():  # petla zdarzen
            if event.type == pygame.QUIT:
                sys.exit()
            elif event.type == pygame.MOUSEBUTTONDOWN:
                mouse_pos = pygame.mouse.get_pos()
                self._check_play_button(mouse_pos)
            elif event.type == pygame.KEYDOWN:  # sprawdzamy nacisniecie klawisz
                self._check_keydown_events(event)
            elif event.type == pygame.KEYUP:  # jesli klawisz podniesiony t
                # o nie przesuwamy
                self._check_keyup_events(event)

    def _check_keydown_events(self, event):
        """Reakacja na nacisniecie klawisza"""
        if event.key == pygame.K_RIGHT:  # czy nacisniety klawisz to prawy kursor
            self.ship.moving_right = True
        elif event.key == pygame.K_LEFT:
            self.ship.moving_left = True
        elif event.key == pygame.K_UP:
            self.ship.moving_up = True
        elif event.key == pygame.K_DOWN:
            self.ship.moving_down = True
        elif event.key == pygame.K_SPACE:
            self._fire_bullet()

        elif event.key == pygame.K_q:  # zamkniecie w przypadku wcisniecia q
            sys.exit()

    def _check_keyup_events(self, event):
        """Reakcja na zwolnienie klawisz"""
        if event.key == pygame.K_RIGHT:
            self.ship.moving_right = False
        elif event.key == pygame.K_LEFT:
            self.ship.moving_left = False
        elif event.key == pygame.K_UP:
            self.ship.moving_up = False
        elif event.key == pygame.K_DOWN:
            self.ship.moving_down = False

    def _check_play_button(self, mouse_pos):
        """rozpoczecie nowej gry po wcisnieciu przycisku"""
        button_clicked = self.play_button.rect.collidepoint(mouse_pos)
        if button_clicked and not self.stats.game_active:
            #wyzerowanie ustawien gry
            self.settings.initialize_dynamic_settings()
            self.stats.reset_stats()
            self.stats.game_active = True
            self.sb.prep_score()
            self.sb.prep_level()
            self.sb.prep_ships()

            #usuniecie listy aliens i bullets
            self.aliens.empty()
            self.bullets.empty()

            #utworzenie nowej floty i wysrodkowanie statku
            self._create_fleet()
            self.ship.center_ship()

            #ukrycie kursora myszy
            pygame.mouse.set_visible(False)

    def _fire_bullet(self):
        """Utworzenie nowego pocisku i dodanie go do grupy pociskow"""
        if len(self.bullets) < self.settings.bullet_alowed:
            new_bullet = Bullet(self)
            self.bullets.add(new_bullet)

    def _update_screen(self):
        """Uaktualnianie obrazu na ekranie"""
        # odswiezanie ekranu
        self.screen.fill(self.settings.bg_color)  # definicja tła
        self.ship.blitme()  # wyswietlenie statkum nad tłem
        for bullet in self.bullets.sprites():
            bullet.draw_bullet()

        self.aliens.draw(self.screen)

        #wyswietlenie inf o punktach
        self.sb.show_score()

        #wyswietlenie przycisku tylko gdy gra nie aktywna
        if not self.stats.game_active:
            self.play_button.draw_button()
        # wyswietlenie ostatnio zmodyfikowanego ekranu, odswiezanie ekranu
        pygame.display.flip()

    def _update_aliens(self):
        """Uaktualnienie polozenie wszystkich obcych we flocie"""
        self._check_fleet_edges()
        self.aliens.update()

        #wykrywanie kolizji miedzy obcym i statkiem
        if pygame.sprite.spritecollideany(self.ship, self.aliens):
            self._ship_hit()

        #wyszukanie obcych uderzajcych w dolna krawedz
        self._check_aliens_bottom()

    def _check_fleet_edges(self):
        """Odpowiednia reakcja gdy opcy dotrze do krawedzi ekranu"""
        for alien in self.aliens.sprites():
            if alien.check_edges():
                self._change_fleet_direction()
                break

    def _change_fleet_direction(self):
        """przesuniecie floty w dol i zmiana kierunku"""
        for alien in self.aliens.sprites():
            alien.rect.y += self.settings.fleet_drop_speed
        self.settings.fleet_direction *= -1