Пример #1
0
    def __init__(self, model, view):
        self.model = model
        self.view = view

        # Add Background layer to visible models
        self.view.add_model(None, InventoryView.render_background,
                            Position(0, 0), View.BACKGROUND)

        # Add Character to visible models
        self.view.add_model(self.model.character,
                            InventoryView.render_character_data,
                            Position(Map.MAP_SIZE / 4, 0), View.FOREGROUND)

        # Add item description - using blank item for initialization
        self.description_item = Item(0, 0, "", 0)
        self.view.add_model(self.description_item,
                            InventoryView.render_description, Position(0, 0),
                            View.FOREGROUND)
        # Build item list from model into a menu
        self.inventory_menu = Menu(self.view,
                                   InventoryView.render_inventory_menu,
                                   self.on_node_activated, Position(0, 0))

        for item in self.model.character.inventory.item_list:
            self.inventory_menu.nodes.append(
                LeafNode(item.name, self.select_item, item))
Пример #2
0
    def on_node_activated(self, node):

        if node.is_leaf_node():
            result = node.execute_action()

        # Add save game nodes to menu it consists of allowing the user to overwrite any
        # existing save or add a new one.
        if node.id == self.save_game_node_id:

            game_menu = Menu(
                self.view, MainMenu.render_menu, self.on_node_activated,
                Position(Map.MAP_SIZE / 2 - MainMenu.MENU_WIDTH / 2,
                         Map.MAP_SIZE / 2 - MainMenu.MENU_HEIGHT / 2))

            self.save_node_ids = utils.add_saved_game_nodes(
                game_menu,
                Database().save_game_overwrite,
                self.game_model.create_memento())

            new_node = LeafNode("New Saved Game",
                                Database().save_game,
                                self.game_model.create_memento())

            game_menu.nodes.append(new_node)
            self.save_node_ids.append(new_node.id)
            node.submenu = game_menu

        # Add load game nodes to menu it allows a user to load any existing save.
        if node.id == self.load_game_node_id:
            game_menu = Menu(
                self.view, MainMenu.render_menu, self.on_node_activated,
                Position(Map.MAP_SIZE / 2 - MainMenu.MENU_WIDTH / 2,
                         Map.MAP_SIZE / 2 - MainMenu.MENU_HEIGHT / 2))

            self.load_node_ids = utils.add_saved_game_nodes(
                game_menu,
                Database().load_saved_game, None)

            node.submenu = game_menu

        # If user has selected a save node
        if node.id in self.save_node_ids:
            utils.return_to_game(self.game_model)

        # If user has selected a load node
        if node.id in self.load_node_ids:
            self.game_model.set_memento(result)
            utils.return_to_game(self.game_model)
    def __init__(self, model, view):
        self.model = model
        self.view = view

        # Add Background layer to visible models
        self.view.add_model(
            None, InventoryView.render_background,
            Position(0, 0), View.BACKGROUND)

        # Add Character to visible models
        self.view.add_model(
            self.model.character, InventoryView.render_character_data,
            Position(Map.MAP_SIZE/4, 0), View.FOREGROUND)

        # Add item description - using blank item for initialization
        self.description_item = Item(0, 0, "", 0)
        self.view.add_model(
            self.description_item, InventoryView.render_description,
            Position(0, 0), View.FOREGROUND)
        # Build item list from model into a menu
        self.inventory_menu = Menu(self.view, InventoryView.render_inventory_menu,
                                   self.on_node_activated, Position(0, 0))

        for item in self.model.character.inventory.item_list:
            self.inventory_menu.nodes.append(
                LeafNode(item.name, self.select_item, item))
Пример #4
0
    def __init__(self, model, view, enemy_name):
        self.model = model
        self.view = view
        self.state = BattleController.ACTION_SELECT
        self.current_action = None
        self.enemy = copy.copy(model.enemies[enemy_name])

        # Add Character model
        self.view.add_model(self.model.character, BattleView.render_character,
                            Position(Map.GRID_SIZE / 2, Map.GRID_SIZE / 2),
                            View.FOREGROUND)

        # Add Map Model
        self.view.add_model(
            self.model.current_map.get_map_tile(
                self.model.character.position.x_coord,
                self.model.character.position.y_coord, 0),
            BattleView.render_map,
            Position(0,
                     Map.MAP_SIZE - BattleView.MENU_HEIGHT), View.BACKGROUND)

        # Add Enemy
        self.view.add_model(self.enemy, BattleView.render_enemy,
                            Position(Map.GRID_SIZE / 2, 2), View.FOREGROUND)

        # Add target window Model and set current target to player
        characters = {'Player': self.model.character, 'Enemy': self.enemy}
        self.target_window = TargetWindow(self.model.character, self.state,
                                          characters)
        self.view.add_model(self.target_window,
                            BattleView.render_target_window,
                            Position(Map.GRID_SIZE / 2,
                                     Map.GRID_SIZE / 2), View.FOREGROUND)

        # Add action select menu to visible models
        self.action_menu = Menu(
            self.view, BattleView.render_menu, self.on_node_activated,
            Position(0, Map.MAP_SIZE - BattleView.MENU_HEIGHT))

        self.action_menu.nodes.append(
            LeafNode("Attack", self.set_attack_action))
        self.action_menu.nodes.append(LeafNode("Items", None))

        # Add Battle Log
        self.battle_log = BattleLog("%s Attacked!" % enemy_name)
        self.view.add_model(self.battle_log, BattleView.render_battle_log,
                            Position(0, 0), View.FOREGROUND)
Пример #5
0
    def __init__(self, model, view, previous_controller, previous_view):
        self.game_model = model
        self.view = view
        self.previous_controller = previous_controller
        self.previous_view = previous_view
        self.save_node_ids = []
        self.load_node_ids = []

        self.menu_model = Menu(
            self.view, MainMenu.render_menu, self.on_node_activated,
            Position(Map.MAP_SIZE / 2 - MainMenu.MENU_WIDTH / 2,
                     Map.MAP_SIZE / 2 - MainMenu.MENU_HEIGHT / 2))

        save_game_node = MenuNode("Save Game")
        self.menu_model.nodes.append(save_game_node)
        self.save_game_node_id = save_game_node.id

        load_game_node = MenuNode("Load Saved Game")
        self.menu_model.nodes.append(load_game_node)
        self.load_game_node_id = load_game_node.id

        self.menu_model.nodes.append(LeafNode("Quit", utils.quit))
Пример #6
0
    def __init__(self, model, view):
        self.game_model = model
        self.view = view
        self.save_node_ids = []
        self.load_node_ids = []

        pygame.mixer.music.load(os.path.join('Music', 'theme.mid'))
        pygame.mixer.music.play()

        self.menu_model = Menu(self.view, TitleScreenView.render_menu,
                               self.on_node_activated, Position(0, 0))

        new_game_node = LeafNode("New Game", utils.return_to_game,
                                 self.game_model)
        self.menu_model.nodes.append(new_game_node)
        self.new_game_node_id = new_game_node.id

        load_game_node = MenuNode("Load Saved Game")
        self.menu_model.nodes.append(load_game_node)
        self.load_game_node_id = load_game_node.id

        self.menu_model.nodes.append(LeafNode("Quit", utils.quit))
    def __init__(self, model, view, enemy_name):
        self.model = model
        self.view = view
        self.state = BattleController.ACTION_SELECT
        self.current_action = None
        self.enemy = copy.copy(model.enemies[enemy_name])

        # Add Character model
        self.view.add_model(
            self.model.character, BattleView.render_character,
            Position(Map.GRID_SIZE/2, Map.GRID_SIZE/2), View.FOREGROUND)

        # Add Map Model
        self.view.add_model(
            self.model.current_map.get_map_tile(self.model.character.position.x_coord,
                                                self.model.character.position.y_coord,
                                                0),
            BattleView.render_map, Position(0, Map.MAP_SIZE -
                                            BattleView.MENU_HEIGHT),
            View.BACKGROUND)

        # Add Enemy
        self.view.add_model(
            self.enemy, BattleView.render_enemy, Position(Map.GRID_SIZE/2, 2), View.FOREGROUND)

        # Add target window Model and set current target to player
        characters = {'Player': self.model.character,
                      'Enemy': self.enemy}
        self.target_window = TargetWindow(self.model.character, self.state, characters)
        self.view.add_model(self.target_window, BattleView.render_target_window,
                            Position(Map.GRID_SIZE/2, Map.GRID_SIZE/2), View.FOREGROUND)

        # Add action select menu to visible models
        self.action_menu = Menu(
            self.view, BattleView.render_menu,self.on_node_activated,
            Position(0, Map.MAP_SIZE - BattleView.MENU_HEIGHT))

        self.action_menu.nodes.append(LeafNode("Attack", self.set_attack_action))
        self.action_menu.nodes.append(LeafNode("Items", None))

        # Add Battle Log
        self.battle_log = BattleLog("%s Attacked!" % enemy_name)
        self.view.add_model(self.battle_log, BattleView.render_battle_log,
                            Position(0, 0), View.FOREGROUND)
Пример #8
0
    def __init__(self, model, view, previous_controller, previous_view):
        self.game_model = model
        self.view = view
        self.previous_controller = previous_controller
        self.previous_view = previous_view
        self.save_node_ids = []
        self.load_node_ids = []

        self.menu_model = Menu(
            self.view, MainMenu.render_menu,self.on_node_activated,
            Position(Map.MAP_SIZE/2 - MainMenu.MENU_WIDTH /2, Map.MAP_SIZE/2 -
                     MainMenu.MENU_HEIGHT /2))

        save_game_node = MenuNode("Save Game")
        self.menu_model.nodes.append(save_game_node)
        self.save_game_node_id = save_game_node.id

        load_game_node = MenuNode("Load Saved Game")
        self.menu_model.nodes.append(load_game_node)
        self.load_game_node_id = load_game_node.id

        self.menu_model.nodes.append(LeafNode("Quit", utils.quit))
    def __init__(self, model, view):
        self.game_model = model
        self.view = view
        self.save_node_ids = []
        self.load_node_ids = []

        pygame.mixer.music.load(os.path.join('Music','theme.mid'))
        pygame.mixer.music.play()

        self.menu_model = Menu(self.view, TitleScreenView.render_menu,
                               self.on_node_activated, Position(0,0))

        new_game_node = LeafNode(
            "New Game", utils.return_to_game, self.game_model)
        self.menu_model.nodes.append(new_game_node)
        self.new_game_node_id = new_game_node.id

        load_game_node = MenuNode("Load Saved Game")
        self.menu_model.nodes.append(load_game_node)
        self.load_game_node_id = load_game_node.id

        self.menu_model.nodes.append(
            LeafNode("Quit", utils.quit))
Пример #10
0
    def on_node_activated(self, node):

        if node.is_leaf_node():
            result = node.execute_action()

        # Add load game nodes to menu it allows a user to load any existing save.
        if node.id == self.load_game_node_id:
            game_menu = Menu(self.view, TitleScreenView.render_menu,
                             self.on_node_activated, Position(0, 0))

            self.load_node_ids = utils.add_saved_game_nodes(
                game_menu,
                Database().load_saved_game, None)

            node.submenu = game_menu

        # If user has selected new game
        if node.id == self.new_game_node_id:
            utils.return_to_game(self.game_model)

        # If user has selected a load node
        if node.id in self.load_node_ids:
            self.game_model.set_memento(result)
            utils.return_to_game(self.game_model)
Пример #11
0
class TitleScreenController(Controller):
    def __init__(self, model, view):
        self.game_model = model
        self.view = view
        self.save_node_ids = []
        self.load_node_ids = []

        pygame.mixer.music.load(os.path.join('Music', 'theme.mid'))
        pygame.mixer.music.play()

        self.menu_model = Menu(self.view, TitleScreenView.render_menu,
                               self.on_node_activated, Position(0, 0))

        new_game_node = LeafNode("New Game", utils.return_to_game,
                                 self.game_model)
        self.menu_model.nodes.append(new_game_node)
        self.new_game_node_id = new_game_node.id

        load_game_node = MenuNode("Load Saved Game")
        self.menu_model.nodes.append(load_game_node)
        self.load_game_node_id = load_game_node.id

        self.menu_model.nodes.append(LeafNode("Quit", utils.quit))

    def on_node_activated(self, node):

        if node.is_leaf_node():
            result = node.execute_action()

        # Add load game nodes to menu it allows a user to load any existing save.
        if node.id == self.load_game_node_id:
            game_menu = Menu(self.view, TitleScreenView.render_menu,
                             self.on_node_activated, Position(0, 0))

            self.load_node_ids = utils.add_saved_game_nodes(
                game_menu,
                Database().load_saved_game, None)

            node.submenu = game_menu

        # If user has selected new game
        if node.id == self.new_game_node_id:
            utils.return_to_game(self.game_model)

        # If user has selected a load node
        if node.id in self.load_node_ids:
            self.game_model.set_memento(result)
            utils.return_to_game(self.game_model)

    @staticmethod
    def get_imports():
        models = ["menu", "node_menu", "node_leaf"]
        views = ["main_menu"]
        controllers = ["menu_controller"]

        return Controller.qualify_imports((models, views, controllers))

    def handle_key_press(self, pressed_key):

        if pressed_key == pygame.K_LEFT:
            if len(Menu.breadcrumbs) > 0:
                self.menu_model = self.menu_model.go_to_previous_menu()

        if pressed_key == pygame.K_RIGHT or pressed_key == pygame.K_RETURN:
            self.menu_model = self.menu_model.activate_node()

        if pressed_key == pygame.K_UP:
            self.menu_model.dec_active_node()

        if pressed_key == pygame.K_DOWN:
            self.menu_model.inc_active_node()

        if pressed_key == pygame.K_ESCAPE:
            utils.return_to_game(self.game_model)

    def handle_game_event(self, event):
        if event.type == pygame.QUIT:
            pygame.quit()
            sys.exit()
class TitleScreenController(Controller):

    def __init__(self, model, view):
        self.game_model = model
        self.view = view
        self.save_node_ids = []
        self.load_node_ids = []

        pygame.mixer.music.load(os.path.join('Music','theme.mid'))
        pygame.mixer.music.play()

        self.menu_model = Menu(self.view, TitleScreenView.render_menu,
                               self.on_node_activated, Position(0,0))

        new_game_node = LeafNode(
            "New Game", utils.return_to_game, self.game_model)
        self.menu_model.nodes.append(new_game_node)
        self.new_game_node_id = new_game_node.id

        load_game_node = MenuNode("Load Saved Game")
        self.menu_model.nodes.append(load_game_node)
        self.load_game_node_id = load_game_node.id

        self.menu_model.nodes.append(
            LeafNode("Quit", utils.quit))

    def on_node_activated(self, node):

        if node.is_leaf_node():
            result = node.execute_action()

        # Add load game nodes to menu it allows a user to load any existing save.
        if node.id == self.load_game_node_id:
            game_menu = Menu(self.view, TitleScreenView.render_menu,
                             self.on_node_activated, Position(0, 0))

            self.load_node_ids = utils.add_saved_game_nodes(
                game_menu, Database().load_saved_game, None)

            node.submenu = game_menu

        # If user has selected new game
        if node.id == self.new_game_node_id:
            utils.return_to_game(self.game_model)

        # If user has selected a load node
        if node.id in self.load_node_ids:
            self.game_model.set_memento(result)
            utils.return_to_game(self.game_model)

    @staticmethod
    def get_imports():
        models = ["menu", "node_menu", "node_leaf"]
        views = ["main_menu"]
        controllers = ["menu_controller"]
        
        return Controller.qualify_imports((models, views, controllers))

    def handle_key_press(self, pressed_key):

        if pressed_key == pygame.K_LEFT:
            if len(Menu.breadcrumbs) > 0:
                self.menu_model = self.menu_model.go_to_previous_menu()

        if pressed_key == pygame.K_RIGHT or pressed_key == pygame.K_RETURN:
            self.menu_model = self.menu_model.activate_node()

        if pressed_key == pygame.K_UP:
            self.menu_model.dec_active_node()

        if pressed_key == pygame.K_DOWN:
            self.menu_model.inc_active_node()

        if pressed_key == pygame.K_ESCAPE:
            utils.return_to_game(self.game_model)

    def handle_game_event(self, event):
        if event.type == pygame.QUIT:
            pygame.quit()
            sys.exit()
Пример #13
0
class BattleController(Controller):

    ACTION_SELECT = 0
    TARGET_SELECT = 1
    ENEMY_TURN = 2

    def __init__(self, model, view, enemy_name):
        self.model = model
        self.view = view
        self.state = BattleController.ACTION_SELECT
        self.current_action = None
        self.enemy = copy.copy(model.enemies[enemy_name])

        # Add Character model
        self.view.add_model(self.model.character, BattleView.render_character,
                            Position(Map.GRID_SIZE / 2, Map.GRID_SIZE / 2),
                            View.FOREGROUND)

        # Add Map Model
        self.view.add_model(
            self.model.current_map.get_map_tile(
                self.model.character.position.x_coord,
                self.model.character.position.y_coord, 0),
            BattleView.render_map,
            Position(0,
                     Map.MAP_SIZE - BattleView.MENU_HEIGHT), View.BACKGROUND)

        # Add Enemy
        self.view.add_model(self.enemy, BattleView.render_enemy,
                            Position(Map.GRID_SIZE / 2, 2), View.FOREGROUND)

        # Add target window Model and set current target to player
        characters = {'Player': self.model.character, 'Enemy': self.enemy}
        self.target_window = TargetWindow(self.model.character, self.state,
                                          characters)
        self.view.add_model(self.target_window,
                            BattleView.render_target_window,
                            Position(Map.GRID_SIZE / 2,
                                     Map.GRID_SIZE / 2), View.FOREGROUND)

        # Add action select menu to visible models
        self.action_menu = Menu(
            self.view, BattleView.render_menu, self.on_node_activated,
            Position(0, Map.MAP_SIZE - BattleView.MENU_HEIGHT))

        self.action_menu.nodes.append(
            LeafNode("Attack", self.set_attack_action))
        self.action_menu.nodes.append(LeafNode("Items", None))

        # Add Battle Log
        self.battle_log = BattleLog("%s Attacked!" % enemy_name)
        self.view.add_model(self.battle_log, BattleView.render_battle_log,
                            Position(0, 0), View.FOREGROUND)

    def on_node_activated(self, node):
        if node.is_leaf_node():
            node.execute_action()

    @staticmethod
    def get_imports():
        models = ["map", "trigger"]
        views = ["battle_view"]
        controllers = ["battle_controller"]

        return Controller.qualify_imports((models, views, controllers))

    def handle_key_press(self, pressed_key):
        if self.state is BattleController.TARGET_SELECT:
            if self.target_window.current_target.name == 'Player':
                self.handle_player_start_point(pressed_key)
            else:
                self.handle_enemy_start_point(pressed_key)

            if pressed_key == K_RETURN:
                self.execute_action(self.current_action)
                self.current_action = None

        elif self.state is BattleController.ACTION_SELECT:
            if pressed_key == pygame.K_UP or pressed_key == pygame.K_w:
                self.action_menu.dec_active_node()
            if pressed_key == pygame.K_DOWN or pressed_key == pygame.K_s:
                self.action_menu.inc_active_node()
            if pressed_key == K_RETURN:
                self.action_menu = self.action_menu.activate_node()

        if pressed_key == pygame.K_b:
            self.end_battle()

    def handle_player_start_point(self, pressed_key):
        if pressed_key == pygame.K_UP or pressed_key == pygame.K_w:
            self.update_target_window(self.enemy, self.state)

    def handle_enemy_start_point(self, pressed_key):
        if pressed_key == pygame.K_DOWN or pressed_key == pygame.K_s:
            self.update_target_window(self.model.character, self.state)

    def update_target_window(self, new_target_model, battle_state):
        # Update target window with new target model and/or battle state
        self.target_window.current_target = new_target_model
        self.target_window.battle_state = battle_state

        # Get new target's position and set it for the target window
        new_target_position = self.view.get_visible_model_position(
            new_target_model)
        self.view.set_visible_model_position(self.target_window,
                                             new_target_position)

    def update_battle_log(self, message):
        self.battle_log.add_battle_log_entry(message)

    def set_attack_action(self):
        self.current_action = AttackAction(self.model.character.attack)
        self.state = BattleController.TARGET_SELECT
        self.update_target_window(self.enemy, self.state)

    def execute_action(self, action):
        action.execute_action(self.target_window, self.battle_log)

        # End battle when someone dies
        if self.target_window.current_target.health <= 0:
            if self.target_window.current_target.name == 'Player':
                self.quit_game()
            else:
                # return to ensure enemy doesn't attack after being killed
                self.end_battle()
                return

        # Change to enemy turn
        self.state = BattleController.ENEMY_TURN

        # Update target window
        self.update_target_window(self.target_window.current_target,
                                  self.state)
        self.execute_enemy_turn()

    def execute_enemy_turn(self):

        if self.model.character.defense >= self.enemy.attack:
            self.update_battle_log("You dodged %s's attack." % self.enemy.name)
        else:
            self.model.character.health -= (self.enemy.attack -
                                            self.model.character.defense)
            self.update_battle_log("%s hit you for %d damage." %
                                   (self.enemy.name, self.enemy.attack -
                                    self.model.character.defense))

        if self.model.character.health <= 0:
            self.quit_game()

        self.state = BattleController.ACTION_SELECT
        self.update_target_window(self.target_window.current_target,
                                  self.state)

    def end_battle(self):
        base = utils.fetch(utils.qualify_controller_name("game_controller"))

        imports = base.GameController.get_imports()

        view_module = utils.fetch(
            imports[base.GameController.VIEWS]["game_view"])

        view = view_module.GameView()

        controller = base.GameController(self.model, view)

        pygame.event.post(
            pygame.event.Event(event_types.UPDATE_GAME_STATE, {
                "Controller": controller,
                "View": view
            }))

    def handle_game_event(self, event):
        if event.type == pygame.QUIT:
            self.quit_game()

    def quit_game(self):
        pygame.quit()
        sys.exit()
Пример #14
0
class InventoryController(Controller):
    def __init__(self, model, view):
        self.model = model
        self.view = view

        # Add Background layer to visible models
        self.view.add_model(None, InventoryView.render_background,
                            Position(0, 0), View.BACKGROUND)

        # Add Character to visible models
        self.view.add_model(self.model.character,
                            InventoryView.render_character_data,
                            Position(Map.MAP_SIZE / 4, 0), View.FOREGROUND)

        # Add item description - using blank item for initialization
        self.description_item = Item(0, 0, "", 0)
        self.view.add_model(self.description_item,
                            InventoryView.render_description, Position(0, 0),
                            View.FOREGROUND)
        # Build item list from model into a menu
        self.inventory_menu = Menu(self.view,
                                   InventoryView.render_inventory_menu,
                                   self.on_node_activated, Position(0, 0))

        for item in self.model.character.inventory.item_list:
            self.inventory_menu.nodes.append(
                LeafNode(item.name, self.select_item, item))

    def handle_key_press(self, pressed_key):
        if pressed_key == pygame.K_LEFT:
            if len(Menu.breadcrumbs) > 0:
                self.inventory_menu = self.inventory_menu.go_to_previous_menu()

        if pressed_key == pygame.K_RIGHT or pressed_key == pygame.K_RETURN:
            self.inventory_menu = self.inventory_menu.activate_node()

        if pressed_key == pygame.K_UP:
            self.inventory_menu.dec_active_node()

        if pressed_key == pygame.K_DOWN:
            self.inventory_menu.inc_active_node()

        if pressed_key == pygame.K_i:
            # For now goes back to only game controller, but we need a
            # way to detect previous controller
            self.close_inventory()

    def on_node_activated(self, node):
        if node.is_leaf_node():
            node.execute_action()

    def select_item(self, item):
        self.description_item.description = item.description
        if item.slot == Item.Bag:
            # Show an error that item can't be equipped
            return
        current_loadout = self.model.character.loadout
        if item.slot in current_loadout:
            if item is current_loadout[item.slot]:
                item.unequip(self.model.character)
            else:
                item.equip(self.model.character)
        else:
            item.equip(self.model.character)

    def close_inventory(self):
        base = utils.fetch(utils.qualify_controller_name("game_controller"))

        imports = base.GameController.get_imports()

        view_module = utils.fetch(
            imports[base.GameController.VIEWS]["game_view"])

        view = view_module.GameView()

        controller = base.GameController(self.model, view)

        pygame.event.post(
            pygame.event.Event(event_types.UPDATE_GAME_STATE, {
                "Controller": controller,
                "View": view
            }))

    def handle_game_event(self, event):
        if event.type == pygame.QUIT:
            self.quit_game()

    @staticmethod
    def get_imports():
        models = ["map", "trigger"]
        views = ["inventory_view"]
        controllers = ["inventory_controller"]

        return Controller.qualify_imports((models, views, controllers))

    def quit_game(self):
        pygame.quit()
        sys.exit()
Пример #15
0
class MenuController(Controller):

    def __init__(self, model, view, previous_controller, previous_view):
        self.game_model = model
        self.view = view
        self.previous_controller = previous_controller
        self.previous_view = previous_view
        self.save_node_ids = []
        self.load_node_ids = []

        self.menu_model = Menu(
            self.view, MainMenu.render_menu,self.on_node_activated,
            Position(Map.MAP_SIZE/2 - MainMenu.MENU_WIDTH /2, Map.MAP_SIZE/2 -
                     MainMenu.MENU_HEIGHT /2))

        save_game_node = MenuNode("Save Game")
        self.menu_model.nodes.append(save_game_node)
        self.save_game_node_id = save_game_node.id

        load_game_node = MenuNode("Load Saved Game")
        self.menu_model.nodes.append(load_game_node)
        self.load_game_node_id = load_game_node.id

        self.menu_model.nodes.append(LeafNode("Quit", utils.quit))

    def on_node_activated(self, node):

        if node.is_leaf_node():
            result = node.execute_action()

        # Add save game nodes to menu it consists of allowing the user to overwrite any
        # existing save or add a new one.
        if node.id == self.save_game_node_id:

            game_menu = Menu(self.view, MainMenu.render_menu,
                             self.on_node_activated,Position(
                             Map.MAP_SIZE / 2 - MainMenu.MENU_WIDTH / 2,
                             Map.MAP_SIZE / 2 - MainMenu.MENU_HEIGHT / 2))

            self.save_node_ids = utils.add_saved_game_nodes(
                                 game_menu, Database().save_game_overwrite,
                                 self.game_model.create_memento())

            new_node = LeafNode(
                "New Saved Game", Database().save_game,
                 self.game_model.create_memento())

            game_menu.nodes.append(new_node)
            self.save_node_ids.append(new_node.id)
            node.submenu = game_menu

        # Add load game nodes to menu it allows a user to load any existing save.
        if node.id == self.load_game_node_id:
            game_menu = Menu(self.view, MainMenu.render_menu,
                             self.on_node_activated,Position(
                             Map.MAP_SIZE / 2 - MainMenu.MENU_WIDTH / 2,
                             Map.MAP_SIZE / 2 - MainMenu.MENU_HEIGHT / 2))

            self.load_node_ids = utils.add_saved_game_nodes(
                                game_menu, Database().load_saved_game, None)

            node.submenu = game_menu

        # If user has selected a save node
        if node.id in self.save_node_ids:
            utils.return_to_game(self.game_model)

        # If user has selected a load node
        if node.id in self.load_node_ids:
            self.game_model.set_memento(result)
            utils.return_to_game(self.game_model)

    @staticmethod
    def get_imports():
        models = ["menu", "node_menu", "node_leaf"]
        views = ["main_menu"]
        controllers = ["menu_controller"]
        
        return Controller.qualify_imports((models, views, controllers))

    def handle_key_press(self, pressed_key):

        if pressed_key == pygame.K_LEFT:
            if len(Menu.breadcrumbs) > 0:
                self.menu_model = self.menu_model.go_to_previous_menu()

        if pressed_key == pygame.K_RIGHT or pressed_key == pygame.K_RETURN:
            self.menu_model = self.menu_model.activate_node()

        if pressed_key == pygame.K_UP:
            self.menu_model.dec_active_node()

        if pressed_key == pygame.K_DOWN:
            self.menu_model.inc_active_node()

        if pressed_key == pygame.K_ESCAPE:
            utils.return_to_game(self.game_model)

    def handle_game_event(self, event):
        if event.type == pygame.QUIT:
            pygame.quit()
            sys.exit()
Пример #16
0
class BattleController(Controller):

    ACTION_SELECT = 0
    TARGET_SELECT = 1
    ENEMY_TURN = 2

    def __init__(self, model, view, enemy_name):
        self.model = model
        self.view = view
        self.state = BattleController.ACTION_SELECT
        self.current_action = None
        self.enemy = copy.copy(model.enemies[enemy_name])

        # Add Character model
        self.view.add_model(
            self.model.character, BattleView.render_character,
            Position(Map.GRID_SIZE/2, Map.GRID_SIZE/2), View.FOREGROUND)

        # Add Map Model
        self.view.add_model(
            self.model.current_map.get_map_tile(self.model.character.position.x_coord,
                                                self.model.character.position.y_coord,
                                                0),
            BattleView.render_map, Position(0, Map.MAP_SIZE -
                                            BattleView.MENU_HEIGHT),
            View.BACKGROUND)

        # Add Enemy
        self.view.add_model(
            self.enemy, BattleView.render_enemy, Position(Map.GRID_SIZE/2, 2), View.FOREGROUND)

        # Add target window Model and set current target to player
        characters = {'Player': self.model.character,
                      'Enemy': self.enemy}
        self.target_window = TargetWindow(self.model.character, self.state, characters)
        self.view.add_model(self.target_window, BattleView.render_target_window,
                            Position(Map.GRID_SIZE/2, Map.GRID_SIZE/2), View.FOREGROUND)

        # Add action select menu to visible models
        self.action_menu = Menu(
            self.view, BattleView.render_menu,self.on_node_activated,
            Position(0, Map.MAP_SIZE - BattleView.MENU_HEIGHT))

        self.action_menu.nodes.append(LeafNode("Attack", self.set_attack_action))
        self.action_menu.nodes.append(LeafNode("Items", None))

        # Add Battle Log
        self.battle_log = BattleLog("%s Attacked!" % enemy_name)
        self.view.add_model(self.battle_log, BattleView.render_battle_log,
                            Position(0, 0), View.FOREGROUND)

    def on_node_activated(self, node):
        if node.is_leaf_node():
            node.execute_action()

    @staticmethod
    def get_imports():
        models = ["map", "trigger"]
        views = ["battle_view"]
        controllers = ["battle_controller"]

        return Controller.qualify_imports((models, views, controllers))

    def handle_key_press(self, pressed_key):
        if self.state is BattleController.TARGET_SELECT:
            if self.target_window.current_target.name == 'Player':
                self.handle_player_start_point(pressed_key)
            else:
                self.handle_enemy_start_point(pressed_key)

            if pressed_key == K_RETURN:
                self.execute_action(self.current_action)
                self.current_action = None

        elif self.state is BattleController.ACTION_SELECT:
            if pressed_key == pygame.K_UP or pressed_key == pygame.K_w:
                self.action_menu.dec_active_node()
            if pressed_key == pygame.K_DOWN or pressed_key == pygame.K_s:
                self.action_menu.inc_active_node()
            if pressed_key == K_RETURN:
                self.action_menu = self.action_menu.activate_node()

        if pressed_key == pygame.K_b:
            self.end_battle()

    def handle_player_start_point(self, pressed_key):
        if pressed_key == pygame.K_UP or pressed_key == pygame.K_w:
            self.update_target_window(self.enemy, self.state)

    def handle_enemy_start_point(self, pressed_key):
        if pressed_key == pygame.K_DOWN or pressed_key == pygame.K_s:
            self.update_target_window(self.model.character, self.state)

    def update_target_window(self, new_target_model, battle_state):
        # Update target window with new target model and/or battle state
        self.target_window.current_target = new_target_model
        self.target_window.battle_state = battle_state

        # Get new target's position and set it for the target window
        new_target_position = self.view.get_visible_model_position(new_target_model)
        self.view.set_visible_model_position(self.target_window, new_target_position)

    def update_battle_log(self, message):
        self.battle_log.add_battle_log_entry(message)

    def set_attack_action(self):
        self.current_action = AttackAction(self.model.character.attack)
        self.state = BattleController.TARGET_SELECT
        self.update_target_window(self.enemy, self.state)

    def execute_action(self, action):
        action.execute_action(self.target_window, self.battle_log)

        # End battle when someone dies
        if self.target_window.current_target.health <= 0:
            if self.target_window.current_target.name == 'Player':
                self.quit_game()
            else:
                # return to ensure enemy doesn't attack after being killed
                self.end_battle()
                return

        # Change to enemy turn
        self.state = BattleController.ENEMY_TURN

        # Update target window
        self.update_target_window(self.target_window.current_target, self.state)
        self.execute_enemy_turn()

    def execute_enemy_turn(self):

        if self.model.character.defense >= self.enemy.attack:
            self.update_battle_log("You dodged %s's attack." % self.enemy.name)
        else:
            self.model.character.health -= (self.enemy.attack - self.model.character.defense)
            self.update_battle_log("%s hit you for %d damage." %
                                   (self.enemy.name,
                                    self.enemy.attack - self.model.character.defense))

        if self.model.character.health <= 0:
            self.quit_game()

        self.state = BattleController.ACTION_SELECT
        self.update_target_window(self.target_window.current_target, self.state)

    def end_battle(self):
        base = utils.fetch(utils.qualify_controller_name("game_controller"))

        imports = base.GameController.get_imports()

        view_module = utils.fetch(imports[base.GameController.VIEWS]["game_view"])

        view = view_module.GameView()

        controller = base.GameController(self.model, view)

        pygame.event.post(pygame.event.Event(
            event_types.UPDATE_GAME_STATE,
            {"Controller": controller, "View": view}))

    def handle_game_event(self, event):
        if event.type == pygame.QUIT:
            self.quit_game()

    def quit_game(self):
        pygame.quit()
        sys.exit()
class InventoryController(Controller):

    def __init__(self, model, view):
        self.model = model
        self.view = view

        # Add Background layer to visible models
        self.view.add_model(
            None, InventoryView.render_background,
            Position(0, 0), View.BACKGROUND)

        # Add Character to visible models
        self.view.add_model(
            self.model.character, InventoryView.render_character_data,
            Position(Map.MAP_SIZE/4, 0), View.FOREGROUND)

        # Add item description - using blank item for initialization
        self.description_item = Item(0, 0, "", 0)
        self.view.add_model(
            self.description_item, InventoryView.render_description,
            Position(0, 0), View.FOREGROUND)
        # Build item list from model into a menu
        self.inventory_menu = Menu(self.view, InventoryView.render_inventory_menu,
                                   self.on_node_activated, Position(0, 0))

        for item in self.model.character.inventory.item_list:
            self.inventory_menu.nodes.append(
                LeafNode(item.name, self.select_item, item))

    def handle_key_press(self, pressed_key):
        if pressed_key == pygame.K_LEFT:
            if len(Menu.breadcrumbs) > 0:
                self.inventory_menu = self.inventory_menu.go_to_previous_menu()

        if pressed_key == pygame.K_RIGHT or pressed_key == pygame.K_RETURN:
            self.inventory_menu = self.inventory_menu.activate_node()

        if pressed_key == pygame.K_UP:
            self.inventory_menu.dec_active_node()

        if pressed_key == pygame.K_DOWN:
            self.inventory_menu.inc_active_node()

        if pressed_key == pygame.K_i:
            # For now goes back to only game controller, but we need a
            # way to detect previous controller
            self.close_inventory()

    def on_node_activated(self, node):
        if node.is_leaf_node():
            node.execute_action()

    def select_item(self, item):
        self.description_item.description = item.description
        if item.slot == Item.Bag:
            # Show an error that item can't be equipped
            return
        current_loadout = self.model.character.loadout
        if item.slot in current_loadout:
            if item is current_loadout[item.slot]:
                item.unequip(self.model.character)
            else:
                item.equip(self.model.character)
        else:
            item.equip(self.model.character)

    def close_inventory(self):
        base = utils.fetch(utils.qualify_controller_name("game_controller"))

        imports = base.GameController.get_imports()

        view_module = utils.fetch(imports[base.GameController.VIEWS]["game_view"])

        view = view_module.GameView()

        controller = base.GameController(self.model, view)

        pygame.event.post(pygame.event.Event(
            event_types.UPDATE_GAME_STATE,
            {"Controller": controller, "View": view}))

    def handle_game_event(self, event):
        if event.type == pygame.QUIT:
            self.quit_game()

    @staticmethod
    def get_imports():
        models = ["map", "trigger"]
        views = ["inventory_view"]
        controllers = ["inventory_controller"]

        return Controller.qualify_imports((models, views, controllers))

    def quit_game(self):
        pygame.quit()
        sys.exit()
Пример #18
0
class MenuController(Controller):
    def __init__(self, model, view, previous_controller, previous_view):
        self.game_model = model
        self.view = view
        self.previous_controller = previous_controller
        self.previous_view = previous_view
        self.save_node_ids = []
        self.load_node_ids = []

        self.menu_model = Menu(
            self.view, MainMenu.render_menu, self.on_node_activated,
            Position(Map.MAP_SIZE / 2 - MainMenu.MENU_WIDTH / 2,
                     Map.MAP_SIZE / 2 - MainMenu.MENU_HEIGHT / 2))

        save_game_node = MenuNode("Save Game")
        self.menu_model.nodes.append(save_game_node)
        self.save_game_node_id = save_game_node.id

        load_game_node = MenuNode("Load Saved Game")
        self.menu_model.nodes.append(load_game_node)
        self.load_game_node_id = load_game_node.id

        self.menu_model.nodes.append(LeafNode("Quit", utils.quit))

    def on_node_activated(self, node):

        if node.is_leaf_node():
            result = node.execute_action()

        # Add save game nodes to menu it consists of allowing the user to overwrite any
        # existing save or add a new one.
        if node.id == self.save_game_node_id:

            game_menu = Menu(
                self.view, MainMenu.render_menu, self.on_node_activated,
                Position(Map.MAP_SIZE / 2 - MainMenu.MENU_WIDTH / 2,
                         Map.MAP_SIZE / 2 - MainMenu.MENU_HEIGHT / 2))

            self.save_node_ids = utils.add_saved_game_nodes(
                game_menu,
                Database().save_game_overwrite,
                self.game_model.create_memento())

            new_node = LeafNode("New Saved Game",
                                Database().save_game,
                                self.game_model.create_memento())

            game_menu.nodes.append(new_node)
            self.save_node_ids.append(new_node.id)
            node.submenu = game_menu

        # Add load game nodes to menu it allows a user to load any existing save.
        if node.id == self.load_game_node_id:
            game_menu = Menu(
                self.view, MainMenu.render_menu, self.on_node_activated,
                Position(Map.MAP_SIZE / 2 - MainMenu.MENU_WIDTH / 2,
                         Map.MAP_SIZE / 2 - MainMenu.MENU_HEIGHT / 2))

            self.load_node_ids = utils.add_saved_game_nodes(
                game_menu,
                Database().load_saved_game, None)

            node.submenu = game_menu

        # If user has selected a save node
        if node.id in self.save_node_ids:
            utils.return_to_game(self.game_model)

        # If user has selected a load node
        if node.id in self.load_node_ids:
            self.game_model.set_memento(result)
            utils.return_to_game(self.game_model)

    @staticmethod
    def get_imports():
        models = ["menu", "node_menu", "node_leaf"]
        views = ["main_menu"]
        controllers = ["menu_controller"]

        return Controller.qualify_imports((models, views, controllers))

    def handle_key_press(self, pressed_key):

        if pressed_key == pygame.K_LEFT:
            if len(Menu.breadcrumbs) > 0:
                self.menu_model = self.menu_model.go_to_previous_menu()

        if pressed_key == pygame.K_RIGHT or pressed_key == pygame.K_RETURN:
            self.menu_model = self.menu_model.activate_node()

        if pressed_key == pygame.K_UP:
            self.menu_model.dec_active_node()

        if pressed_key == pygame.K_DOWN:
            self.menu_model.inc_active_node()

        if pressed_key == pygame.K_ESCAPE:
            utils.return_to_game(self.game_model)

    def handle_game_event(self, event):
        if event.type == pygame.QUIT:
            pygame.quit()
            sys.exit()