예제 #1
0
class Game():
    '''this is the main game class this class handel the '''
    def __init__(self):
        self.settings = Settings()  #creat a instance of Settings class
        self.screen = pygame.display.set_mode(
            (self.settings.height, self.settings.width))
        pygame.display.set_caption("Alian invator")
        self.rect = self.screen.get_rect()
        self.background_music = mixer.music.load("music/background.wav")

        # self.fire_music=mixer.music.load("music/background.wav")

        #allow to acces screen right lefe top and bollom etc
        self.ship = Ship(self)
        self.stats = GameState(self)
        self.scoreboard = Scoreboard(self)
        self.bullets = pygame.sprite.Group()
        self.alien = pygame.sprite.Group()
        self.play_button = Button(self, "play")
        self.create_fleet()

    def main(self):
        #main while loop
        mixer.music.play(-1)
        while True:

            self._event()
            self.ship.ship_move()
            self.update_bullets()
            self.update_alien()

            #update the display
            self._update_display()
            #control the frame rate
            clock.tick(60)

    #update the display
    def _update_display(self):
        #fill the display
        self.screen.fill(self.settings.black)
        #draw ship
        self.ship.blit_me()
        # display all the  bullet in sprites group
        for bullet in self.bullets.sprites():
            bullet.draw_bullet()
        self.alien.draw(self.screen)
        self.scoreboard.show_score()

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

        pygame.display.flip()

    #chak event
    def _event(self):
        '''
        this fucntion chack any kind of event like key pressed or key up and 
        depanding on the event type it's run functions 
        '''

        #collect all the event in a list
        for event in pygame.event.get():
            #chack if game is cross or not
            if event.type == pygame.QUIT:
                sys.exit()
            #chack any event is keydonw or not
            elif event.type == pygame.KEYDOWN:

                self.key_down(event)
                self.fire_bullets(event)

            elif event.type == pygame.KEYUP:
                self.key_up(event)

            elif event.type == pygame.MOUSEBUTTONDOWN:
                mouse_pos = pygame.mouse.get_pos()
                self.click_play(mouse_pos)

    def update_bullets(self):
        '''
        chack the bullet activaties like move it and if it hit the top of the screen 
        then remove the bullet ,chack the it cullidite with the  buttom  
        
        '''

        self.bullets.update()
        for Bullet in self.bullets.copy():
            if Bullet.rect.bottom < 0:
                self.bullets.remove(Bullet)
        self.collision_and_new_alian()

    def key_up(self, event):
        """ chack the key up event """
        if event.key == pygame.K_a:
            self.ship.left = False

        elif event.key == pygame.K_d:
            self.ship.right = False

    def key_down(self, event):
        """ chack the key down event"""
        if event.key == pygame.K_a:
            self.ship.left = True

        elif event.key == pygame.K_d:
            self.ship.right = True

    def fire_bullets(self, event):
        """this function handle bullet movement and maintain bullet limite """
        if event.key == pygame.K_SPACE:
            if len(self.bullets) < self.settings.bullet_limit:
                fire = mixer.Sound("music/gun_sound_1.mp3")
                fire.play()
                new_bullets = Bullet(self)
                self.bullets.add(new_bullets)

    def create_fleet(self):
        """ create alian fleet and chack the cullsion adjust the alian positon
        create row and collom of the alian 
        
        
        """

        alien = Alien(self)
        alien_width, alien_height = alien.rect.size
        avilable_space_x = self.settings.width - (2 * alien_width)
        number_of_alian = avilable_space_x // (2 * alien_width)
        Ship_height = self.ship.rect.height
        avilable_space_y = self.settings.height - (3 *
                                                   alien_height) - Ship_height
        number_row = avilable_space_y // (2 * alien_height)

        for row_number in range(number_row - 5):
            for alien in range(number_of_alian + 4):
                self.row(alien, alien_width, row_number)

    def row(self, alien, alien_width, row_number):
        '''create a row of alian '''
        new_alien = Alien(self)
        alien_width, alien_height = new_alien.rect.size
        new_alien.rect.x = alien_width + 2 * alien_width * alien
        new_alien.rect.y = new_alien.rect.height + 2 * alien_height * row_number
        self.alien.add(new_alien)

    def update_alien(self):
        self.chk_fleet_edgs()
        self.alien.update()
        if pygame.sprite.spritecollideany(self.ship, self.alien):
            self.ship_hit()
        self.chack_alian_bottom()


#chak move metnt

    def chk_fleet_edgs(self):
        for alien in self.alien.sprites():
            if alien.chack_edgs():
                self.change_direction()
                break

    def change_direction(self):
        for alien in self.alien.sprites():
            alien.rect.y += self.settings.fleet_drop
        self.settings.fleet_direction *= -1

    def collision_and_new_alian(self):
        collisions = pygame.sprite.groupcollide(self.bullets, self.alien, True,
                                                True)

        if collisions:
            explosion = mixer.Sound("music/gun_sound_2.mp3")
            explosion.play()
            self.stats.score += self.settings.alian_point
            self.scoreboard._prep_score()
            self.scoreboard._prep_ships()
        if not self.alien:
            self.bullets.empty()
            self.create_fleet()
            self.settings.level_up()

    def ship_hit(self):
        """ handel ship hit  with alian  reduce life of the ship , reduce the ship """

        if self.settings.ship_limit > 0:
            self.settings.ship_limit -= 1
            self.scoreboard._prep_ships()

            self.alien.empty()
            self.bullets.empty()
            self.create_fleet()
            self.ship.center_ship()

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

    def chack_alian_bottom(self):
        for alien in self.alien.sprites():
            if alien.rect.bottom > self.rect.bottom:
                self.ship_hit()
                break

    def click_play(self, mouse_pos):
        botton_clicked = self.play_button.rect.collidepoint(mouse_pos)
        if botton_clicked and self.play_button.rect.collidepoint(mouse_pos):
            pygame.mouse.set_visible(False)
            self.settings.initialize_dynamic_setting()
            self.stats.reset_state()
            self.stats.game_active = True
            self.alien.empty()
            self.bullets.empty()
            self.create_fleet()
            self.ship.center_ship()
예제 #2
0
class Game():
    def __init__(self):
        pygame.init() # initialization pygame

        self.settings = Settings() # creating settings instance
        self.clock = pygame.time.Clock() # creating clock to contro fps

        self.win = pygame.display.set_mode((self.settings.win_width, self.settings.win_height)) # setting game window
        self.bg_color = self.settings.bg_color # background color
        pygame.display.set_caption("Alien shooter") # setting game name

        self.stats = GameStats(self)
        self.sb = Scoreboard(self)
        self.ship = Ship(self) # creating ship instance

        self.bullets = pygame.sprite.Group() # creating sprite group to hold bullets
        self.aliens = pygame.sprite.Group() # creating sprite group to hold alien fleet

        self._create_fleet() # creating alien fleet using (_create_fleet() helper method)

        self.play_button = Button(self, "Play")

    def run_game(self):
        while True:
            self.clock.tick(self.settings.FPS)
            self._check_event() # checking every event in a for loop
            if self.stats.game_active:
                self.ship.update_ship_position() # update the ship position in every loop after a valid keypress
                self.bullets.update() # update the position of every bullet in the self.bullets group
                self._remove_bullets() # delete the bullet once they get past the screen
                self._update_alien() # update alien's x and y position
                self._update_screen() # update all the screen elements
            else:
                self._update_screen()

    def _check_event(self):
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                sys.exit()
            elif event.type == pygame.KEYDOWN:
                self._check_keydown(event)
            elif event.type == pygame.KEYUP:
                self._check_keyup(event)
            elif event.type == pygame.MOUSEBUTTONDOWN:
                mouse_pos = pygame.mouse.get_pos()
                self._check_play_button(mouse_pos)

    def _check_play_button(self, mouse_pos):
        button_clicked = self.play_button.rect.collidepoint(mouse_pos)
        if button_clicked and not self.stats.game_active: # check if button has clicked and game is active
            self.settings._levelup_settings() # reset changing settings values when play button is clicked
            self.stats.reset_stats() # reset game stats
            self.stats.game_active = True # make game state active
            self.sb._prep_score() # prepare score image
            self.sb._prep_ship()

            self.aliens.empty() # removing all the remaining aliens
            self.bullets.empty() # removing all the remaining bullets

            self._create_fleet() # create new fleet
            self.ship.center_ship() # bring the alien ship to the center
            pygame.mouse.set_visible(False) # setting mouse visibility of once the button is clicked

    def _check_keydown(self, event):
        if event.key == pygame.K_q:
            sys.exit()
        elif 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_SPACE:
            self._fire_bullet() # pressing space will triger _fire_bullet() helper method

    def _check_keyup(self, event):
        if event.key == pygame.K_RIGHT:
            self.ship.moving_right = False
        if event.key == pygame.K_LEFT:
            self.ship.moving_left = False

    def _fire_bullet(self):
        if len(self.bullets) < self.settings.bullet_allowed and self.stats.game_active: # if self.bullet group has lass than specefied number
            # of bullets, only then add new bullet
            new_bullet = Bullet(self) # creates instance of Bullet class
            self.bullets.add(new_bullet) # add that instance to self.bullets group

    def _remove_bullets(self):
        for bullet in self.bullets.copy():
            if bullet.rect.bottom <= 0:
                self.bullets.remove(bullet)
        self._bullet_alien_collisions()

    def _bullet_alien_collisions(self):
        collisions = pygame.sprite.groupcollide(self.bullets, self.aliens, True, True)
        if collisions: # check if collision happed between ship and bullet
            for aliens in collisions.values():
                self.stats.score += self.settings.alien_point * len(aliens) # if yes then increment schore
            self.sb._prep_score() # prep score image of that score
            self.sb.check_high_score() # checking if current score is new high score

        if  len(self.aliens) == 0: # check if all aliens has been shot donw //Basically we are entering a new level if all aliens are shot down
            self.bullets.empty() # if yes then empty the bullet group
            self._create_fleet() # create new alien fleet
            self.settings.increase_speed() # increase game speed
            self.stats.level += 1
            self.sb._prep_level()

    def _create_fleet(self):
        alien = Alien(self) # creating alien instance
        alien_width, alien_height = alien.rect.size # storing alien's width and height in two variable
        available_space_x = self.settings.win_width - (2 * alien_width) # checking available x space
        alien_number_x = available_space_x // (2 * alien_width) # checking number of alien that can fit in x space

        ship_height = self.ship.rect.height # accessing ship's height element
        available_space_y = self.settings.win_height - (3 * alien_height) - (ship_height + 60)# checking available y space ####### unstable change
        alien_number_y = available_space_y // (2 * alien_height) # checking number of alien that can fin in y space

        #creating the first row of alien
        for row_number in range(alien_number_y):
            for alien_number in range(alien_number_x):
                self._create_alien(alien_number, row_number)

    def _create_alien(self, alien_number, row_number):
        alien = Alien(self) # create alien instance
        alien_width, alien_height = alien.rect.size # storing alien's width in a variable
        alien.x = alien_width + (alien_number * 2 * alien_width)
        alien.rect.x = alien.x # setting rect's x position
        alien.rect.y = 15 + alien.rect.height + (2 * alien_height * row_number) # setting aliens y position ######### unstable change
        self.aliens.add(alien)

    def _update_alien(self):
        self._check_fleet_edges()
        self.aliens.update() # call update() medthod from alien class on self.aliens; sprite group
        if pygame.sprite.spritecollideany(self.ship, self.aliens): # check collistion between ship and alines
            self._ship_hit() # if collision happens; call _ship_hit() medthod
        self._bottom_hit() # check if any of the aliens has reached bottom

    def _check_fleet_edges(self):
        for alien in self.aliens.sprites(): # loop through every alien instance in self.aliens group
            if alien.check_edge(): # call check_edge() medthod on every every alien instance
                self._change_fleet_direction() # call _change_fleet_direction() when condition is Ture
                break # break out of this loop once _change_fllet_direction() is called

    def _change_fleet_direction(self):
        for alien in self.aliens.sprites(): # loop through every alien instance in self.aliens group
            alien.rect.y += self.settings.fleet_drop_speed # increase rect's y position
        self.settings.fleet_direction *= -1 # multiply fleet_directin with nagative one

    def _ship_hit(self):
        if self.stats.ship_left > 0:
            # decrement ship number
            self.stats.ship_left -= 1
            self.sb._prep_ship()

            # removing remaining ship and bullet
            self.aliens.empty()
            self.bullets.empty()

            # creating new fleet and centering ship
            self._create_fleet()
            self.ship.center_ship()
            # pause
            time.sleep(2)
        else:
            self.stats.game_active = False
            pygame.mouse.set_visible(True)

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

    def _update_screen(self):
        self.win.fill(self.bg_color)
        self.ship.draw_ship() # fetching draw ship method from Ship class of ship module
        for bullet in self.bullets.sprites():
            bullet.draw_bullet() # draws every bullet instance present in self.bullets group

        self.aliens.draw(self.win) # draws every allien in self.alines group
        self.sb.draw_score() # draws score

        if not self.stats.game_active: # draw the play button when the game is inactive
            self.play_button.draw_button()
        pygame.display.update()