class GameOverScreen(ScreenBase): SCREEN_TITLE_FONT_SIZE = 72 PLAYER_NAME_ENTRY_BOX_FONT_SIZE = 36 RETRY_BUTTON_FONT_SIZE = 24 def __init__(self, display, players, remain_sprites): super().__init__(display) # Game Over music Sounds.game_over() self.score_communicator = ScoreCommunicator('db/scores_db.csv') # Calculate position of game title and buttons self.display_width_factor = display.get_width() / 800 self.display_height_factor = display.get_height() / 640 self.SCREEN_TITLE_CENTER = (self.display_width_factor * 400, self.display_height_factor * 50) self.PLAYER_BOX_CENTER = (self.SCREEN_TITLE_CENTER[0], self.SCREEN_TITLE_CENTER[1] + self.display_height_factor * 200) self.PLAYER_NAME_ENTRY_BOX_CENTER = (self.PLAYER_BOX_CENTER[0], self.PLAYER_BOX_CENTER[1] + self.display_height_factor * 50) self.RETRY_BUTTON_CENTER = (self.PLAYER_NAME_ENTRY_BOX_CENTER[0], self.PLAYER_NAME_ENTRY_BOX_CENTER[1] + self.display_height_factor * 100) self.MAIN_MENU_BUTTON_CENTER = (self.RETRY_BUTTON_CENTER[0], self.RETRY_BUTTON_CENTER[1] + self.display_width_factor * 50) # Create screen title and buttons self.screen_title = TextBox(self.display, self.SCREEN_TITLE_CENTER, self.SCREEN_TITLE_FONT_SIZE, "GAME OVER") self.player_box = TextBox(self.display, self.PLAYER_BOX_CENTER, self.PLAYER_NAME_ENTRY_BOX_FONT_SIZE) self.player_name_entry_box = TextEntryBox( self.display, self.PLAYER_NAME_ENTRY_BOX_CENTER, self.PLAYER_NAME_ENTRY_BOX_FONT_SIZE) self.retry_button = TextButton(self.display, self.RETRY_BUTTON_CENTER, self.RETRY_BUTTON_FONT_SIZE, "RETRY") self.main_menu_button = TextButton(self.display, self.MAIN_MENU_BUTTON_CENTER, self.RETRY_BUTTON_FONT_SIZE, "MAIN MENU") # Receive players information self.players = [] for player in players: self.players.append(player) # Create background with remaining game objects self.remain_sprites = remain_sprites def update(self, event): super().update(event) # If esc is pressed, switch to settings screen if event.type == pg.KEYDOWN: if event.key == pg.K_ESCAPE: self.switch_to_scene( SettingsScreen(self.display, self, self.remain_sprites)) # Update objects movement self.remain_sprites.update() # Update player names entry system if len(self.players) != 0: player_box_dialogue = f'ENTER PLAYER{self.players[0].number} NAME:' self.player_box.set_dialogue(player_box_dialogue) self.player_name_entry_box.update(event) if not self.player_name_entry_box.poll: self.players[0].name = self.player_name_entry_box.entered_text self.score_communicator.write_csv_file(self.players[0].name, self.players[0].score) self.players.remove(self.players[0]) # If all players received a name, end the screen else: self.switch_to_scene(HighScoresScreen(self.display)) # If retry button is clicked, game is restarted ignoring actual player's name self.retry_button.update(event) if self.retry_button.get_clicked(): self.switch_to_scene(GameScreen.GameScreen(self.display)) # If main menun button is clicked, switches to title screen self.main_menu_button.update(event) if self.main_menu_button.get_clicked(): self.switch_to_scene(TitleScreen.TitleScreen(self.display)) # Render all text boxes and draw all sprites def render(self): self.display.fill(self.BG_COLOR) self.screen_title.render() self.player_box.render() self.player_name_entry_box.render() self.retry_button.render() self.main_menu_button.render() self.remain_sprites.draw(self.display)
class TitleScreen(ScreenBase.ScreenBase): GAME_TITLE_FONT_SIZE = 96 BUTTON_FONT_SIZE = 24 def __init__(self, display): super().__init__(display) # Title screen music Sounds.play_title_song() # Calculate position of game title and buttons self.display_width_factor = display.get_width() / 800 self.display_height_factor = display.get_height() / 640 self.GAME_TITLE_CENTER = (self.display_width_factor * 400, self.display_height_factor * 200) self.PLAY_BUTTON_CENTER = (self.GAME_TITLE_CENTER[0], self.GAME_TITLE_CENTER[1] + self.display_height_factor * 150) self.SCORE_BUTTON_CENTER = (self.PLAY_BUTTON_CENTER[0], self.PLAY_BUTTON_CENTER[1] + 50) # Create game title and buttons self.game_title = TextBox(self.display, self.GAME_TITLE_CENTER, self.GAME_TITLE_FONT_SIZE, "METEORITOS") self.play_button = TextButton(self.display, self.PLAY_BUTTON_CENTER, self.BUTTON_FONT_SIZE, "PLAY GAME") self.score_button = TextButton(self.display, self.SCORE_BUTTON_CENTER, self.BUTTON_FONT_SIZE, "HIGH SCORES") # Create background asteroids self.asteroids = pg.sprite.Group() for i in range(12): if i % 3 == 0: self.asteroids.add(SmallAsteroid(display)) elif i % 3 == 1: self.asteroids.add(MediumAsteroid(display)) else: self.asteroids.add(BigAsteroid(display)) def update(self, event): super().update(event) # If esc is pressed, switch to settings screen if event.type == pg.KEYDOWN: if event.key == pg.K_ESCAPE: self.switch_to_scene( SettingsScreen.SettingsScreen(self.display, self, self.asteroids)) self.play_button.update(event) self.score_button.update(event) if self.play_button.get_clicked(): self.switch_to_scene(GameScreen.GameScreen(self.display)) return if self.score_button.get_clicked(): self.switch_to_scene( HighScoresScreen.HighScoresScreen(self.display)) self.asteroids.update() def render(self): self.display.fill(self.BG_COLOR) self.game_title.render() self.play_button.render() self.score_button.render() self.asteroids.draw(self.display)
class HighScoresScreen(ScreenBase): SCREEN_TITLE_FONT_SIZE = 36 BUTTON_FONT_SIZE = 24 SCORE_FONT_SIZE = 24 def __init__(self, display): super().__init__(display) # Calculate position of game title and buttons self.display_width_factor = display.get_width() / 800 self.display_height_factor = display.get_height() / 640 self.SCREEN_TITLE_CENTER = (self.display_width_factor * 400, self.display_height_factor * 50) self.BACK_BUTTON_CENTER = (self.SCREEN_TITLE_CENTER[0] - self.display_height_factor * 250, self.SCREEN_TITLE_CENTER[1] + self.display_height_factor * 50) self.CLEAR_SCORE_BUTTON_CENTER = (self.SCREEN_TITLE_CENTER[0] + self.display_height_factor * 250, self.BACK_BUTTON_CENTER[1]) self.FIRST_SCORE_BOX_CENTER = (self.SCREEN_TITLE_CENTER[0], self.CLEAR_SCORE_BUTTON_CENTER[1] + self.display_height_factor * 50) # Create screen title and buttons self.screen_title = TextBox(self.display, self.SCREEN_TITLE_CENTER, self.SCREEN_TITLE_FONT_SIZE, "HIGH SCORES") self.back_button = TextButton(self.display, self.BACK_BUTTON_CENTER, self.BUTTON_FONT_SIZE, "BACK TO MENU") self.clear_score_button = TextButton(self.display, self.CLEAR_SCORE_BUTTON_CENTER, self.BUTTON_FONT_SIZE, "CLEAR SCORES") # Create vector of text boxes representing the scores table self.score_text_box = [] # Create score communicator path = os.path.dirname(__file__) path = os.path.join(path, os.pardir, os.pardir, 'db', 'scores_db.csv') self.score_communicator = ScoreCommunicator(path) # Create background asteroids self.asteroids = pg.sprite.Group() for i in range(12): if i % 3 == 0: self.asteroids.add(SmallAsteroid(display)) elif i % 3 == 1: self.asteroids.add(MediumAsteroid(display)) else: self.asteroids.add(BigAsteroid(display)) def update(self, event): super().update(event) # If esc is pressed, switch to settings screen if event.type == pg.KEYDOWN: if event.key == pg.K_ESCAPE: self.switch_to_scene( SettingsScreen(self.display, self, self.asteroids)) self.back_button.update(event) self.clear_score_button.update(event) if self.back_button.get_clicked(): self.switch_to_scene(TitleScreen.TitleScreen(self.display)) return if self.clear_score_button.get_clicked(): self.score_communicator.clear_db() return self.score_communicator.read_csv_file() self.score_text_box = [] rows_number = 0 for row in self.score_communicator.scores_table: dialogue = row[0] for i in range(6 - len(row[0])): dialogue = dialogue + ' ' for i in range(15): dialogue = dialogue + '. ' dialogue = dialogue + '%05d' % row[1] center = (self.FIRST_SCORE_BOX_CENTER[0], self.FIRST_SCORE_BOX_CENTER[1] + rows_number * 50) self.score_text_box.append( TextBox(self.display, center, self.SCORE_FONT_SIZE, dialogue)) rows_number += 1 if rows_number >= 9: break self.asteroids.update() def render(self): self.display.fill(self.BG_COLOR) self.screen_title.render() self.back_button.render() self.clear_score_button.render() for text_box in self.score_text_box: text_box.render() self.asteroids.draw(self.display)
class SettingsScreen(ScreenBase): SCREEN_TITLE_FONT_SIZE = 48 SOUND_BUTTON_FONT_SIZE = 36 OPTIONS_FONT_SIZE = 24 RESUME_BUTTON_FONT_SIZE = 24 MENU_SIZE = (600, 500) def __init__(self, display, previous_scene, remain_sprites): super().__init__(display) # Calculate position of game title and buttons self.display_width_factor = display.get_width() / 800 self.display_height_factor = display.get_height() / 640 self.SCREEN_TITLE_CENTER = (self.display_width_factor * 400, self.display_height_factor * 100) self.SOUND_OPTIONS_CENTER = (self.display_width_factor * 400, self.display_height_factor * 200) self.DEFAULT_CENTER = (self.display_width_factor * 250, self.display_height_factor * 250) self.BONUS_CENTER = (self.display_width_factor * 400, self.display_height_factor * 250) self.MUTE_CENTER = (self.display_width_factor * 550, self.display_height_factor * 250) self.RESUME_BUTTON_CENTER = (self.SCREEN_TITLE_CENTER[0], self.SCREEN_TITLE_CENTER[1] + self.display_height_factor * 250) self.LOG_CENTER = (self.RESUME_BUTTON_CENTER[0], self.RESUME_BUTTON_CENTER[1] + self.display_height_factor * 100) self.MAIN_MENU_CENTER = (self.LOG_CENTER[0], self.LOG_CENTER[1] + self.display_height_factor * 100) # Create screen title and buttons self.screen_title = TextBox(self.display, self.SCREEN_TITLE_CENTER, self.SCREEN_TITLE_FONT_SIZE, "SETTINGS") self.sound_options = TextBox(self.display, self.SOUND_OPTIONS_CENTER, self.SOUND_BUTTON_FONT_SIZE, "SOUND OPTIONS") self.default = TextButton(self.display, self.DEFAULT_CENTER, self.OPTIONS_FONT_SIZE, "DEFAULT") self.bonus = TextButton(self.display, self.BONUS_CENTER, self.OPTIONS_FONT_SIZE, "BONUS") self.none = TextButton(self.display, self.MUTE_CENTER, self.OPTIONS_FONT_SIZE, "MUTE") self.resume_button = TextButton(self.display, self.RESUME_BUTTON_CENTER, self.RESUME_BUTTON_FONT_SIZE, "RESUME") self.log_button = TextButton(self.display, self.LOG_CENTER, self.RESUME_BUTTON_FONT_SIZE, "LOG") self.main_menu_button = TextButton(self.display, self.MAIN_MENU_CENTER, self.RESUME_BUTTON_FONT_SIZE, "MAIN MENU") # Create a rect to fill with nothing but the settings menu self.menu_rect = pg.Rect( self.display.get_width() / 2 - self.display_height_factor * self.MENU_SIZE[0] / 2, self.display.get_height() / 2 - self.display_height_factor * self.MENU_SIZE[1] / 2, self.MENU_SIZE[0], self.MENU_SIZE[1]) # Store previous scene for later callback self.previous_scene = previous_scene # Create background with remaining game objects self.remain_sprites = remain_sprites def update(self, event): super().update(event) # If esc is pressed, switch to previous scene if event.type == pg.KEYDOWN: if event.key == pg.K_ESCAPE: self.switch_to_scene(self.previous_scene) # If default is pressed change sound_param self.default.update(event) if self.default.get_clicked(): Sounds.sound_param = 1 Sounds.unpause_title_song() # If bonus is pressed change sound_param self.bonus.update(event) if self.bonus.get_clicked(): Sounds.sound_param = 2 Sounds.unpause_title_song() # If none is pressed change sound_param self.none.update(event) if self.none.get_clicked(): Sounds.sound_param = 0 Sounds.pause_title_song() # If resume button is clicked, back to the previous scene self.resume_button.update(event) if self.resume_button.get_clicked(): self.switch_to_scene(self.previous_scene) # If log button is clicked, switch logging state of previous scene, if possible self.log_button.update(event) if self.log_button.get_clicked(): if self.previous_scene.__class__.__name__ == "GameScreen": self.previous_scene.logging = not self.previous_scene.logging # If main menu button is clicked, switches to title screen self.main_menu_button.update(event) if self.main_menu_button.get_clicked(): self.switch_to_scene(TitleScreen.TitleScreen(self.display)) # Render all text boxes and draw all sprites def render(self): self.display.fill(self.BG_COLOR) self.remain_sprites.draw(self.display) self.display.fill(self.BG_COLOR, self.menu_rect) self.screen_title.render() self.sound_options.render() self.default.render() self.bonus.render() self.none.render() self.resume_button.render() self.log_button.render() self.main_menu_button.render()