class AlienInvasion: def __init__(self): pygame.init() #intializing components of game self.settings = Settings() #create an instance of Settings class self.screen = pygame.display.set_mode( (self.settings.height, self.settings.width)) #set the size of regular window #Fullscreen 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("Alien Invasion") #set the name of game self.stats = GameStats(self) self.ship = Ship(self) #passing the current instance of AlienInvasion self.bullets = pygame.sprite.Group( ) #create instance of sprite.Group class self.aliens = pygame.sprite.Group() self.sb = ScoreBoard(self) self._create_fleet() self.crash_sound = pygame.mixer.Sound( "Explosion+1.wav") #save audion in self.crash_sound self.laser_sound = pygame.mixer.Sound("Laser.wav") self.ship_hit_sound = pygame.mixer.Sound("Explosion+5.wav") #Make play button self.play_button = Button(self, "Play") def run_game(self): while True: #while game is running self._check_events() if self.stats.game_active: self.ship.update() self._update_bullets() self._update_aliens() self._update_screen() def _check_events(self): for event in pygame.event.get(): #keyboard and mouse events if event.type == pygame.QUIT: #if clicked on the close window button pygame.quit() sys.exit() # then exit the game elif event.type == pygame.KEYDOWN: self._check_key_down(event) elif event.type == pygame.KEYUP: self._check_key_up(event) elif event.type == pygame.MOUSEBUTTONDOWN: mouse_pos = pygame.mouse.get_pos() self._check_play_button(mouse_pos) def _check_key_down(self, event): 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: with open("High_Score.txt", 'w') as hs: hs.write((str(self.stats.high_score))) pygame.quit() sys.exit() elif event.key == pygame.K_SPACE: self._fire_bullet() def _check_key_up(self, event): 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): #Create new bullet and add it to bullets group if len(self.bullets ) < self.settings.bullets_allowed: #check the number of bullets new_bullet = Bullet(self) self.bullets.add(new_bullet) pygame.mixer.Sound.play(self.laser_sound) #play audio at crash pygame.mixer.music.stop() #stop audio def _update_bullets(self): self.bullets.update() #move bullets on screen for bullet in self.bullets.copy( ): #check bullet position in copy of bullet if bullet.rect.bottom <= 0: #check if bottom of bullet is at zero y-coordinate self.bullets.remove(bullet) #remove the bullet from list #print(len(self.bullets)) #print length of list of bullets self._check_bullet_alien_collision() def _check_bullet_alien_collision(self): #Check collision of bullets and alien collisions = pygame.sprite.groupcollide(self.bullets, self.aliens, True, True) #True and True means that both the bulleta and alien would disappear #from screen after collsion if collisions: pygame.mixer.Sound.play(self.crash_sound) #play audio at crash pygame.mixer.music.stop() #stop audio for aliens in collisions.values(): #collision is a dictionary self.stats.score += self.settings.alien_points * len(aliens) self.sb.prep_score() self.sb.check_high_score() #When the fleet has been destroyed if not self.aliens: self.bullets.empty() #remove the existing bullets self._create_fleet() #create new fleet self.settings.increase_speed() # Increase level. self.stats.level += 1 self.sb.prep_level() def _create_fleet(self): alien = Alien(self) #make an instance of alien alien_width = alien.rect.width #get the width of alien.bmp alien_height = alien.rect.height #get the alien.bmp height #print("Alien width is " + str(alien_width)) available_space_x = self.settings.width - (2 * alien_width) #print(available_space_x)#subtract margins number_aliens_x = available_space_x // (2 * alien_width ) #calculate no. of aliens #print(number_aliens_x) ship_height = self.ship.rect.height available_space_y = self.settings.height - (3 * alien_height) - ( ship_height) number_rows = available_space_y // (3 * alien_height) for row in range(number_rows): for alien_number in range( number_aliens_x): #loop through no. of aliens self._create_alien(alien_number, row) def _create_alien(self, alien_number, row): alien = Alien(self) # create alien 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 self.aliens.add(alien) #add it to sprite list def _update_aliens(self): self.aliens.update() #call this method to move aliens on screen self._check_fleet_edges() #Check for alien and ship collision if pygame.sprite.spritecollideany(self.ship, self.aliens): self._ship_hit() #Check whether alien has hit the bottom self._check_aliens_bottom() def _check_fleet_edges(self): #loop through sprites list of alien for alien in self.aliens.sprites(): if alien.check_edges(): #print('aaaa') self.change_fleet_direction() break def change_fleet_direction(self): for alien in self.aliens.sprites(): alien.rect.y += self.settings.fleet_drop_speed self.settings.fleet_direction *= -1 def _ship_hit(self): #Decrement ship if self.stats.ship_left > 0: pygame.mixer.Sound.play(self.ship_hit_sound) #play audio at crash pygame.mixer.music.stop() #stop audio self.stats.ship_left -= 1 self.sb.prep_ships() #Get rid of aliens and bullets self.bullets.empty() self.aliens.empty() #Create a new fleet self._create_fleet() self.ship.center_ship() #Pause sleep(0.5) else: pygame.mixer.Sound.play(self.ship_hit_sound) #play audio at crash pygame.mixer.music.stop() #stop audio self.stats.game_active = False pygame.mouse.set_visible(True) def _check_aliens_bottom(self): 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 player clicks Play button_clicked = self.play_button.rect.collidepoint(mouse_pos) if button_clicked and not self.stats.game_active: self.settings.intialize_dynamic_settings() self.stats.reset_stats() self.stats.game_active = True self.sb.prep_score() self.sb.prep_level() self.sb.prep_ships() #get rid of aliens 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 _update_screen(self): self.screen.fill(self.settings.bg_color) self.ship.blitme() #draw ship for bullet in self.bullets.sprites(): #draw bullets bullet.draw_bullet() self.aliens.draw(self.screen) #draw aliens self.sb.show_score() # draw scoreboard #draw button if not self.stats.game_active: self.play_button.draw_button() pygame.display.flip() #display window
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((0, 0), pygame.FULLSCREEN) # self.settings.screen_width = self.screen.get_rect().width # self.settings.screen_height = self.screen.get_rect().height self.screen = pygame.display.set_mode((self.settings.screen_width, self.settings.screen_height)) pygame.display.set_caption("Alien Invasion") icon = pygame.image.load("images/alien2.png") # background = self.settings.bg pygame.display.set_icon(icon) # Create an instance to store game statistics, and create score board. self.stats = GameStats(self) self.sb = ScoreBoard(self) self.ship = Ship(self) self.bullets = pygame.sprite.Group() self.aliens = pygame.sprite.Group() self._create_fleet() # Make the play button. self.play_button = Button(self, "Play") def runGame(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 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._check_play_button(mouse_pos) 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 settings. 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() # 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 _check_keydown_events(self, event): """Respond to key presses.""" 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() 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.ship.moving_right = False elif event.key == pygame.K_LEFT: self.ship.moving_left = 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.""" # 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_collisions() def _check_bullet_alien_collisions(self): """Respond to bullet-alien collisions""" # Remove any bullets and aliens that have collided. 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: # Destroy existing bullets and create a new fleet. self.bullets.empty() self._create_fleet() self.settings.increase_speed() # Increase level. self.stats.level += 1 self.sb.prep_level() def _update_aliens(self): """Check if the fleet is at an edge, then Update the positions of all aliens in the fleet.""" self._check_fleet_edges() self.aliens.update() # Look for alien-ship collisions. 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 _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 on 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 the 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 _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 _check_fleet_edges(self): """Respond appropriately if any aliens have reached an edge""" for alien in self.aliens.sprites(): if alien.check_edges(): self._change_fleet_direction() break 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 _ship_hit(self): """Respond to the ship being hit by an alien.""" 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() # 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): """Check if any aliens have reached the bottom of the screen.""" screen_rect = self.screen.get_rect() for alien in self.aliens.sprites(): if alien.rect.bottom >= screen_rect.bottom: # Treat this the same as if the ship got hit. self._ship_hit() break def _update_screen(self): """Update images on the screen, and flip to the new screen.""" 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 the score information. self.sb.show_score() # Draw the play button if the game is inactive. if not self.stats.game_active: self.play_button.draw_button() # Make the most recently drawn screen visible pygame.display.flip()
class AlienInvasion: """Overall class to manage game asserts and behavior.""" def __init__(self): """Initialize the game, and create game resources.""" self._init_pygame() self.settings = Settings() self.screen = pg.display.set_mode( (self.settings.screen_width, self.settings.screen_height)) self.ship = Ship(self) self.stats = GameStats(self) self.score_board = ScoreBoard(self) self.fleet = Fleet(self) self.play_button = Button(self) self.info_tag = Tag(self) # Sprite groups. self.aliens = self.fleet.aliens self.bullets = pg.sprite.Group() self.explosions = pg.sprite.Group() # Sounds. self.shooting_sound = Sound(SHOOT_WAV) self.ship_hit_sound = Sound(SHIP_HIT_WAV) self.alien_shot_sound = Sound(SHOT_ALIEN_WAV) self._update_sounds() self.clock = pg.time.Clock() @staticmethod def _init_pygame(): """Initialize pygame and caption the game window.""" pg.init() pg.display.set_caption("Alien Invaders") def check_events(self): """Respond to key presses and mouse events.""" for event in pg.event.get(): # Write high-score to file then Exit. if self._quit_game(event): self.stats.write_highscore() sys.exit() # Reset the game. if self._start_game(event) and not self.stats.game_active: self.settings.initialize_dynamic_settings() self._setup_new_game() if event.type == KEYDOWN: self._check_keydown_events(event) elif event.type == KEYUP: self._check_keyup_events(event) @staticmethod def _quit_game(event: pg.event.Event) -> bool: """Check if the user wants to exit the game.""" return event.type == QUIT or (event.type == KEYDOWN and event.key == K_ESCAPE) def _start_game(self, event: pg.event.Event) -> bool: """Start a new game when the clicks Play or hits Enter.""" if event.type == MOUSEBUTTONDOWN: return self.play_button.rect.collidepoint(pg.mouse.get_pos()) return event.type == KEYDOWN and event.key == K_RETURN def _check_keydown_events(self, event: pg.event.Event): """Respond to key presses.""" if event.key == K_RIGHT: self.ship.moving_right = True elif event.key == K_LEFT: self.ship.moving_left = True elif event.key == K_SPACE: self._fire_bullet() elif event.key == K_m: self._update_sounds() def _check_keyup_events(self, event: pg.event.Event): """Respond to key releases.""" if event.key == K_RIGHT: self.ship.moving_right = False elif event.key == K_LEFT: self.ship.moving_left = False def _setup_new_game(self): """Reset the game statistics and create a new board.""" self.stats.reset_stats() self.stats.game_active = True self.score_board.prep_images() self.ship.center_ship() self._reset_all_sprites() # Hide the mouse cursor. pg.mouse.set_visible(False) def _reset_all_sprites(self): """Remove old bullets and aliens, create a new ship and alien fleet.""" self.aliens.empty() self.bullets.empty() self.fleet.create_fleet() def _reset(self): """Reset game when a life is lost.""" if self.stats.ships_left < 1: # no more lives left self.stats.game_active = False pg.mouse.set_visible(True) # Decrement ships left, update score-board, and reset game. self.stats.ships_left -= 1 self.score_board.prep_ships() self._reset_all_sprites() sleep(0.3) def _fire_bullet(self): """Create a new bullet and add it to the bullets group.""" if len(self.bullets) < self.settings.bullets_limit: new_bullets = self.ship.shoot() if new_bullets: self.bullets.add(new_bullets) self.shooting_sound.play() def _collisions(self): """Respond to alien-ship collisions, and aliens hitting the screen bottom.""" # Ship collision: play sound, make explosion. explosion = Explosion(self.ship.rect.center) self.explosions.add(explosion) self.ship_hit_sound.play() def _alien_ship_collision(self) -> bool: """Return True if ship is hit by an alien.""" ship_hit = pg.sprite.spritecollide(self.ship, self.aliens, True) if ship_hit: for _ in ship_hit: self._collisions() return True def _alien_ground_collision(self) -> bool: """Return True if any aliens have reached the bottom of the screen.""" screen_rect = self.screen.get_rect() for alien in self.aliens.sprites(): if alien.rect.bottom >= screen_rect.bottom: # Check if AT LEAST one alien reaches the ground. self._collisions() return True def _alien_bullet_collision(self): """Respond to bullet-alien collision.""" collisions = pg.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.score_board.prep_score() # For each collision, play sound, make explosion. for alien in aliens: explosion = Explosion(alien.rect.center) self.explosions.add(explosion) self.alien_shot_sound.play() self.score_board.check_high_score() if not self.aliens: if not self.explosions: # Destroy sprites left; create new fleet; increase game speed and level. self.bullets.empty() self.fleet.create_fleet() self.settings.increase_level() self.stats.level += 1 self.score_board.prep_level() def update_bullets(self): """Update position of bullets and get rid of old bullets.""" self.bullets.update() self._alien_bullet_collision() def update_aliens(self): """Update the position of all aliens in the fleet.""" self.fleet.check_fleet_edges() alien_collisions: bool = self._alien_ship_collision( ) or self._alien_ground_collision() self.aliens.update() self.explosions.update() if alien_collisions: self._reset() def _update_sounds(self): """Plays sounds if play = 1, stops sounds if play = -1.""" # Defaults to 1, sounds enabled. self.settings.sound_playing *= -1 for _sound in ( self.shooting_sound, self.ship_hit_sound, self.alien_shot_sound, ): if self.settings.sound_playing == 1: _sound.set_volume(0.2) elif self.settings.sound_playing == -1: _sound.set_volume(0) def update_screen(self): """Update images on the screen, and flip to the new screen.""" background = pg.image.load(BACKGROUND_IMG).convert() bg_image = pg.transform.scale( background, (self.settings.screen_width, self.settings.screen_height)) self.screen.blit(bg_image, (0, 0)) # Draw sprites. self.ship.draw() self.explosions.draw(self.screen) self.aliens.draw(self.screen) self.bullets.draw(self.screen) # Draw the score information self.score_board.show_score() # Draw the play button if the game is inactive. if not self.stats.game_active: # Button and Tag self.info_tag.prep_msg( "Press Esc to exit. Press M to (un)mute game sounds.") self.info_tag.draw_button() self.play_button.prep_msg("Click here or press Enter to play.") self.play_button.draw_button() pg.display.flip() self.clock.tick(60)
class AlienInvasion: def __init__(self): 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("Alien Invasion") self.stats = GameStats(self) self.sb = ScoreBoard(self) self.ship = Ship(self) self.bullets = pygame.sprite.Group() self.aliens = pygame.sprite.Group() self._create_fleet() self.stars = pygame.sprite.Group() self._create_stars_grid() self.easy_button = Button(self, 850, 250, (102, 255, 0), "Easy") self.normal_button = Button(self, 850, 450, (255, 216, 0), "Normal") self.hard_button = Button(self, 850, 650, (255, 36, 0), "Hard") self.zerout_record_button = Button(self, 850, 850, (0, 0, 0), "Zero out a record") def run_game(self): """Запускает основной цикл игры""" while True: self._check_events() self.sb.read_high_score() if self.stats.game_active: self.ship.update() self._update_bullets() self._update_aliens() self._update_screen() def _check_events(self): """Обрабатывает события клавиш и мыши""" 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._difficulty_buttons(mouse_pos) self._check_play_button(mouse_pos) self._zerout_record(mouse_pos) def _check_keydown_events(self, event): """Реакция на нажите клавиш""" if event.key == pygame.K_d: self.ship.moving_right = True elif event.key == pygame.K_a: self.ship.moving_left = True elif event.key == pygame.K_ESCAPE: self.sb.write_high_score() sys.exit() elif event.key == pygame.K_SPACE: if self.stats.game_active: self._fire_bullet() def _check_keyup_events(self, event): """Реакция на отпускание клавиш""" if event.key == pygame.K_d: self.ship.moving_right = False elif event.key == pygame.K_a: self.ship.moving_left = False def _zerout_record(self, mouse_pos): """Обнуляет рекорд при нажатии кнопки""" button_clicked = self.zerout_record_button.rect.collidepoint(mouse_pos) if button_clicked and not self.stats.game_active: os.system( 'python D:\\Programming\\Python\\alien_invasion\\start.py') sys.exit() def _check_play_button(self, mouse_pos): """Запускает новую игру при нажатии кнопки play""" easy_button_clicked = self.easy_button.rect.collidepoint(mouse_pos) normal_button_clicked = self.normal_button.rect.collidepoint(mouse_pos) hard_button_clicked = self.hard_button.rect.collidepoint(mouse_pos) if easy_button_clicked or normal_button_clicked or hard_button_clicked and not self.stats.game_active: # Cброс статистики self.stats.reset_status() self.stats.game_active = True self.sb.prep_level() self.sb.prep_ships() self.aliens.empty() self.bullets.empty() self._create_fleet() self.ship.center_ship() pygame.mouse.set_visible(False) def _difficulty_buttons(self, mouse_pos): easy_button_clicked = self.easy_button.rect.collidepoint(mouse_pos) normal_button_clicked = self.normal_button.rect.collidepoint(mouse_pos) hard_button_clicked = self.hard_button.rect.collidepoint(mouse_pos) if easy_button_clicked or normal_button_clicked or hard_button_clicked and not self.stats.game_active: pygame.mixer.music.load( 'alien_invasion/other_files/for_levels.mp3') pygame.mixer.music.set_volume(50) pygame.mixer.music.play(-1) if easy_button_clicked: self.settings.dynamic_settings() self.settings.alien_speed = 0.7 self.settings.ship_speed = 1.8 self.settings.bullet_speed = 1.9 self._check_play_button(mouse_pos) if normal_button_clicked: self.settings.dynamic_settings() self.settings.alien_speed = 1.0 self.settings.ship_speed = 1.5 self.settings.bullet_speed = 1.5 self._check_play_button(mouse_pos) if hard_button_clicked: self.settings.dynamic_settings() self.settings.alien_speed = 1.8 self.settings.ship_speed = 0.8 self.settings.bullet_speed = 0.7 self._check_play_button(mouse_pos) def _fire_bullet(self): """Создание нового снаряда и включение его в группу""" if len(self.bullets) < self.settings.bullet_allowed: new_bullet = Bullet(self) self.bullets.add(new_bullet) fire_sound = pygame.mixer.Sound( "alien_invasion/other_files/shot.wav") fire_sound.play() def _update_bullets(self): """Обновляет позиции снарядов и уничтожает старые снаряды""" self.bullets.update() for bullet in self.bullets.copy(): if bullet.rect.bottom <= 0: self.bullets.remove(bullet) self._check_bullet_alien_collisions() def _check_bullet_alien_collisions(self): if not self.aliens: # Уничтожение существующих снарядов и создание нового флота self.bullets.empty() self._create_fleet() self.settings.inscrease_speed() # Увеличение уровня self.stats.level += 1 self.sb.prep_level() # проверка попаданий в пришельцев.При попадании удаляет снаряд и пришельца 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) hit_sound = pygame.mixer.Sound( 'alien_invasion/other_files/ufo.wav') hit_sound.play() self.sb.prep_score() self.sb.check_high_score() def _create_fleet(self): """Создание флота пришельцев""" alien = Alien(self) alien_width, alien_height = alien.rect.size avaible_space_x = self.settings.screen_width - (2 * alien_width) number_aliens_x = avaible_space_x // (2 * alien_width) """Определяет количество рядов, помещающихся на экране""" ship_height = self.ship.rect.height avaible_space_y = (self.settings.screen_height - (3 * alien_height) - ship_height) number_rows = avaible_space_y // (2 * alien_height) # Создание флота for row_number in range(number_rows): for alien_number in range(number_aliens_x): self._create_alien(alien_number, row_number) def _create_alien(self, alien_number, row_number): """Создание пришельца и размещение его в ряду""" 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 _check_fleet_edges(self): """Реакция на достижение края экрана""" for alien in self.aliens.sprites(): if alien.check_edges(): self._change_fleet_direction() break def _change_fleet_direction(self): """Опускает флот и меняет направление""" for alien in self.aliens.sprites(): alien.rect.y += self.settings.fleet_drop_speed self.settings.fleet_direction *= -1 def _check_aliens_bottom(self): """Проверяет, добрались ли пришельцы до нижнего края экрана""" screen_rect = self.screen.get_rect() for alien in self.aliens.sprites(): if alien.rect.bottom >= screen_rect.bottom: self._ship_hit() break def _update_aliens(self): """Обновляет позиции всех прищельцев""" self._check_fleet_edges() self.aliens.update() # Проверка коллизий пришельца с кораблём if pygame.sprite.spritecollide(self.ship, self.aliens, True): self._ship_hit() # Проверяет, добрались ли пришельцы до нижнего края экрана self._check_aliens_bottom() def _create_stars_grid(self): """Создание сетки звёзд""" # Создание одной звезды star = Star(self) avaible_star_space_x = self.settings.screen_width avaible_star_space_y = self.settings.screen_height star_height = star.rect.y star_width = star.rect.x i = 0 star_x = [0] star_y = [0] for i in range(60): cur_pos_x = randrange(0, 1900, 50) cur_pos_y = randrange(0, 1080, 45) for x in star_x: if cur_pos_x == x: cur_pos_x = randrange(0, 1900, 50) star_x.append(cur_pos_x) break else: star_x.append(cur_pos_x) break for y in star_y: if cur_pos_y == y: cur_pos_y = randrange(0, 1080, 45) star_y.append(cur_pos_y) break else: star_y.append(cur_pos_y) break if star_x[i] == 0 and star_y[i] == 0: star.remove() else: self._create_star(star_x[i], star_y[i]) def _create_star(self, x, y): star = Star(self) star.rect.x = x star.rect.y = y self.stars.add(star) def _ship_hit(self): """Обрабатывает столкновения корабля с пришельцами""" if self.stats.ships_left > 0: # Уменьшение ships_left self.stats.ships_left -= 1 #Проигравание звука при потере жизни ship_hit_sound = pygame.mixer.Sound( 'alien_invasion/other_files/minus_hp.wav') ship_hit_sound.play() self.sb.prep_ships() # Очистка списков пришельцев и пуль self.aliens.empty() self.bullets.empty() # Созание нового флота и размещение корабля в центре self._create_fleet() self.ship.center_ship() # Пауза sleep(0.5) else: self.stats.game_active = False pygame.mixer.music.stop() pygame.mouse.set_visible(True) def _update_screen(self): """Обновляет изображение на экране""" self.screen.fill(self.settings.bg_color) self.stars.draw(self.screen) self.sb.show_score() self.ship.blitme() for bullet in self.bullets.sprites(): bullet.draw_bullet() self.aliens.draw(self.screen) if not self.stats.game_active: self.easy_button.draw_button() self.normal_button.draw_button() self.hard_button.draw_button() self.zerout_record_button.draw_button() pygame.display.flip()
class AlienInvasion: def __init__(self): 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") self.stats = GameStats(self) self.sb = ScoreBoard(self) self.ship = Ship(self) self.bullets = pygame.sprite.Group() self.aliens = pygame.sprite.Group() self._creat_fleet() self.play_button = Button(self, 'Play') self.sound = pygame.mixer.Sound( get_resource_path('music/exicting_music.mp3')) def run_game(self): while True: self._check_events() if self.stats.game_active: self.ship.update() self._update_bullets() self._update_aliens() self._update_screen() def play_sound(self, path): self.sounds = pygame.mixer.Sound(get_resource_path(path)) self.sounds.play() def _ship_hit(self): if self.stats.ships_left > 0: self.play_sound('music/hit_sound.mp3') self.stats.ships_left -= 1 self.sb.prep_ships() self.aliens.empty() self.bullets.empty() self._creat_fleet() self.ship.center_ship() else: self.stats.game_active = False self.play_sound('music/hit_sound.mp3') self.play_sound('music/lose.mp3') self.sound.stop() pygame.mouse.set_visible(True) sleep(0.5) def _creat_fleet(self): alien = Alien(self) alien_width, alien_height = alien.rect.size available_space_x = self.settings.screen_width - 2 * alien_width number_alien_x = available_space_x // (2 * alien_width) 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) for row_number in range(number_rows): for alien_number in range(number_alien_x): self._creat_alien(alien_number, row_number) def _creat_alien(self, alien_number, row_number): 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_height * row_number self.aliens.add(alien) def _change_fleet_direction(self): """将整群外星人下移 并改变方向""" for alien in self.aliens.sprites(): alien.rect.y += self.settings.fleet_drop_speed self.settings.fleet_direction *= -1 def _check_fleet_edges(self): for alien in self.aliens.sprites(): if alien.check_edges(): self._change_fleet_direction() break def _check_events(self): 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_play_button(self, mouse_pos): button_clicked = self.play_button.rect.collidepoint(mouse_pos) if button_clicked and not self.stats.game_active: 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() self.aliens.empty() self.bullets.empty() self._creat_fleet() self.ship.center_ship() pygame.mouse.set_visible(False) self.sound.play(-1) def _check_keydown_events(self, event): 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() elif event.key == pygame.K_SPACE: self._fire_bullet() 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 def _check_bullet_alien_collisions(self): collisions = pygame.sprite.groupcollide(self.bullets, self.aliens, True, True) if collisions: self.play_sound('music/hit_sound.mp3') 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.bullets.empty() self._creat_fleet() self.settings.increase_speed() self.stats.level += 1 self.sb.prep_level() self.play_sound('music/level_up.mp3') def _check_aliens_bottom(self): screen_rect = self.screen.get_rect() for alien in self.aliens.sprites(): if alien.rect.bottom >= screen_rect.bottom: self._ship_hit() break def _fire_bullet(self): if len(self.bullets) < self.settings.bullet_allowed: new_bullet = Bullet(self) self.bullets.add(new_bullet) def _update_bullets(self): self.bullets.update() for bullet in self.bullets.copy(): # copy() 很重要 if bullet.rect.bottom <= 0: self.bullets.remove(bullet) self._check_bullet_alien_collisions() def _update_aliens(self): self._check_fleet_edges() self.aliens.update() if pygame.sprite.spritecollideany(self.ship, self.aliens): self._ship_hit() self._check_aliens_bottom() def _update_screen(self): self.screen.fill(self.settings.bg_color) self.ship.blitme() for bullet in self.bullets.sprites(): bullet.draw_bullet() self.aliens.draw(self.screen) self.sb.show_score() if not self.stats.game_active: self.play_button.draw_button() pygame.display.flip() # 翻转 更新屏幕
class AlienInvasion: def __init__(self): pygame.init() self.my_setting = Settings() self.screen = pygame.display.set_mode( (self.my_setting.screen_width, self.my_setting.screen_height)) pygame.display.set_caption('Alien Invasion') self.color = self.my_setting.bg_color '''放在初始化完成下面''' self.ship = Ship(self) '''子弹''' self.bullets = pygame.sprite.Group() self.is_bulleting = False '''外星人''' self.aliens = pygame.sprite.Group() self._build_aliens() '''游戏状态''' self.status = GameStatus(self) '''play按钮''' self.play_button = Button(self, 'Play') '''分数按钮''' self.sb = ScoreBoard(self) def run_game(self): self._auto_fire() while True: self._check_event() if self.status.game_active: self.ship.update() self._update_bullets() self._update_aliens() self._update_screen() '''--------------------------''' def _build_aliens(self): alien_sample = Alien(self) alien_width = alien_sample.rect.width alien_height = alien_sample.rect.height '''可用宽度''' available_space_x = self.screen.get_rect().width - 2 * alien_width available_number_x = available_space_x // (2 * alien_width) '''可用高度''' available_space_y = self.screen.get_rect().height - 3 * alien_width available_number_y = available_space_y // (2 * alien_height) for num_y in range(available_number_y): for num_x in range(available_number_x): alien = self._create_alien(num_x, num_y) self.aliens.add(alien) def _create_alien(self, num_x, num_y): alien = Alien(self) alien.x = alien.rect.width + num_x * (2 * alien.rect.width) alien.rect.x = alien.x alien.y = alien.rect.height + num_y * (2 * alien.rect.width) alien.rect.y = alien.y return alien def _update_bullets(self): self.bullets.update() for bullet in self.bullets.copy(): if bullet.rect.bottom <= 0: self.bullets.remove(bullet) self._check_bullet_alien_collide() def _check_bullet_alien_collide(self): collisions = pygame.sprite.groupcollide(self.bullets, self.aliens, True, True) '''增加得分''' if collisions: for aliens in collisions.values(): for alien in aliens: self.status.score += self.my_setting.per_alien_score self.sb.prep_score() self.sb.check_high_score() if not self.aliens: self.bullets.empty() self.my_setting._increase_speed() self.status.level += 1 self.sb.prep_level() self._build_aliens() def _update_aliens(self): self._check_alien_edge() self.aliens.update() if pygame.sprite.spritecollideany(self.ship, self.aliens): self._ship_hit() self._check_alien_bottom() def _ship_hit(self): self._reset_scene_status() self.status.minus_ship() self.sb.prep_ships() sleep(1) def _check_alien_bottom(self): 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_alien_edge(self): for alien in self.aliens.sprites(): if alien.check_edge(): self._change_alien_direction(alien) break def _change_alien_direction(self, alien): self.my_setting.alien_direction = self.my_setting.alien_direction * ( -1) for alien in self.aliens.sprites(): alien.y += self.my_setting.alien_spped_y alien.rect.y = alien.y def _check_event(self): for event in pygame.event.get(): if event.type == pygame.QUIT: self.status.save_high_score() sys.exit() elif event.type == pygame.KEYDOWN: self._check_key_down(event) elif event.type == pygame.KEYUP: self._check_key_up(event) elif event.type == pygame.MOUSEBUTTONDOWN: mouse_pos = pygame.mouse.get_pos() self._check_mouse_down(mouse_pos) def _check_key_down(self, event): if event.key == pygame.K_RIGHT: self.ship.right_moving = True elif event.key == pygame.K_LEFT: self.ship.left_moving = True elif event.key == pygame.K_q: self.status.save_high_score() sys.exit() elif event.key == pygame.K_SPACE: # self._fire_bullet() self.fire_job.resume() elif event.key == pygame.K_p: self._start_game() def _check_key_up(self, event): if event.key == pygame.K_RIGHT: self.ship.right_moving = False elif event.key == pygame.K_LEFT: self.ship.left_moving = False elif event.key == pygame.K_SPACE: # self._fire_bullet() self.fire_job.pause() def _check_mouse_down(self, pos): if self.play_button.rect.collidepoint(pos): self._start_game() def _start_game(self): if not self.status.game_active: self.status.reset() self.sb.prep_score() self.sb.prep_high_score() self.sb.prep_level() self.sb.prep_ships() self.status.game_active = True self._reset_scene_status() self.my_setting._init_dynamic_setting() pygame.mouse.set_visible(False) def _reset_scene_status(self): self.aliens.empty() self.bullets.empty() self._build_aliens() self.ship.center_place() def _auto_fire(self): scheduler = BackgroundScheduler() self.fire_job = scheduler.add_job(self._fire_bullet, 'interval', seconds=0.1) scheduler.start() self.fire_job.pause() def _update_screen(self): self.screen.fill(self.color) self.ship.blitme() '''绘制子弹''' for bullet in self.bullets.sprites(): bullet.draw_bullet() self.aliens.draw(self.screen) if not self.status.game_active: self.play_button.draw_button() self.sb.draw_score() pygame.display.flip() def _fire_bullet(self): if self.status.game_active: new_bullet = Bullet(self) self.bullets.add(new_bullet)
class AlienInvasion: """Overall class to manage game assets and behaviour""" def __init__(self): """Initialize the game, and create game resources""" pygame.init() #pop_sound = mixer.music.Sound('sounds/bang_02.mp3') 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("Polandball and the Prussian Invasion") self.stats = GameStats(self) self.sb = ScoreBoard(self) #Set the background color self.bg_color = (255, 255, 255) self.ship = Ship(self) self.bullets = pygame.sprite.Group() self.aliens = pygame.sprite.Group() self._create_fleet() self.play_button = Button(self, "Play") 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): """Response to keypresses and mouse events""" # Watch for keyboard 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_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: 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() self.aliens.empty() self.bullets.empty() self._create_fleet() self.ship.center_ship() pygame.mouse.set_visible(False) def _check_keydown_events(self, event): """Respond to keypresses""" if event.key == pygame.K_RIGHT: # Move the ship to the right self.ship.moving_right = True if event.key == pygame.K_LEFT: self.ship.moving_left = True if event.key == pygame.K_q: sys.exit() if event.key == pygame.K_SPACE: self._fire_bullet() #pop_sound.play() def _check_keyup_events(self, event): """Respond to keyreleases""" if event.key == pygame.K_RIGHT: # Move the ship to the right self.ship.moving_right = False if event.key == pygame.K_LEFT: self.ship.moving_left = False def _fire_bullet(self): """Create a new bullet and add it to the bullets group""" new_bullet = Bullet(self) self.bullets.add(new_bullet) def _update_bullets(self): self.bullets.update() for bullet in self.bullets.copy(): if bullet.rect.bottom <= 0: self.bullets.remove(bullet) self._check_bullet_alien_collisions() def _ship_hit(self): """Respomd to the shit being hit by an alien""" if self.stats.ships_left > 0: self.stats.ships_left -= 1 self.sb.prep_ships() self.aliens.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 _create_fleet(self): """Create the fleet of aliens""" 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) 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) for row_number in range(number_rows): for alien_number in range(number_aliens_x): self._create_alien(alien_number, row_number) def _create_alien(self, alien_number, row_number): 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 _check_fleet_edges(self): """Respond 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_bullet_alien_collisions(self): """Respond to bullet-alien collisions""" collisions = pygame.sprite.groupcollide(self.bullets, self.aliens, True, True) if collisions: self.stats.score += self.settings.alien_points self.sb.prep_score() self.sb.check_high_score() if not self.aliens: self.settings.initialize_dynamic_settings() self.bullets.empty() self._create_fleet() self.settings.increase_speed() self.stats.level += 1 self.sb.prep_level() 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.sprites(): if alien.rect.bottom >= screen_rect.bottom: self._ship_hit() break def _update_aliens(self): """Update the posistions of all aliens in the fleet""" self._check_fleet_edges() self.aliens.update() if pygame.sprite.spritecollideany(self.ship, self.aliens): self._ship_hit() self._check_aliens_bottom() def _update_screen(self): """Update images on the screen, and flip to the new screen""" # Redraw the screen during each pass through the loop self.screen.fill(self.settings.bg_color) self.ship.blitme() for bullet in self.bullets.sprites(): bullet.draw_bullet() self.aliens.draw(self.screen) 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()
class AlienInvasion: def __init__(self): pygame.init() self.settings = Settings() self.screen = pygame.display.set_mode( (self.settings.screen_width, self.settings.screen_heigth)) pygame.display.set_caption("Alien INVASION by s0medude") self.stats = GameStats(self) self.ship = Ship(self) self.bullets = pygame.sprite.Group() self.aliens = pygame.sprite.Group() self._create_fleet() self.play_button = Button(self) self.levels_button = Button(self) self.button_levels_list = [] self.scoreboard = ScoreBoard(self) def _check_keydown_events(self, event): 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: self._save_high_score() sys.exit() elif event.key == pygame.K_SPACE: self._fire_bullet() elif event.key == pygame.K_p: if not self.stats.game_active: self.settings.initialize_dynamic_settings() self._start_game() elif event.key == pygame.K_r: self.stats.game_active = False self._reset_stats() pygame.mouse.set_visible(True) def _check_keyup_events(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 _check_mouse_events(self): mouse_pos = pygame.mouse.get_pos() if not self.levels_button.clicked: self._check_play_button(mouse_pos) self._check_main_levels_button(mouse_pos) else: self._check_level_button(mouse_pos) def _check_events(self): for event in pygame.event.get(): if event.type == pygame.QUIT: self._save_high_score() 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: self._check_mouse_events() def _save_high_score(self): filename = 'high_score.json' with open(filename, 'w') as f: json.dump(self.stats.high_score, f) f.close() def _draw_bullet(self): for bullet in self.bullets.sprites(): bullet.draw_bullet() def _fire_bullet(self): if len(self.bullets) < self.settings.bullets_allowed: new_bullet = Bullet(self) self.bullets.add(new_bullet) def _check_bullet_alien_collision(self): 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.scoreboard.prep_score() self.scoreboard.check_high_score() self._start_new_level() def _start_new_level(self): if not self.aliens: self.bullets.empty() self._create_fleet() self.settings.increase_speed() self.stats.level += 1 self.scoreboard.prep_level() def _update_bullet(self): self.bullets.update() for bullet in self.bullets.copy(): if bullet.rect.bottom <= 0: self.bullets.remove(bullet) self._check_bullet_alien_collision() def _create_alien(self, alien_number, row_number): 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_height + (2 * alien_height * row_number) self.aliens.add(alien) def _create_fleet(self): alien = Alien(self) alien_width, alien_height = alien.rect.size ship_height = self.ship.rect.height available_space_x = self.settings.screen_width - (2 * alien_width) available_space_y = (self.settings.screen_heigth - (3 * alien_height) - ship_height) number_aliens_x = available_space_x // (2 * alien_width) number_rows = available_space_y // (2 * alien_height) for row_number in range(number_rows + 1): for alien_number in range(number_aliens_x + 1): self._create_alien(alien_number, row_number) def _check_fleet_edges(self): for alien in self.aliens.sprites(): if alien.check_edges(): self._change_fleet_directions() break def _change_fleet_directions(self): for alien in self.aliens.sprites(): alien.rect.y += self.settings.fleet_alien_speed self.settings.fleet_direction *= -1 def _ship_hit(self): if self.stats.ship_left > 0: self.stats.ship_left -= 1 self.scoreboard.prep_ships() self.aliens.empty() self.bullets.empty() self._create_fleet() self.ship.center_ship() sleep(0.5) else: self.stats.game_active = False self._reset_stats() pygame.mouse.set_visible(True) def _check_ship_hit(self): if pygame.sprite.spritecollideany(self.ship, self.aliens): self._ship_hit() def _check_aliens_bottom(self): screen_rect = self.screen.get_rect() for alien in self.aliens.sprites(): if alien.rect.bottom >= screen_rect.bottom: self._ship_hit() break def _update_aliens(self): self._check_fleet_edges() self.aliens.update() self._check_ship_hit() self._check_aliens_bottom() def _draw_main_buttons(self): if not self.stats.game_active and not self.levels_button.clicked: self.play_button.draw_button("START", 450, 360) self.levels_button.draw_button("LEVELS", 750, 360) elif not self.stats.game_active and self.levels_button.clicked: self._draw_level_buttons() def _draw_level_buttons(self): number_buttons_x, number_rows_y = 3, 3 number = 1 for row in range(number_rows_y): row += 1 for level in range(number_buttons_x): level += 1 button = Button(self) button.rect.width, button.rect.height = 150, 50 button.draw_button(f"Level {str(number)}", 300 * level, 180 * row) number += 1 self.button_levels_list.append(button) def _check_play_button(self, mouse_pos): if self.play_button.check_button( mouse_pos) and not self.stats.game_active: self._reset_stats() self._start_game() def _check_main_levels_button(self, mouse_pos): if self.levels_button.check_button( mouse_pos) and not self.stats.game_active: self._update_screen() def _check_level_button(self, mouse_pos): for button in self.button_levels_list: if button.check_button(mouse_pos) and not self.stats.game_active: i = self.button_levels_list.index(button) self.stats.level += i self.settings.increase_speed(self.stats.level) self._start_game() self.levels_button.clicked = False def _reset_stats(self): self.settings.initialize_dynamic_settings() self.stats.reset_stats() self.levels_button.clicked = False def _start_game(self): self.stats.game_active = True self.scoreboard.prep_images() self.bullets.empty() self.aliens.empty() self._create_fleet() self.ship.center_ship() pygame.mouse.set_visible(False) def _update_screen(self): self.screen.fill(self.settings.bg_color) self.screen.blit(self.settings.bg_image, self.settings.bg_image_rect) self.ship.blitme() self._draw_bullet() self.aliens.draw(self.screen) self.scoreboard.show_score() self._draw_main_buttons() pygame.display.flip() def run_game(self): while True: self._check_events() if self.stats.game_active: self.ship.update() self._update_bullet() self._update_aliens() self._update_screen()
class AlienInvasion: def __init__(self): pygame.init() pygame.display.set_caption("Alien Invasion") 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) # self.settings.screen_width = self.screen.get_rect().width # self.settings.screen_height = self.screen.get_rect().height self.stats = GameStats(self) self.scoreboard = ScoreBoard(self) self.ship = Ship(self) self.bullets = pygame.sprite.Group() self.aliens = pygame.sprite.Group() self._create_fleet() self.play_button = Button(self, "Easy", "Medium", "Hard") self._initialize_sounds() def run_game(self): while True: self._check_event() if self.stats.game_flag: self.ship.update() self._update_bullets() self._update_aliens() self._update_screen() #print(len(self.bullets)) def _start_game(self): if not self.stats.game_flag: self.stats.reset_stats() self.stats.game_flag = True self.bullets.empty() self.aliens.empty() self._create_fleet() self.ship.center_ship() pygame.mouse.set_visible(False) def _write_high_score(self): high_score_file = self.settings.high_score_file high_score = self.stats.high_score with open(high_score_file, 'w') as file_object: json.dump(high_score, file_object) def _check_event(self): for event in pygame.event.get(): if event.type == pygame.QUIT: self._write_high_score() sys.exit() elif event.type == pygame.MOUSEBUTTONDOWN: mouse_position = pygame.mouse.get_pos() self._check_play_button(mouse_position) elif event.type == pygame.KEYDOWN: self._check_keydown_events(event) elif event.type == pygame.KEYUP: self._check_keyup_events(event) def _check_play_button(self, mouse_position): easy_button = self.play_button.rect_easy.collidepoint(mouse_position) medium_button = self.play_button.rect_medium.collidepoint(mouse_position) hard_button = self.play_button.rect_hard.collidepoint(mouse_position) if easy_button: self.settings.initialize_dynamic_settings() self._initialize_game() elif medium_button: self.settings.medium_game_settings() self._initialize_game() elif hard_button: self.settings.hard_game_settings() self._initialize_game() def _initialize_game(self): self._start_game() self.scoreboard.prep_score() self.scoreboard.prep_level() self.scoreboard.prep_ships() def _initialize_sounds(self): pygame.mixer.music.load(self.settings.game_music) pygame.mixer.music.play(-1) self.bullet_sound = pygame.mixer.Sound(self.settings.bullet_sound) self.collide_sound = pygame.mixer.Sound(self.settings.collide_sound) def _check_keydown_events(self, event): 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_p: self._start_game() elif event.key == pygame.K_q: self._write_high_score() sys.exit() elif event.key == pygame.K_SPACE and self.stats.game_flag == True: self.bullet_sound.play() self._fire_bullet() 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 def _fire_bullet(self): if len(self.bullets) < self.settings.bullet_allowed: new_bullet = Bullet(self) self.bullets.add(new_bullet) def _update_bullets(self): self.bullets.update() for bullet in self.bullets.copy(): if bullet.rect.bottom <= 0: self.bullets.remove(bullet) self._check_bullet_alien_collisions() def _check_bullet_alien_collisions(self): collisions = pygame.sprite.groupcollide( self.bullets, self.aliens, True, True) if not self.aliens: self.bullets.empty() self._create_fleet() self.settings.increase_speed() self.stats.level +=1 self.scoreboard.prep_level() if collisions: for aliens in collisions.values(): self.stats.score += self.settings.alien_points * len(aliens) self.collide_sound.play() self.scoreboard.prep_score() self.scoreboard.check_high_score() def _check_fleet_edges(self): for alien in self.aliens.sprites(): if alien.check_edges(): self._change_fleet_direction() break def _change_fleet_direction(self): for alien in self.aliens.sprites(): alien.rect.y += self.settings.fleet_drop_speed self.settings.fleet_direction *= -1 def _ship_hit(self): if self.stats.ship_left > 0: self.stats.ship_left -= 1 self.scoreboard.prep_ships() self.aliens.empty() self.bullets.empty() self._create_fleet() self.ship.center_ship() sleep(0.5) else: self.stats.game_flag = False pygame.mouse.set_visible(True) def _check_alien_bottom(self): screen_rect = self.screen.get_rect() for alien in self.aliens.sprites(): if alien.rect.bottom >= screen_rect.bottom: self._ship_hit() break def _update_aliens(self): self._check_fleet_edges() self.aliens.update() if pygame.sprite.spritecollideany(self.ship, self.aliens): self._ship_hit() self._check_alien_bottom() def _create_fleet(self): alien = Alien(self) alien_width, alien_height = alien.rect.size available_space_x = self.settings.screen_width - (2 * alien_width) number_alien_x = available_space_x // (2 * alien_width) 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) for row_number in range(number_rows): for alien_number in range(number_alien_x): self._create_alien(alien_number, row_number) def _create_alien(self, alien_number, row_number): 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.y = alien_height + 2 * alien_height * row_number alien.rect.y = alien.y self.aliens.add(alien) def _update_screen(self): self.screen.fill(self.settings.bg_color) self.ship.blitme() for bullet in self.bullets.sprites(): bullet.draw_bullet() self.aliens.draw(self.screen) self.scoreboard.show_score() if not self.stats.game_flag: self.play_button.draw_button() pygame.display.flip()
class AlienInvasion(object): """ Класс для управления ресурсами и поведением игры. """ def __init__(self): """Инициализирует игру и создает игровые ресурсы.""" pygame.init() pygame.display.set_caption('Alien Invasion') self.settings = Settings() self.background_color = self.settings.background_color if self.settings.fullscreen: self.screen = pygame.display.set_mode((0, 0), pygame.FULLSCREEN) else: self.screen = pygame.display.set_mode( (self.settings.screen_width, self.settings.screen_height)) self.stats = GameStats(self) self.score = ScoreBoard(self) self.play_button = PlayButton(self, 'Play') self.ship = Ship(self) self.bullets = pygame.sprite.Group() self.mega_bullets = pygame.sprite.Group() self.aliens = pygame.sprite.Group() self._create_fleet() def _check_events(self): """Обрабатывает нажатия клавиш и события мыши.""" 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: self._check_play_button(pygame.mouse.get_pos()) def _check_keydown_events(self, event): 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 or event.key == pygame.K_ESCAPE: sys.exit() elif event.key == pygame.K_SPACE: self._fire_bullet() elif event.key == pygame.K_z: self._fire_mega_bullet() 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 def _check_play_button(self, position): """Запускает новую игру при нажатии кнопки Play.""" if self.play_button.rect.collidepoint( position) and not self.stats.game_active: self.stats.reset_stats() self.settings.init_dynamic_settings() self.stats.game_active = True self.score.prep_score() self.score.prep_level() self.score.prep_ships() self.aliens.empty() self.bullets.empty() self._create_fleet() self.ship.center_ship() pygame.mouse.set_visible(False) def _check_bullet_alien_collisions(self): # Проверка попаданий в пришельцев. 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.score.prep_score() self.score.check_high_score() self._using_mega_bullets() if not self.aliens: self.bullets.empty() self.mega_bullets.empty() self._create_fleet() self.settings.increase_speed() self.stats.level += 1 self.score.prep_level() def _check_fleet_edges(self): """Реагирует на достижение пришельцем края экрана.""" for alien in self.aliens.sprites(): if alien.check_edges(): self._change_fleet_direction() break def _check_aliens_bottom(self): """Проверяет, добрались ли пришельцы до нижнего края экрана.""" screen_rect = self.screen.get_rect() for alien in self.aliens.sprites(): if alien.rect.bottom >= screen_rect.bottom: self._ship_hit() break def _update_bullets(self): """Обновляет позиции снарядов.""" self.bullets.update() # Удаление снарядов, вышедших за край экрана. for bullet in self.bullets.copy(): if bullet.rect.bottom <= 0: self.bullets.remove(bullet) self._check_bullet_alien_collisions() def _update_aliens(self): """Обновляет позиции всех пришельцев во флоте.""" self._check_fleet_edges() self.aliens.update() # Проверка коллизий "пришелец — корабль". if pygame.sprite.spritecollideany(self.ship, self.aliens): self._ship_hit() self._check_aliens_bottom() def _update_screen(self): """Обновляет изображения на экране и отображает новый экран.""" self.screen.fill(self.background_color) self.ship.blitme() for bullet in self.bullets.sprites(): bullet.draw_bullet() for mega_bullet in self.mega_bullets.sprites(): mega_bullet.draw_bullet() self.aliens.draw(self.screen) # Вывод информации о счете. self.score.show_score() if not self.stats.game_active: self.play_button.draw_button() pygame.display.flip() def _fire_bullet(self): """Создание нового снаряда и включение его в группу bullets.""" if len(self.bullets) < self.settings.max_bullets: self.bullets.add(Bullet(self)) def _fire_mega_bullet(self): self.mega_bullets.add(MegaBullet(self)) def _create_alien(self, alien_number, row_number): """Создание пришельца и размещение его в ряду.""" 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): """Создание флота вторжения.""" # Создание одного пришельца, не включенного во флот, # для расчета максимального количествыа пришельцев в ряду # TODO: оптипизировать alien = Alien(self) alien_width, alien_height = alien.rect.size available_space_x = self.settings.screen_width - (2 * alien_width) number_of_aliens_x = available_space_x // (2 * alien_width) available_space_y = (self.settings.screen_height - (3 * alien_height) - self.ship.rect.height) number_of_rows_y = available_space_y // (2 * alien_height) # Создание флота пришельцев. for row_number in range(number_of_rows_y): for alien_number in range(number_of_aliens_x): self._create_alien(alien_number, row_number) def _change_fleet_direction(self): """Опускает весь флот и меняет направление флота.""" for alien in self.aliens.sprites(): alien.rect.y += self.settings.fleet_speed self.settings.fleet_direction *= -1 def _using_mega_bullets(self): # Обработка читерских пуль self.mega_bullets.update() for mega_bullet in self.mega_bullets.copy(): if mega_bullet.rect.bottom <= 0: self.mega_bullets.remove(mega_bullet) pygame.sprite.groupcollide( self.mega_bullets, self.aliens, False, True, ) def _ship_hit(self): """Обрабатывает столкновение корабля с пришельцем.""" self.stats.ships_left -= 1 self.score.prep_ships() if self.stats.ships_left > 0: self.aliens.empty() self.bullets.empty() self._create_fleet() self.ship.center_ship() time.sleep(2) else: self.stats.game_active = False pygame.mouse.set_visible(True) def run_game(self): """Запуск основного цикла игры.""" while True: self._check_events() if self.stats.game_active: self.ship.update() self._update_bullets() self._update_aliens() self._update_screen()
class AlienInvasion: """Overall class to manage game assets and behavior.""" def __init__(self): """Initialize the game, and create game resources.""" pygame.init() # init of pygame which allows us to use various commands of pygame self.settings = Settings() # default settings are inside Settings class self.screen = pygame.display.set_mode((0, 0), pygame.FULLSCREEN) # width and height self.settings.screen_width = self.screen.get_rect().width self.settings.screen_height = self.screen.get_rect().height pygame.display.set_caption("Alien Invasion") # title self.stats = GameStats(self) self.sb = ScoreBoard(self) self.ship = Ship(self) # passing current instance of AlienInvasion class to Ship class self.bullets = pygame.sprite.Group() # creates empty group for bullets self.aliens = pygame.sprite.Group() # creates empty group for aliens self._create_fleet() self.easy_button = Button(self, 'Easy', (0, 255, 0)) self.medium_button = Button(self, 'Medium', (255, 255, 0)) self.hard_button = Button(self, 'Hard', (255, 0, 0)) def run_game(self): """Start the main loop for the game.""" while True: # this loop runs continuously self._check_events() if self.stats.game_active: self.ship.update() self._update_bullets() self._update_aliens() self._update_screen() def _check_events(self): # helper method starts with underscore """Respond to keypresses and mouse events""" for event in pygame.event.get(): # watch for the keyboard and mouse events if event.type == pygame.QUIT: # checks if cross button is clicked 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_button(mouse_pos) def _check_button(self, mouse_pos): """Starts a new game when player clicks Play""" easy_button_clicked = self.easy_button.rect.collidepoint(mouse_pos) medium_button_clicked = self.medium_button.rect.collidepoint(mouse_pos) hard_button_clicked = self.hard_button.rect.collidepoint(mouse_pos) if easy_button_clicked and not self.stats.game_active: self.settings.initialize_dynamic_settings(1.0) self._start_game() elif medium_button_clicked and not self.stats.game_active: self.settings.initialize_dynamic_settings(1.5) self._start_game() elif hard_button_clicked and not self.stats.game_active: self.settings.initialize_dynamic_settings(2.0) self._start_game() 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 _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 def _check_keydown_events(self, event): 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() elif event.key == pygame.K_SPACE: self._fire_bullet() # elif event.key == pygame.K_p: # self._start_game() def _start_game(self): self.stats.reset_stats() self.stats.game_active = True self.sb.prep_score() self.sb.prep_level() self.sb.prep_ships() self.aliens.empty() self.bullets.empty() self._create_fleet() self.ship.center_ship() # Hide the mouse cursor. pygame.mouse.set_visible(False) def _update_bullets(self): """Update position of bullets and get rid of old bullets.""" # Update bullet positions. self.bullets.update() # Getting rid of the bullets that disappered for bullet in self.bullets.copy(): if bullet.rect.top <= 0: self.bullets.remove(bullet) self._check_bullet_alien_collisions() def _check_bullet_alien_collisions(self): # Check for any bullets that have hit aliens. # If so, get rid of the bullet and the alien. collisions = pygame.sprite.groupcollide( self.bullets, self.aliens, False, 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.bullets.empty() self._create_fleet() self.settings.increase_speed() self.stats.level += 1 self.sb.prep_level() def _create_fleet(self): """Create the fleet of aliens.""" # Create an alien and find the number of aliens in the row # Spacing between two aliens is one alien width alien = Alien(self) alien_width, alien_height = alien.rect.size available_width_x = self.settings.screen_width - 2 * alien_width number_alien_x = available_width_x // (2 * alien_width) ship_height = self.ship.rect.height available_height_y = self.settings.screen_height - 3 * alien_height - ship_height number_rows = available_height_y // (2 * alien_height) # Create the first row of aliens for row_number in range(number_rows): for alien_number in range(number_alien_x): self._create_alien(alien_number, row_number) def _create_alien(self, alien_number, row_number): 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 _check_fleet_edges(self): """Respond appropriately if any aliens have reached an edge.""" for alien in self.aliens.sprites(): if alien.check_edges(): self._change_fleet_direction() break 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 _update_aliens(self): """ Check if the fleet is at an edge, then update the positions of all aliens in the fleet. """ self._check_fleet_edges() self.aliens.update() if pygame.sprite.spritecollideany(self.ship, self.aliens): self._ship_hit() self._check_aliens_bottom() def _ship_hit(self): if self.stats.ships_left > 0: self.stats.ships_left -= 1 self.sb.prep_ships() self.bullets.empty() self.aliens.empty() self._create_fleet() self.ship.center_ship() sleep(0.5) else: self.stats.game_active = False pygame.mouse.set_visible(True) def _check_aliens_bottom(self): """If any alien reaches the bottom of the screen""" screen_rect = self.screen.get_rect() for alien in self.aliens.sprites(): if alien.rect.bottom >= screen_rect.bottom: self._ship_hit() break def _update_screen(self): """Update images on the screen, and flip to the new screen.""" self.screen.fill(self.settings.bg_color) # sets the bg color self.ship.blitme() for bullet in self.bullets.sprites(): bullet.draw_bullet() self.aliens.draw(self.screen) self.sb.show_score() # Draw the play button if the game is inactive. if not self.stats.game_active: self.easy_button.draw_button('easy') self.medium_button.draw_button('medium') self.hard_button.draw_button('hard') pygame.display.flip() # Make the most recently drawn screen visible.
class AlienInvasion: """初始化游戏资源和行为的类""" def __init__(self): """初始化游戏并创建游戏资源""" pygame.init() # 初始化背景设置,让 Pygame 能正常工作 self.settings = Settings() # 创建Settings实例并用它来访问设置 # 创建一个显示窗口。参数是元组,单位为像素,返回对象是surface(屏幕的一部分,用于显示游戏元素,这里表示整个游戏窗口) self.screen = pygame.display.set_mode( (self.settings.screen_width, self.settings.screen_height)) self.stats = GameStats(self) # 创建存储游戏统计信息的实例 self.scoreboard = ScoreBoard(self) # 创建记分牌 self.ship = Ship(self) self.bullets = pygame.sprite.Group() # 创建用于存储子弹的编组 self.aliens = pygame.sprite.Group() # 创建用于存储外星人的编组 self.play_button = Button(self, "Play") # 创建 Play 按钮 self._create_fleet() pygame.display.set_caption("Alien Invasion") def run_game(self): """开始游戏的主循环""" 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): """响应按键和鼠标事件""" for event in pygame.event.get(): # 得到一个监听键盘和鼠标事件列表(上一次被调用后发生的所有事件) if event.type == pygame.QUIT: # 玩家单击游戏窗口的关闭按钮时,将检测到 pygame.QUIT事件 sys.exit() # 退出游戏 elif event.type == pygame.KEYDOWN: # 玩家每次按键都被注册为一个KEYDOWN事件 self._check_keydown_events(event) elif event.type == pygame.KEYUP: self._check_keyup_events(event) elif event.type == pygame.MOUSEBUTTONDOWN: # 玩家点击 Play 按钮 mouse_pos = pygame.mouse.get_pos() self._check_play_button(mouse_pos) def _check_keydown_events(self, event): """响应按键""" 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_SPACE: self._fire_bullet() elif event.key == pygame.K_q: sys.exit() def _create_fleet(self): """创建外星人群""" # 创建第一个外星人并计算一行可容纳多少个外星人 alien = Alien(self) alien_width = alien.rect.width alien_height = alien.rect.height available_space_x = self.settings.screen_width - alien_width available_space_y = self.settings.screen_height - 3 * alien_height - self.ship.rect.height num_aliens_x = available_space_x // (2 * alien_width) num_aliens_rows = available_space_y // (2 * alien_height) # 创建外星人群 for row_number in range(num_aliens_rows): for alien_number in range(num_aliens_x): self._create_alien(alien_number, row_number, alien_width, alien_height) def _create_alien(self, alien_number, row_number, alien_width, alien_height): """创建一个外星人群""" alien = Alien(self) alien.x = alien_width + alien_number * alien_width * 2 alien.y = alien_height + 10 + row_number * alien_height * 2 alien.rect.x = alien.x alien.rect.y = alien.y self.aliens.add(alien) def _fire_bullet(self): """创建一颗子弹,并将其加入编组bullets中""" if len(self.bullets) < self.settings.bullet_allowed: new_bullet = Bullet(self) # !! 别忘了传入 ai_game self.bullets.add(new_bullet) def _update_bullets(self): """更新子弹的位置并删除消失的子弹""" self.bullets.update() # 对编组调用update()时,编组自动对其中的每个精灵调用 update() # 删除消失的子弹 for bullet in self.bullets.copy(): if bullet.rect.bottom <= 0: self.bullets.remove(bullet) # print(len(self.bullets)) self._check_bullet_alien_collisions() # 射杀外星人 def _check_bullet_alien_collisions(self): """检查子弹和为行人的碰撞""" # 检查是否有子弹击中了外星人,若有则删除相应的子弹和外星人 collisions = pygame.sprite.groupcollide(self.bullets, self.aliens, True, True) if collisions: # 记分 for aliens in collisions.values(): # 保证消灭的每个外星人都计入得分,aliens是个列表 self.stats.score += self.settings.alien_points * len(aliens) self.scoreboard.prep_score() self.scoreboard.check_high_score() # 若外星人群被消灭,则删除现有的子弹并新建一群外星人,并加快游戏的节奏,提升玩家等级 if not self.aliens: self.bullets.empty() self._create_fleet() self.settings.increase_speed() self.stats.level += 1 self.scoreboard.prep_level() def _update_aliens(self): """检查是否有外星人位于屏幕边缘,并更新外星人群中所有外星人的位置""" self._check_fleet_edge() self.aliens.update() # 检测外星人和飞船之间的碰撞 if pygame.sprite.spritecollideany(self.ship, self.aliens): self._ship_hit() # 检查是否有外星人到达屏幕底端 self._check_aliens_bottom() def _check_fleet_edge(self): """有外星人到达边缘时采取相应的措施""" for alien in self.aliens.sprites(): if alien.check_edge(): self._change_fleet_direction() break def _change_fleet_direction(self): """将整群外星人下移,并改变方向""" for alien in self.aliens.sprites(): alien.rect.y += self.settings.fleet_drop_speed self.settings.fleet_direction *= -1 def _ship_hit(self): """飞船被外星人撞到""" if self.stats.ships_left > 0: # 将ship_left - 1 self.stats.ships_left -= 1 # 更新记分牌 self.scoreboard.prep_ships() # 清空剩余的外星人和子弹 self.aliens.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 _check_aliens_bottom(self): """检查是否有外星人到达了屏幕底端""" for alien in self.aliens.sprites(): if alien.rect.bottom >= self.screen.get_rect().bottom: self._ship_hit() # 像飞船被撞到一样处理 break def _check_play_button(self, mouse_pos): """在玩家单击 Play 按钮时开始新游戏""" button_checked = self.play_button.rect.collidepoint(mouse_pos) if button_checked and not self.stats.game_active: # 防止用户在游戏过程中点击了按钮所在区域时,游戏重新开始 # 隐藏鼠标光标 pygame.mouse.set_visible(False) # 重置游戏设置 self.settings.initialize_dynamic_settings() # 重置游戏统计信息 self.stats.reset_stats() self.stats.game_active = True self.scoreboard.prep_score() # 分数要改变 self.scoreboard.prep_level() # 等级要改变 self.scoreboard.prep_ships() # 余下飞船数要改变 # 清空余下的外星人和子弹 self.aliens.empty() self.bullets.empty() # 创建一群新的外星人,并将飞船放在屏幕底部中央 self._create_fleet() self.ship.center_ship() 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 def _update_screen(self): """更新屏幕上的图像,并切换到新屏幕""" self.screen.fill( self.settings.bg_color) # 颜色,fill()方法用于处理surface,只接受一个实参——一种颜色 self.ship.blitme() # 绘制飞船 for bullet in self.bullets.sprites(): bullet.draw_bullet() self.aliens.draw(self.screen) # 如果游戏处于非活动状态,就绘制Play按钮 if not self.stats.game_active: self.play_button.draw_button() self.scoreboard.show_score_level_ships() # 显示得分、等级和飞船条数 pygame.display.flip() # 让最近绘制的屏幕可见
class AlienAttack: """Overall class to manage game assests and characterstics of game""" def __init__(self): """Initialize the game , and create game resources""" pygame.init() self.setting = Setting() self.bullets = pygame.sprite.Group( ) # use for collecting similar type of object self.screen = pygame.display.set_mode( (0, 0), pygame.FULLSCREEN ) # 0 width and 0 length expresses the full screen self.setting.screen_width = self.screen.get_rect().width self.setting.screen_height = self.screen.get_rect().height # pygame.display.set_caption("Alien Invasion") self.ship = Ship(self) self.enemy = pygame.sprite.Group() self.stats = GameStats(self) self.score_board = ScoreBoard(self) #create a score board self._create_fleet() # as we need only one button then we need to call it once self.play_button = Button(self, "Play") def _create_fleet(self): """Create a fleet of alien""" new_enemy = Enemy(self) enemy_width, enemy_height = new_enemy.rect.size available_space_x = self.setting.screen_width - (2 * enemy_width) number_enemy_x = available_space_x // (2 * enemy_width) # determine the number of rows that will fit ship_height = self.ship.ship_rect.height available_space_y = self.setting.screen_height - ( 3 * enemy_height) - ship_height number_rows = available_space_y // (2 * enemy_height) # create a full fleet of aliens for row_number in range(number_rows + 1): for enemy_number in range(number_enemy_x + 1): self._create_alien(enemy_number, row_number) def _create_alien(self, enemy_number, row_number): new_enemy = Enemy(self) enemy_width, enemy_height = new_enemy.rect.size new_enemy.x = enemy_width + 2 * enemy_width * enemy_number new_enemy.rect.x = new_enemy.x new_enemy.rect.y = new_enemy.rect.height + 2 * new_enemy.rect.height * row_number self.enemy.add(new_enemy) def run_game(self): """Start the main loop for game""" while True: self._check_event() if self.stats.game_active: self.ship.update() self._update_bullets() self._update_enemy() self._update_screen() def _ship_hit(self): """Respond to the ship being hit by alien""" # decrement ship left if self.stats.ships_left > 0: self.stats.ships_left -= 1 self.score_board.prep_ships() # get rid of any remaining aliens and bulllets self.enemy.empty() self.bullets.empty() # Create a new fleet self._create_fleet() self.ship.center_ship() # pause sleep(0.5) else: self.stats.game_active = False self.stats.reset_stat() self.ship.center_ship() pygame.mouse.set_visible(True) self.stats.level = 0 def _update_enemy(self): """Update the position of enemy ships""" self._check_fleet_edges() self.enemy.update() # Look for alien-ship collision if pygame.sprite.spritecollideany( self.ship, self.enemy): # use for collision bw images or rectangles self._ship_hit() self._check_enemy_bottom() def _check_fleet_edges(self): """Respond appropriatly if any aliens have reached an edge""" for enemy in self.enemy.sprites(): if enemy.check_edge(): self._change_fleet_direction() break def _change_fleet_direction(self): """Drop the entire fleet and change the fleet's direction""" for enemy in self.enemy.sprites(): enemy.rect.y += self.setting.fleet_drop_speed self.setting.fleet_direction *= -1 def _update_bullets(self): self.bullets.update() # get rid of the bullets that have disapperead for bullet in self.bullets.copy(): if bullet.rect.y <= 0: self.bullets.remove(bullet) self._check_bullet_enemy_collision() def _check_bullet_enemy_collision(self): """Respond to bullet - alien collision""" # check for any bullet that have hit enemy # if so , get rid of the bullet and the enemy collisions = pygame.sprite.groupcollide(self.bullets, self.enemy, True, True) if not self.enemy: self.bullets.empty() self._create_fleet() self.setting.increase_speed() #increase level self.stats.level += 1 self.score_board.prep_level() if collisions: for enemy in collisions.values(): self.stats.score += self.setting.enemy_point * len(enemy) self.score_board.prep_score() self.score_board.check_high_score() def _check_event(self): """Response to keypress and mouse event""" 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_event(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): """Start a new game when the player clicked clicks play""" button_clicked = self.play_button.rect.collidepoint(mouse_pos) if button_clicked and not self.stats.game_active: self.stats.reset_stat() self.score_board.prep_score() self.setting.initialize_dynamic_setting() self.stats.game_active = True self.score_board.prep_level() pygame.mouse.set_visible(False) self.score_board.prep_ships() # Get rid of any remaining aliens and bullets self.enemy.empty() self.bullets.empty() # create a new fleet and center the ship self._create_fleet() self.ship.center_ship() def _check_keydown_events(self, event): """Response to keyup events""" 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_UP: self.ship.moving_up = True elif event.key == pygame.K_DOWN: self.ship.moving_down = True elif event.key == pygame.K_q: sys.exit() elif event.key == pygame.K_SPACE: self._fire_bullet() def _fire_bullet(self): if len(self.bullets) < self.setting.bullet_alloewed: new_bullet = Bullet(self) self.bullets.add(new_bullet) def _check_keyup_event(self, event): """Response to keyup events""" 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 _update_screen(self): """update images on the screen, and flip to the new screen""" self.screen.fill(self.setting.bg_color) self.ship.blitme() for bullet in self.bullets.sprites(): bullet.draw_bullet() self.enemy.draw(self.screen) self.score_board.show_score() # draw the play button if the game is inactive if not self.stats.game_active: self.play_button.draw_button() """Make the latest change visible on screen""" pygame.display.flip() def _check_enemy_bottom(self): """check if any aliens have reached the bottom of screen""" screen_rect = self.screen.get_rect() for enemy in self.enemy.sprites(): if enemy.rect.bottom >= screen_rect.bottom: self._ship_hit() break