Exemple #1
0
class Game:
    """
    Main game class
    Contains other game classes: dungeon map, player map, player itself
    """
    def __init__(self):

        self.dungeon_map = DungeonMap()
        self.player_map = PlayerMap()
        self.player = Player()

    @log_decorator
    def setup_game(self):
        """
        Game startup method: user should choose between playing new game or loading save
        """
        my_logger.debug("Game start choice")
        start_game_choice = input(
            'Enter "y" if you want to play a new game or\n"load" if you want to load existing game:\n'
        )
        my_logger.debug("Game start choice handling")

        if start_game_choice == "load":

            self.load_game()

        else:

            map_request = input(
                'Enter preferable map size in format "width:height", or just press enter to play with default map:\n'
            )
            my_logger.info("Generating map...")

            if not len(map_request):

                map_size = [20, 10]

            else:

                map_size = [int(token) for token in map_request.split(':')]

            self.dungeon_map.set_map_size(*map_size)
            self.dungeon_map.generate_map()
            my_logger.info("Map has been generated successfully!")

            self.player_map.set_map_size(*map_size)
            self.player_map.init_map()

            self.player.reset()
            self.player.randomize_initial_position(self.dungeon_map)

        self.player_map.update_map(self.dungeon_map, self.player.player_x,
                                   self.player.player_y)
        self.player_map.draw_map()

    @log_decorator
    def load_game(self):
        """
        Game load (pickle!)
        """
        my_logger.info("Loading game...")
        in_file = open('dungeon.sav', 'rb')

        data = pickle.load(in_file)

        [
            self.dungeon_map.dungeon_map, self.dungeon_map.map_size,
            self.player_map.dungeon_map, self.player.player_x,
            self.player.player_y, self.player.health, self.player.treasures
        ] = data
        my_logger.info("Game has been loaded!")

    @log_decorator
    def save_game(self):
        """
        Game save (pickle!)
        """
        data = [
            self.dungeon_map.dungeon_map, self.dungeon_map.map_size,
            self.player_map.dungeon_map, self.player.player_x,
            self.player.player_y, self.player.health, self.player.treasures
        ]

        out_file = open('dungeon.sav', 'wb')

        pickle.dump(data, out_file)

    @log_decorator
    def run_farame(self):
        """
        Game frame. Returns true if game could be resumed and false otherwise
        """
        ret_value = True
        move = input(
            '\nEnter your move, please (w - up, d - right, s - down, a - left), or "save" for save game:\n'
        )

        if move == "save":

            self.save_game()
            ret_value = False

        self.player.make_move(move, *self.dungeon_map.map_size)

        self.player_map.update_map(self.dungeon_map, self.player.player_x,
                                   self.player.player_y)
        self.player_map.draw_map()

        if self.dungeon_map.get_cell_content(self.player.player_x,
                                             self.player.player_y) == 'T':

            self.dungeon_map.set_cell_content(self.player.player_x,
                                              self.player.player_y, '-')
            self.player.add_treasure()

        elif self.dungeon_map.get_cell_content(self.player.player_x,
                                               self.player.player_y) == 'X':

            self.dungeon_map.set_cell_content(self.player.player_x,
                                              self.player.player_y, '-')
            self.player.apply_damage()

        self.player.draw_character()

        if self.player.is_dead():

            my_logger.info("\n}}}This is a trap! You loose!{{{\n")
            ret_value = False

        elif self.player.is_winner():

            my_logger.info("\n>>>This is a treasure! You are victorious!<<<\n")
            ret_value = False

        return ret_value
class Game:
    """
    Main game class
    Contains other game classes: dungeon map, player map, player itself
    """
    def __init__(self):

        self.dungeon_map = DungeonMap()
        self.player_map = PlayerMap()
        self.player = Player()

    @log_decorator
    def setup_new_game(self):
        """
        This function is used to generate new map of size, specified by user
        """
        while True:

            map_request = input(
                'Enter preferable map size in format "width:height", or just press enter to play with default map:\n'
            )
            my_logger.info("Generating map...")

            if not len(map_request):

                map_size = [20, 10]
                break

            else:

                try:

                    map_size = [int(token) for token in map_request.split(':')]
                    break

                except ValueError as val_error:

                    my_logger.exception(val_error)
                    my_logger.error("Try to enter map size once again!")

        self.dungeon_map.set_map_size(*map_size)
        self.dungeon_map.generate_map()
        my_logger.info("Map has been generated successfully!")

        self.player_map.set_map_size(*map_size)
        self.player_map.init_map()

        self.player.reset()
        self.player.randomize_initial_position(self.dungeon_map)

    @log_decorator
    def setup_game(self):
        """
        Game startup method: user should choose between playing new game or loading save
        """
        my_logger.debug("Game start choice")
        start_game_choice = input(
            'Enter "y" if you want to play a new game or\n"load" if you want to load existing game:\n'
        )
        my_logger.debug("Game start choice handling")

        if start_game_choice == "load":

            try:

                self.load_game()

            except (FileNotFoundError, pickle.UnpicklingError) as file_error:

                my_logger.exception(file_error)

                if isinstance(file_error, FileNotFoundError):

                    my_logger.error(
                        "There is no dungeon.sav file! Start a new game instead!"
                    )

                elif isinstance(file_error, pickle.UnpicklingError):

                    my_logger.error(
                        "dungeon.sav file is corrupted! Start a new game instead!"
                    )

                self.setup_new_game()

        else:

            self.setup_new_game()

        self.player_map.update_map(self.dungeon_map, self.player.player_x,
                                   self.player.player_y)
        self.player_map.draw_map()

    @log_decorator
    def load_game(self):
        """
        Game load (pickle!)
        """
        my_logger.info("Loading game...")
        in_file = open('dungeon.sav', 'rb')

        data = pickle.load(in_file)

        [
            self.dungeon_map.dungeon_map, self.dungeon_map.map_size,
            self.player_map.dungeon_map, self.player.player_x,
            self.player.player_y, self.player.health, self.player.treasures
        ] = data
        my_logger.info("Game has been loaded!")

    @log_decorator
    def save_game(self):
        """
        Game save (pickle!)
        """
        data = [
            self.dungeon_map.dungeon_map, self.dungeon_map.map_size,
            self.player_map.dungeon_map, self.player.player_x,
            self.player.player_y, self.player.health, self.player.treasures
        ]

        try:

            out_file = open('dungeon.sav', 'wb')

        except PermissionError as premission_error:

            my_logger.exception(premission_error)
            my_logger.error(
                "Unable to save game! So sorry! But you can play again!")

        pickle.dump(data, out_file)

    @log_decorator
    def run_farame(self):
        """
        Game frame. Returns true if game could be resumed and false otherwise
        """
        ret_value = True
        move = input(
            '\nEnter your move, please (w - up, d - right, s - down, a - left), or "save" for save game:\n'
        )

        if move == "save":

            self.save_game()
            ret_value = False

        self.player.make_move(move, *self.dungeon_map.map_size)

        self.player_map.update_map(self.dungeon_map, self.player.player_x,
                                   self.player.player_y)
        self.player_map.draw_map()

        if self.dungeon_map.get_cell_content(self.player.player_x,
                                             self.player.player_y) == 'T':

            self.dungeon_map.set_cell_content(self.player.player_x,
                                              self.player.player_y, '-')
            self.player.add_treasure()

        elif self.dungeon_map.get_cell_content(self.player.player_x,
                                               self.player.player_y) == 'X':

            self.dungeon_map.set_cell_content(self.player.player_x,
                                              self.player.player_y, '-')
            self.player.apply_damage()

        self.player.draw_character()

        if self.player.is_dead():

            my_logger.info("\n}}}This is a trap! You loose!{{{\n")
            ret_value = False

        elif self.player.is_winner():

            my_logger.info("\n>>>This is a treasure! You are victorious!<<<\n")
            ret_value = False

        return ret_value
Exemple #3
0
class Game_session:
    """ a class to keep track of a single game run (active game session) """
    def __init__(self, game):
        """ Initialise game run """
        self.game = game
        self.screen = self.game.screen
        self.settings = self.game.settings

        # create and draw grid
        self.grid = Grid(self)

        # create sprite groups
        self.characters_group = pygame.sprite.Group(
        )  # used for all characters (player and enemies)
        self.hp_counters_group = pygame.sprite.Group(
        )  # used for all HP counter (player and enemies)
        self.enemies_group = pygame.sprite.Group(
        )  # used for enemy characters only

        # create player
        self.player = Player(self, self.grid.tiles_dict["player_tile"][0])
        self.characters_group.add(self.player)

    # EVENT HANDLING
    def check_events(self):
        """Checks for and responds to mouse and kb events"""
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                self.game.quit_game()
            elif event.type == pygame.KEYDOWN:  # key down events
                if event.key == self.settings.key_quit:  # quit game TODO remove or change quit key
                    self.game.quit_game()
            elif event.type == pygame.KEYUP:  # key up events
                if event.key == self.settings.key_keep_wp:  # if player kept weapon
                    self.keep_wp()
                elif event.key == self.settings.key_change_wp:  # if player changed weapon
                    self.change_wp()

    def keep_wp(self):
        """ player keeps current weapon, and fights with adjacent enemies """
        self.settings.sfx_kp_wp.play()  # keep_weapon sound
        sleep(self.settings.sfx_kp_wp.get_length())  # small wait

        if self.player.get_adj_enemies() != [None, None]:
            # everyone deals damage
            for en in self.player.get_adj_enemies():
                if en:
                    en.apply_damage(self.player)
                    self.player.apply_damage(en)

            self.settings.sfx_fight.play()  # fighting sound
            sleep(self.settings.sfx_fight.get_length())

        self.update_screen()

    def change_wp(self):
        """ player swaps to next weapon, receives damage according to new weapon but deals none """
        self.player.change_weapon()
        self.player.update()
        self.settings.sfx_ch_wp.play()  # change_weapon sound
        sleep(self.settings.sfx_ch_wp.get_length())  # small wait

        if self.player.get_adj_enemies() != [None, None]:
            # enemies deal damage (player does not)
            for en in self.player.get_adj_enemies():
                if en:
                    en.apply_damage(self.player)
            self.settings.sfx_fight.play()  # fighting sound
            sleep(self.settings.sfx_fight.get_length())

        self.update_screen()

    # TURN CHANGE ACTIONS

    def update_screen(self):
        """ updates the screens with all turn changes before it can be refreshed"""
        # updates existing characters
        self.characters_group.update()
        # spawns new enemies if possible
        self._spawn_enemies()

    def _spawn_enemies(self):
        """ has chance to spawn enemies on outermost tiles, if they are free """
        outer_tiles = [
            self.grid.tiles_dict["left_tiles"][-1],
            self.grid.tiles_dict["right_tiles"][-1]
        ]
        for tile in outer_tiles:
            if not tile.get_character():
                if random() < self.settings.enemy_spawn_prob:
                    new_enemy = Enemy(self, tile)
                    self.enemies_group.add(new_enemy)
                    self.characters_group.add(new_enemy)

    # DRAWING

    def draw_screen(self):
        """ draws the current game situation to the screen """
        self.screen.fill(self.settings.bg_color)
        self.grid.blit_tiles()
        self.characters_group.draw(self.screen)
        self.hp_counters_group.draw(self.screen)