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