Exemple #1
0
class PacManPortalGame:

    game_color = (0, 0, 0)
    event_start = pygame.USEREVENT + 1
    event_remake = pygame.USEREVENT + 2
    event_next_level = pygame.USEREVENT + 3

    def __init__(self):
        pygame.init()
        pygame.mixer.music.load('sounds/bg-music.wav')
        self.game_screen = pygame.display.set_mode((800, 600))
        pygame.display.set_caption('PacMan Portal')
        self.tick_component = pygame.time.Clock()
        self.hold_score = ScoreController(
            screen=self.game_screen,
            sb_pos=((self.game_screen.get_width() // 5),
                    (self.game_screen.get_height() * 0.965)),
            items_image='apple.png',
            itc_pos=(int(self.game_screen.get_width() * 0.6),
                     self.game_screen.get_height() * 0.965))
        self.map_layout = Maze(screen=self.game_screen,
                               maze_map_file='maze_map.txt')
        self.lives_left = PacManCounter(
            screen=self.game_screen,
            ct_pos=((self.game_screen.get_width() // 3),
                    (self.game_screen.get_height() * 0.965)),
            images_size=(self.map_layout.block_size,
                         self.map_layout.block_size))
        self.next_level = LevelTransition(screen=self.game_screen,
                                          score_controller=self.hold_score)
        self.lost_game = True
        self.pause_game = False
        self.pacman_player = PacMan(screen=self.game_screen,
                                    maze=self.map_layout)
        self.pacman_ghosts = pygame.sprite.Group()
        self.pacman_ghosts_sound = SoundManager(
            sound_files=['ghost-blue.wav', 'ghost-eaten.wav', 'ghost-std.wav'],
            keys=['blue', 'eaten', 'std'],
            channel=Ghost.ghost_audio)
        self.pacman_ghosts_interval_active = 2500
        self.pacman_ghosts_begin_chase = None
        self.pacman_ghosts_blinky = None
        self.pacman_ghosts_others = []
        self.blit_ghosts()
        self.game_actions = {
            PacManPortalGame.event_start: self.init_ghosts,
            PacManPortalGame.event_remake: self.rebuild_maze,
            PacManPortalGame.event_next_level: self.next_level
        }

    def play_game(self):
        event_iterator = EventLoop(loop_running=True,
                                   actions={
                                       **self.pacman_player.event_map,
                                       **self.game_actions
                                   })
        self.next_level.set_show_transition()
        self.lost_game = False
        if self.pacman_player.dead:
            self.pacman_player.revive()
            self.hold_score.reset_level()
            self.lives_left.reset_counter()
            self.rebuild_maze()

        while event_iterator.loop_running:
            self.tick_component.tick(60)
            event_iterator.check_events()
            self.update_screen()
            if self.lost_game:
                pygame.mixer.stop()
                self.hold_score.reset_level()
                event_iterator.loop_running = False

    def run(self):
        play_menu = Menu(self.game_screen)
        high_score_menu = HighScoreScreen(self.game_screen, self.hold_score)
        intro_ghost_chase = Intro(self.game_screen)
        event_iterator = EventLoop(
            loop_running=True,
            actions={pygame.MOUSEBUTTONDOWN: play_menu.check_buttons})

        while event_iterator.loop_running:
            self.tick_component.tick(60)
            event_iterator.check_events()
            self.game_screen.fill(PacManPortalGame.game_color)
            if not play_menu.high_score_menu:
                intro_ghost_chase.update()
                intro_ghost_chase.blit()
                play_menu.blit()
            else:
                high_score_menu.blit()
                high_score_menu.check_done()
            if play_menu.ready_to_play:
                pygame.mixer.music.stop()
                self.play_game()
                for g in self.pacman_ghosts:
                    g.reset_speed()
                play_menu.ready_to_play = False
                self.hold_score.save_high_scores()
                high_score_menu.prep_images()
                high_score_menu.position()
            elif not pygame.mixer.music.get_busy():
                pygame.mixer.music.play(-1)
            pygame.display.flip()

    def init_ghosts(self):
        if not self.pacman_ghosts_blinky.state['enabled']:
            self.pacman_ghosts_blinky.enable()
            self.pacman_ghosts_begin_chase = self.pacman_ghosts_others.copy()
            pygame.time.set_timer(PacManPortalGame.event_start, 0)
            pygame.time.set_timer(PacManPortalGame.event_start,
                                  self.pacman_ghosts_interval_active)
        else:
            try:
                g = self.pacman_ghosts_begin_chase.pop()
                g.enable()
            except IndexError:
                pygame.time.set_timer(PacManPortalGame.event_start, 0)

    def blit_ghosts(self):
        ghost_images_file = [
            'ghost-pink.png', 'ghost-lblue.png', 'ghost-orange.png',
            'ghost-red.png'
        ]
        location = 0
        while len(self.map_layout.ghost_spawn) > 0:
            spawn_info = self.map_layout.ghost_spawn.pop()
            g = Ghost(screen=self.game_screen,
                      maze=self.map_layout,
                      target=self.pacman_player,
                      spawn_info=spawn_info,
                      ghost_file=ghost_images_file[location],
                      sound_manager=self.pacman_ghosts_sound)
            if ghost_images_file[location] == 'ghost-red.png':
                self.pacman_ghosts_blinky = g
            else:
                self.pacman_ghosts_others.append(g)
            self.pacman_ghosts.add(g)
            location = (location + 1) % len(ghost_images_file)

    def next_level(self):
        pygame.time.set_timer(PacManPortalGame.event_next_level, 0)
        self.pacman_player.clear_portals()
        self.hold_score.increment_level()
        self.rebuild_maze()

    def rebuild_maze(self):
        if self.lives_left.lives > 0:
            for g in self.pacman_ghosts:
                if g.state['enabled']:
                    g.disable()
            self.map_layout.build_maze()
            self.pacman_player.reset_position()
            for g in self.pacman_ghosts:
                g.reset_position()
            if self.pacman_player.dead:
                self.pacman_player.revive()
            if self.pause_game:
                self.pause_game = False
            self.next_level.set_show_transition()
        else:
            self.lost_game = True
        pygame.time.set_timer(PacManPortalGame.event_remake, 0)

    def check_player(self):
        pacman_player_score, pacman_player_fruits, pacman_player_ability = self.pacman_player.eat(
        )
        self.hold_score.add_score(
            score=pacman_player_score,
            items=pacman_player_fruits if pacman_player_fruits > 0 else None)
        if pacman_player_ability:
            for g in self.pacman_ghosts:
                g.begin_blue_state()
        touch_ghost = pygame.sprite.spritecollideany(self.pacman_player,
                                                     self.pacman_ghosts)
        if touch_ghost and touch_ghost.state['blue']:
            touch_ghost.set_eaten()
            self.hold_score.add_score(200)
        elif touch_ghost and not (self.pacman_player.dead
                                  or touch_ghost.state['return']):
            self.lives_left.decrement()
            self.pacman_player.clear_portals()
            self.pacman_player.set_death()
            for g in self.pacman_ghosts:
                if g.state['enabled']:
                    g.disable()
            pygame.time.set_timer(PacManPortalGame.event_start, 0)
            pygame.time.set_timer(PacManPortalGame.event_remake, 4000)
        elif not self.map_layout.pellets_left() and not self.pause_game:
            pygame.mixer.stop()
            self.pause_game = True
            pygame.time.set_timer(PacManPortalGame.event_next_level, 1000)

    def update_screen(self):
        if not self.next_level.transition_show:
            self.game_screen.fill(PacManPortalGame.game_color)
            self.check_player()
            self.map_layout.blit()
            if not self.pause_game:
                self.pacman_ghosts.update()
                self.pacman_player.update()
                self.map_layout.teleport.check_teleport(
                    self.pacman_player.rect)
            for g in self.pacman_ghosts:
                if self.hold_score.level > 3:
                    if not g.state['speed_boost']:
                        g.increase_speed()
                    self.map_layout.teleport.check_teleport(g.rect)
                g.blit()
            self.pacman_player.blit()
            self.hold_score.blit()
            self.lives_left.blit()
        elif self.pacman_player.dead:
            self.pacman_player.update()
            self.pacman_player.blit()
        else:
            self.next_level.draw()
            if not self.next_level.transition_show:
                self.init_ghosts()
        pygame.display.flip()
Exemple #2
0
class PacManPortalGame:
    """Contains the main logic and methods
    for the running and updating of the PacMan portal game"""

    BLACK_BG = (0, 0, 0)
    START_EVENT = pygame.USEREVENT + 1
    REBUILD_EVENT = pygame.USEREVENT + 2
    LEVEL_TRANSITION_EVENT = pygame.USEREVENT + 3

    def __init__(self):
        pygame.init()
        pygame.mixer.music.load('sounds/IDKMAN.wav')
        self.screen = pygame.display.set_mode(
            (800, 600)
        )
        pygame.display.set_caption('PacMan Portal')
        self.clock = pygame.time.Clock()
        self.score_keeper = ScoreController(screen=self.screen,
                                            sb_pos=((self.screen.get_width() // 5),
                                                    (self.screen.get_height() * 0.965)),
                                            items_image='cherry.png',
                                            itc_pos=(int(self.screen.get_width() * 0.6),
                                                     self.screen.get_height() * 0.965))
        self.maze = Maze(screen=self.screen, maze_map_file='maze_map.txt')
        self.life_counter = PacManCounter(screen=self.screen, ct_pos=((self.screen.get_width() // 3),
                                                                      (self.screen.get_height() * 0.965)),
                                          images_size=(self.maze.block_size, self.maze.block_size))
        self.level_transition = LevelTransition(screen=self.screen, score_controller=self.score_keeper)
        self.game_over = True
        self.pause = False
        self.player = PacMan(screen=self.screen, maze=self.maze)
        self.ghosts = pygame.sprite.Group()
        self.ghost_sound_manager = SoundManager(sound_files=['RunForestRun.wav', 'Eaten3.wav', 'babySharkPacman.wav'],
                                                keys=['blue', 'eaten', 'std'],
                                                channel=Ghost.GHOST_AUDIO_CHANNEL)
        self.ghost_active_interval = 2500
        self.ghosts_to_activate = None
        self.first_ghost = None
        self.other_ghosts = []
        self.spawn_ghosts()
        self.actions = {PacManPortalGame.START_EVENT: self.init_ghosts,
                        PacManPortalGame.REBUILD_EVENT: self.rebuild_maze,
                        PacManPortalGame.LEVEL_TRANSITION_EVENT: self.next_level}

    def init_ghosts(self):
        """kick start the ghost AI over a period of time"""
        if not self.first_ghost.state['enabled']:
            self.first_ghost.enable()
            self.ghosts_to_activate = self.other_ghosts.copy()
            pygame.time.set_timer(PacManPortalGame.START_EVENT, 0)  # disable timer repeat
            pygame.time.set_timer(PacManPortalGame.START_EVENT, self.ghost_active_interval)
        else:
            try:
                g = self.ghosts_to_activate.pop()
                g.enable()
            except IndexError:
                pygame.time.set_timer(PacManPortalGame.START_EVENT, 0)  # disable timer repeat

    def spawn_ghosts(self):
        """Create all ghosts at their starting positions"""
        files = ['ghost-pink.png', 'ghost-lblue.png', 'ghost-orange.png', 'ghost-red.png']
        idx = 0
        while len(self.maze.ghost_spawn) > 0:
            spawn_info = self.maze.ghost_spawn.pop()
            g = Ghost(screen=self.screen, maze=self.maze, target=self.player,
                      spawn_info=spawn_info, ghost_file=files[idx], sound_manager=self.ghost_sound_manager)
            if files[idx] == 'ghost-red.png':
                self.first_ghost = g    # red ghost should be first
            else:
                self.other_ghosts.append(g)
            self.ghosts.add(g)
            idx = (idx + 1) % len(files)

    def next_level(self):
        """Increment the game level and then continue the game"""
        pygame.time.set_timer(PacManPortalGame.LEVEL_TRANSITION_EVENT, 0)  # reset timer
        self.score_keeper.increment_level()
        self.rebuild_maze()

    def rebuild_maze(self):
        """Resets the maze to its initial state if the game is still active"""
        if self.life_counter.lives > 0:
            for g in self.ghosts:
                if g.state['enabled']:
                    g.disable()
            self.maze.build_maze()
            self.player.reset_position()
            for g in self.ghosts:
                g.reset_position()
            if self.player.dead:
                self.player.revive()
            if self.pause:
                self.pause = False
            self.level_transition.set_show_transition()
        else:
            self.game_over = True
        pygame.time.set_timer(PacManPortalGame.REBUILD_EVENT, 0)    # disable timer repeat

    def check_player(self):
        """Check the player to see if they have been hit by an enemy, or if they have consumed pellets/fruit"""
        n_score, n_fruits, power = self.player.eat()
        self.score_keeper.add_score(score=n_score, items=n_fruits if n_fruits > 0 else None)
        if power:
            for g in self.ghosts:
                g.begin_blue_state()
        ghost_collide = pygame.sprite.spritecollideany(self.player, self.ghosts)
        if ghost_collide and ghost_collide.state['blue']:
            ghost_collide.set_eaten()
            self.score_keeper.add_score(200)
        elif ghost_collide and not (self.player.dead or ghost_collide.state['return']):
            self.life_counter.decrement()
            self.player.set_death()
            for g in self.ghosts:
                if g.state['enabled']:   # disable any ghosts
                    g.disable()
            pygame.time.set_timer(PacManPortalGame.START_EVENT, 0)  # cancel start event
            pygame.time.set_timer(PacManPortalGame.REBUILD_EVENT, 4000)
        elif not self.maze.pellets_left() and not self.pause:
            pygame.mixer.stop()
            self.pause = True
            pygame.time.set_timer(PacManPortalGame.LEVEL_TRANSITION_EVENT, 1000)

    def update_screen(self):
        """Update the game screen"""
        if not self.level_transition.transition_show:
            self.screen.fill(PacManPortalGame.BLACK_BG)
            self.check_player()
            self.maze.blit()
            if not self.pause:
                self.ghosts.update()
                self.player.update()
                # self.maze.teleport.check_teleport(self.player.rect)     # teleport player/projectiles
            for g in self.ghosts:
                if self.score_keeper.level > 3:
                    if not g.state['speed_boost']:
                        g.increase_speed()
                    self.maze.teleport.check_teleport(g.rect)   # teleport ghosts
                g.blit()
            self.player.blit()
            self.score_keeper.blit()
            self.life_counter.blit()
        elif self.player.dead:
            self.player.update()
            self.player.blit()
        else:
            self.level_transition.draw()
            # if transition just finished, init ghosts
            if not self.level_transition.transition_show:
                self.init_ghosts()
        pygame.display.flip()

    def run(self):
        """Run the game application, starting from the menu"""
        menu = Menu(self.screen)
        hs_screen = HighScoreScreen(self.screen, self.score_keeper)
        e_loop = EventLoop(loop_running=True, actions={pygame.MOUSEBUTTONDOWN: menu.check_buttons})

        while e_loop.loop_running:
            self.clock.tick(60)  # 60 fps limit
            e_loop.check_events()
            self.screen.fill(PacManPortalGame.BLACK_BG)
            if not menu.hs_screen:
                menu.update()
                menu.blit()
            else:
                hs_screen.blit()    # display highs score screen
                hs_screen.check_done()
            if menu.ready_to_play:
                pygame.mixer.music.stop()   # stop menu music
                self.play_game()    # player selected play, so run game
                for g in self.ghosts:
                    g.reset_speed()
                menu.ready_to_play = False
                self.score_keeper.save_high_scores()    # save high scores only on complete play
                hs_screen.prep_images()     # update high scores page
                hs_screen.position()
            elif not pygame.mixer.music.get_busy():
                pygame.mixer.music.play(-1)     # music loop
            pygame.display.flip()

    def play_game(self):
        """Run the game's event loop, using an EventLoop object"""
        e_loop = EventLoop(loop_running=True, actions={**self.player.event_map, **self.actions})
        # game init signal
        # pygame.time.set_timer(PacManPortalGame.START_EVENT, self.level_transition.transition_time)
        self.level_transition.set_show_transition()
        self.game_over = False
        if self.player.dead:
            self.player.revive()
            self.score_keeper.reset_level()
            self.life_counter.reset_counter()
            self.rebuild_maze()

        while e_loop.loop_running:
            self.clock.tick(60)  # 60 fps limit
            e_loop.check_events()
            self.update_screen()
            if self.game_over:
                pygame.mixer.stop()
                self.score_keeper.reset_level()
                e_loop.loop_running = False
Exemple #3
0
class PacManPortalGame:

    BLACK_BG = (0, 0, 0)
    START_EVENT = pygame.USEREVENT + 1
    REBUILD_EVENT = pygame.USEREVENT + 2
    LEVEL_TRANSITION_EVENT = pygame.USEREVENT + 3

    def __init__(self):
        pygame.init()
        pygame.mixer.music.load('sounds/bg-music.wav')
        self.screen = pygame.display.set_mode((800, 600))
        pygame.display.set_caption('PacMan')
        self.clock = pygame.time.Clock()
        self.score_keeper = ScoreController(
            screen=self.screen,
            sb_pos=((self.screen.get_width() // 5),
                    (self.screen.get_height() * 0.965)),
            items_image='cherry.png',
            itc_pos=(int(self.screen.get_width() * 0.6),
                     self.screen.get_height() * 0.965))
        self.maze = Maze(screen=self.screen, maze_map_file='maze_map.txt')
        self.life_counter = PacManCounter(
            screen=self.screen,
            ct_pos=((self.screen.get_width() // 3),
                    (self.screen.get_height() * 0.965)),
            images_size=(self.maze.block_size, self.maze.block_size))
        self.level_transition = LevelTransition(
            screen=self.screen, score_controller=self.score_keeper)
        self.game_over = True
        self.pause = False
        self.player = PacMan(screen=self.screen, maze=self.maze)
        self.ghosts = pygame.sprite.Group()
        self.ghost_sound_manager = SoundManager(
            sound_files=['ghost-blue.wav', 'ghost-eaten.wav', 'ghost-std.wav'],
            keys=['blue', 'eaten', 'std'],
            channel=Ghost.GHOST_AUDIO_CHANNEL)
        self.ghost_active_interval = 2500
        self.ghosts_to_activate = None
        self.first_ghost = None
        self.other_ghosts = []
        self.spawn_ghosts()
        self.actions = {
            PacManPortalGame.START_EVENT: self.init_ghosts,
            PacManPortalGame.REBUILD_EVENT: self.rebuild_maze,
            PacManPortalGame.LEVEL_TRANSITION_EVENT: self.next_level
        }

    def init_ghosts(self):
        if not self.first_ghost.state['enabled']:
            self.first_ghost.enable()
            self.ghosts_to_activate = self.other_ghosts.copy()
            pygame.time.set_timer(PacManPortalGame.START_EVENT,
                                  0)  # disable timer repeat
            pygame.time.set_timer(PacManPortalGame.START_EVENT,
                                  self.ghost_active_interval)
        else:
            try:
                g = self.ghosts_to_activate.pop()
                g.enable()
            except IndexError:
                pygame.time.set_timer(PacManPortalGame.START_EVENT,
                                      0)  # disable timer repeat

    def spawn_ghosts(self):
        files = [
            'ghost-pink.png', 'ghost-lblue.png', 'ghost-orange.png',
            'ghost-red.png'
        ]
        idx = 0
        while len(self.maze.ghost_spawn) > 0:
            spawn_info = self.maze.ghost_spawn.pop()
            g = Ghost(screen=self.screen,
                      maze=self.maze,
                      target=self.player,
                      spawn_info=spawn_info,
                      ghost_file=files[idx],
                      sound_manager=self.ghost_sound_manager)
            if files[idx] == 'ghost-red.png':
                self.first_ghost = g  # red ghost should be first
            else:
                self.other_ghosts.append(g)
            self.ghosts.add(g)
            idx = (idx + 1) % len(files)

    def next_level(self):
        pygame.time.set_timer(PacManPortalGame.LEVEL_TRANSITION_EVENT, 0)
        self.score_keeper.increment_level()
        self.rebuild_maze()

    def rebuild_maze(self):
        if self.life_counter.lives > 0:
            for g in self.ghosts:
                if g.state['enabled']:
                    g.disable()
            self.maze.build_maze()
            self.player.reset_position()
            for g in self.ghosts:
                g.reset_position()
            if self.player.dead:
                self.player.revive()
            if self.pause:
                self.pause = False
            self.level_transition.set_show_transition()
        else:
            self.game_over = True
        pygame.time.set_timer(PacManPortalGame.REBUILD_EVENT,
                              0)  # disable timer repeat

    def check_player(self):
        n_score, n_fruits, power = self.player.eat()
        self.score_keeper.add_score(score=n_score,
                                    items=n_fruits if n_fruits > 0 else None)
        if power:
            for g in self.ghosts:
                g.begin_blue_state()
        ghost_collide = pygame.sprite.spritecollideany(self.player,
                                                       self.ghosts)
        if ghost_collide and ghost_collide.state['blue']:
            ghost_collide.set_eaten()
            self.score_keeper.add_score(200)
        elif ghost_collide and not (self.player.dead
                                    or ghost_collide.state['return']):
            self.life_counter.decrement()
            self.player.set_death()
            for g in self.ghosts:
                if g.state['enabled']:
                    g.disable()
            pygame.time.set_timer(PacManPortalGame.START_EVENT,
                                  0)  # cancel start event
            pygame.time.set_timer(PacManPortalGame.REBUILD_EVENT, 4000)
        elif not self.maze.pellets_left() and not self.pause:
            pygame.mixer.stop()
            self.pause = True
            pygame.time.set_timer(PacManPortalGame.LEVEL_TRANSITION_EVENT,
                                  1000)

    def update_screen(self):
        if not self.level_transition.transition_show:
            self.screen.fill(PacManPortalGame.BLACK_BG)
            self.check_player()
            self.maze.blit()
            if not self.pause:
                self.ghosts.update()
                self.player.update()
            for g in self.ghosts:
                if self.score_keeper.level > 3:
                    if not g.state['speed_boost']:
                        g.increase_speed()
                g.blit()
            self.player.blit()
            self.score_keeper.blit()
            self.life_counter.blit()
        elif self.player.dead:
            self.player.update()
            self.player.blit()
        else:
            self.level_transition.draw()
            # if transition just finished, init ghosts
            if not self.level_transition.transition_show:
                self.init_ghosts()
        pygame.display.flip()

    def run(self):
        menu = Menu(self.screen)
        hs_screen = HighScoreScreen(self.screen, self.score_keeper)
        intro_seq = Intro(self.screen)
        e_loop = EventLoop(
            loop_running=True,
            actions={pygame.MOUSEBUTTONDOWN: menu.check_buttons})

        while e_loop.loop_running:
            self.clock.tick(60)  # 60 fps limit
            e_loop.check_events()
            self.screen.fill(PacManPortalGame.BLACK_BG)
            if not menu.hs_screen:
                intro_seq.update()  # display intro/menu
                intro_seq.blit()
                menu.update()
                menu.blit()
            else:
                hs_screen.blit()  # display highs score screen
                hs_screen.check_done()
            if menu.ready_to_play:
                pygame.mixer.music.stop()  # stop menu music
                self.play_game()  # player selected play, so run game
                for g in self.ghosts:
                    g.reset_speed()
                menu.ready_to_play = False
                self.score_keeper.save_high_scores(
                )  # save high scores only on complete play
                hs_screen.prep_images()  # update high scores page
                hs_screen.position()
            elif not pygame.mixer.music.get_busy():
                pygame.mixer.music.play(-1)  # music loop
            pygame.display.flip()

    def play_game(self):
        e_loop = EventLoop(loop_running=True,
                           actions={
                               **self.player.event_map,
                               **self.actions
                           })
        self.level_transition.set_show_transition()
        self.game_over = False
        if self.player.dead:
            self.player.revive()
            self.score_keeper.reset_level()
            self.life_counter.reset_counter()
            self.rebuild_maze()

        while e_loop.loop_running:
            self.clock.tick(60)  # 60 fps limit
            e_loop.check_events()
            self.update_screen()
            if self.game_over:
                pygame.mixer.stop()
                self.score_keeper.reset_level()
                e_loop.loop_running = False
Exemple #4
0
class Game:
    def __init__(self):
        pygame.init()
        pygame.mixer.music.load('sounds/Pac-Man-Theme-Song.mp3')
        self.screen = pygame.display.set_mode((550, 800))
        pygame.display.set_caption('PacMan Portal')
        self.clock = pygame.time.Clock()

        self.score_keeper = ScoreController(
            screen=self.screen,
            sb_pos=((self.screen.get_width() / 5),
                    (self.screen.get_height() * 0.965)),
            items_image='img/berry.png',
            itc_pos=(int(self.screen.get_width() * 0.6),
                     self.screen.get_height() * 0.965))
        self.maze = Maze(self.screen, 'maze.txt')
        self.life_counter = Counter(
            screen=self.screen,
            ct_pos=((self.screen.get_width() // 3),
                    (self.screen.get_height() * 0.965)),
            images_size=(self.maze.block_size, self.maze.block_size))
        self.game_over = True
        self.player = PacMan(screen=self.screen, maze=self.maze)
        self.ghosts = pygame.sprite.Group()
        self.ghost_active_interval = 2500
        self.ghosts_to_activate = None
        self.first_ghost = None
        self.other_ghosts = []
        self.enemies()
        self.actions = {pygame.USEREVENT: self.reset_maze}

    def enemies(self):
        types = ['pink', 'cyan', 'red', 'orange']
        index = 0
        while len(self.maze.ghost_spawn) > 0:
            spawn_info = self.maze.ghost_spawn.pop()
            g = Ghost(screen=self.screen,
                      maze=self.maze,
                      info=spawn_info,
                      file=types[index])
            if types[index] == 'ghost-red.png':
                self.first_ghost = g  # red ghost should be first
            else:
                self.other_ghosts.append(g)
            self.ghosts.add(g)
            index = (index + 1) % len(types)

    def reset_maze(self):
        if self.life_counter.lives > 0:
            pygame.mixer.music.stop()
            self.maze.build_maze()
            self.player.reset_position()
            if self.player.dead:
                self.player.revive()
        else:
            self.game_over = True

    def check_player(self):
        n_score, n_fruits, power = self.player.collide()
        self.score_keeper.add_score(n_score, n_fruits)
        if power:
            for g in self.ghosts:
                g.trigger()
        ghost_collide = pygame.sprite.spritecollideany(self.player,
                                                       self.ghosts)
        if ghost_collide and ghost_collide.kill:
            ghost_collide.set_eaten()
            self.score_keeper.add_score(200)
        elif ghost_collide and not (self.player.dead or ghost_collide.ret):
            self.life_counter.decrement()
            self.player.set_death()
            for g in self.ghosts:
                if g.state.on:
                    g.disable()

    def update_screen(self):
        if not self.player.dead:
            self.screen.fill(Colors().black)
            self.check_player()
            self.maze.blit()
            self.player.update()
            for enemy in self.ghosts:
                enemy.update()
                enemy.blit()
            self.player.blit()
            self.score_keeper.blit()
            self.life_counter.blit()
        elif self.player.dead:
            self.player.update()
            self.player.blit()

        pygame.display.flip()

    def play(self):
        menu = Menu(self.screen)
        hs_screen = HighScoreScreen(self.screen, self.score_keeper)
        intro_seq = Intro(self.screen)
        loop = Events(runs=True, actions={pygame.MOUSEBUTTONDOWN: menu.check})

        while loop.runs:
            self.clock.tick(60)
            loop.check_events()
            self.screen.fill((0, 0, 0))
            if not menu.hs_screen:
                intro_seq.update()
                intro_seq.blit()
                menu.update()
                menu.blit()
            else:
                hs_screen.blit()
                hs_screen.check_done()
            if menu.ready_to_play:
                pygame.mixer.music.stop()
                pygame.mixer.music.load('sounds/waka.wav')
                pygame.mixer.music.play()
                self.play_game()
                menu.ready_to_play = False
                self.score_keeper.save_high_scores()
                hs_screen.prep_images()
                hs_screen.position()
            elif not pygame.mixer.music.get_busy():
                pygame.mixer.music.play(-1)
            pygame.display.flip()

    def play_game(self):
        loop = Events(True, {**self.player.event_map, **self.actions})
        self.game_over = False
        if self.player.dead:
            self.player.revive()
            self.score_keeper.reset_level()
            self.life_counter.reset_counter()
            self.reset_maze()

        while loop.runs:
            loop.check_events()
            self.update_screen()
            if self.game_over:
                pygame.mixer.stop()
                self.score_keeper.reset_level()
                loop.runs = False