Exemplo n.º 1
0
class GameBotView(arcade.View):
    def __init__(self):
        super().__init__()
        arcade.set_background_color(arcade.color.AMAZON)
        self.game = GameProcess(2, self)
        self.deck = self.game.deck

        self.ui_manager = UIManager()

        self.held_cards = None

        self.held_cards_original_position = None

        self.pile_mat_list = None

    def setup(self):
        self.card_list = self.deck.card_list

        for card in self.card_list:
            card.position = START_X, MIDDLE_Y

        self.card_list[0].position = START_X + 20, MIDDLE_Y
        self.card_list[0].angle = 90
        self.card_list[0].face_up()

        self.finish_turn_button = FinishAtackButton(START_X, BOTTOM_Y, self)
        self.take_button = FinishDefendButton(START_X, BOTTOM_Y, self)
        self.next_button = NextPlayerButton(START_X, BOTTOM_Y, self)

        self.card_counter = arcade.text

        self.current_player_hand = self.game.CurrentPlayer.hand
        self.opponent_player_hand = self.game.OpponentPlayer.hand

        self.redraw_hand()
        self.redraw_opp_hand()

        self.held_cards = []

        self.held_cards_original_position = []

        self.pile_mat_list: arcade.SpriteList = arcade.SpriteList()

        for i in range(PILE_COUNT):
            self.pile_mat_list.append(
                arcade.SpriteSolidColor(MAT_WIDTH, MAT_HEIGHT,
                                        arcade.csscolor.DARK_OLIVE_GREEN))
        self.pile_mat_list[TOP_ROW_PILE_1].position = (
            MIDDLE_X - MAT_WIDTH / 2) - X_SPACING, MIDDLE_Y
        self.pile_mat_list[TOP_ROW_PILE_2].position = (MIDDLE_X -
                                                       MAT_WIDTH / 2), MIDDLE_Y
        self.pile_mat_list[TOP_ROW_PILE_3].position = (
            MIDDLE_X - MAT_WIDTH / 2) + X_SPACING, MIDDLE_Y
        self.pile_mat_list[TOP_ROW_PILE_4].position = (
            MIDDLE_X - MAT_WIDTH / 2) + (2 * X_SPACING), MIDDLE_Y
        self.pile_mat_list[BOTTOM_ROW_PILE_1].position = (
            MIDDLE_X - MAT_WIDTH / 2) - X_SPACING, MIDDLE_Y - MAT_HEIGHT
        self.pile_mat_list[BOTTOM_ROW_PILE_2].position = (
            MIDDLE_X - MAT_WIDTH / 2), MIDDLE_Y - MAT_HEIGHT
        self.pile_mat_list[BOTTOM_ROW_PILE_3].position = (
            MIDDLE_X - MAT_WIDTH / 2) + X_SPACING, MIDDLE_Y - MAT_HEIGHT
        self.pile_mat_list[BOTTOM_ROW_PILE_4].position = (
            MIDDLE_X - MAT_WIDTH / 2) + (2 * X_SPACING), MIDDLE_Y - MAT_HEIGHT

        self.piles = []
        for i in range(PILE_COUNT):
            self.piles.append(arcade.SpriteList())

    def on_draw(self):
        arcade.start_render()
        if self.game.winner is None:
            self.pile_mat_list.draw()
            for pile in self.piles:
                pile.draw()
            self.ui_manager.on_draw()
            self.card_list.draw()
            self.card_counter.render_text(
                arcade.CreateText(str(self.deck.Count()), (0, 0, 0), 20, 50),
                START_X - 15, MIDDLE_Y - MAT_HEIGHT / 1.5)
            self.current_player_hand.draw()
            self.opponent_player_hand.draw()
        else:
            self.window.show_view(GameOverView(self))

    def redraw_hand(self):
        count = len(self.current_player_hand)
        new_middle_x = MIDDLE_X - CARD_HORIZONTAL_OFFSET * (count) / 2
        i = 0
        for card in self.current_player_hand:
            card.position = new_middle_x + i, BOTTOM_Y
            i += CARD_HORIZONTAL_OFFSET
            card.face_up()

    def redraw_opp_hand(self):
        count = len(self.opponent_player_hand)
        new_middle_x = MIDDLE_X - CARD_HORIZONTAL_OFFSET * (count) / 2
        i = 0
        for card in self.opponent_player_hand:
            card.position = new_middle_x + i, SCREEN_HEIGHT - BOTTOM_Y
            i += CARD_HORIZONTAL_OFFSET
            card.face_down()

    def show_top(self, card):
        self.index = self.current_player_hand.index(card)
        for i in range(self.index, len(self.current_player_hand) - 1):
            self.current_player_hand[i] = self.current_player_hand[i + 1]
        self.current_player_hand[len(self.current_player_hand) - 1] = card

    def return_down(self, card):
        for i in range(len(self.current_player_hand) - 1, self.index, -1):
            self.current_player_hand[i] = self.current_player_hand[i - 1]
        self.current_player_hand[self.index] = card

    def finish_round(self):
        result = self.game.FinishTurn()
        self.redraw_hand()
        self.redraw_opp_hand()
        self.piles = []
        for i in range(PILE_COUNT):
            self.piles.append(arcade.SpriteList())
        if result == self.game.NORMAL:
            self.game.roundStep = ATACK_ROUND
            self.redraw_hand()
            self.redraw_opp_hand()
            if self.game.botTurn == True:
                self.game.BotAtack()
        elif result == self.game.TOOK_CARDS:
            self.game.roundStep = ATACK_ROUND
            self.redraw_hand()
            self.redraw_opp_hand()
            if self.game.botTurn == True:
                self.game.BotAtack()
        elif result == self.game.TIE:
            endgame_label = arcade.gui.UILabel(
                'Ничья!',
                center_x=MIDDLE_X,
                center_y=MIDDLE_Y,
            )
            self.ui_manager.add_ui_element(endgame_label)
        elif result == self.game.GAME_OVER:
            self.window.show_view(GameOverView(self))

    def swap_player_draw(self):
        if self.game.roundStep == ATACK_ROUND:
            self.game.roundStep = DEFEND_ROUND
            self.ui_manager.purge_ui_elements()
            if self.game.botTurn:
                self.game.BotDefend()
            else:
                self.game.takeAllButton = True
        else:
            self.game.roundStep = ATACK_ROUND
            self.game.takeAllButton = False
            self.game.nextPlayerButton = False
            self.ui_manager.purge_ui_elements()
            if self.game.botTurn:
                self.game.BotAtack()
            else:
                self.game.turnDownButton = True
        self.redraw_hand()
        self.redraw_opp_hand()

    def on_mouse_press(self, x, y, button, key_modifiers):
        if self.game.winner is not None:
            return

        if self.game.botTurn == True:
            return

        cards = arcade.get_sprites_at_point((x, y), self.current_player_hand)

        if len(cards) > 0:
            primary_card = cards[-1]

            self.held_cards = [primary_card]
            self.held_cards_original_position = [self.held_cards[0].position]
            self.show_top(self.held_cards[0])

    def on_mouse_motion(self, x: float, y: float, dx: float, dy: float):
        if self.game.winner is not None:
            return

        if self.game.botTurn == True:
            return

        for card in self.held_cards:
            card.center_x += dx
            card.center_y += dy

    def on_mouse_release(self, x: float, y: float, button: int,
                         modifiers: int):
        if self.game.winner is not None:
            return

        if len(self.held_cards) == 0:
            return

        if self.game.botTurn == True:
            return

        pile, distance = arcade.get_closest_sprite(self.held_cards[0],
                                                   self.pile_mat_list)
        reset_position = True
        pile_index = self.pile_mat_list.index(pile)
        if arcade.check_for_collision(
                self.held_cards[0],
                pile) and self.game.roundStep == ATACK_ROUND and len(
                    self.piles[pile_index]) == 0:
            if self.game.Attack(self.held_cards[0]):
                for i, dropped_card in enumerate(self.held_cards):
                    dropped_card.position = pile.center_x, pile.center_y
                self.piles[pile_index].append(self.held_cards[0])
                self.game.atackList.append(self.held_cards[0])
                self.redraw_hand()
                self.redraw_opp_hand()
                self.game.turnDownButton = False
                reset_position = False
        elif arcade.check_for_collision(
                self.held_cards[0],
                pile) and self.game.roundStep == DEFEND_ROUND and len(
                    self.piles[pile_index]) == 1:
            if self.piles[pile_index][0] in self.game.atackList:
                defend = self.game.atackList[self.game.atackList.index(
                    self.piles[pile_index][0])]
            if self.game.Defend(self.held_cards[0], defend):
                for i, dropped_card in enumerate(self.held_cards):
                    dropped_card.position = pile.center_x, pile.center_y - CARD_VERTICAL_OFFSET
                self.piles[pile_index].append(self.held_cards[0])
                if len(self.game.atackList) == len(self.game.defendList):
                    self.ui_manager.purge_ui_elements()
                    if len(self.game.OpponentPlayer.hand) == 0:
                        time.sleep(5)
                        self.finish_round()
                        return
                    self.game.nextPlayerButton = True
                    self.ui_manager.add_ui_element(self.next_button)
                    self.game.takeAllButton = False
                    self.redraw_hand()
                else:
                    self.redraw_hand()
                    self.redraw_opp_hand()
                reset_position = False
        if reset_position:
            for pile_index, card in enumerate(self.held_cards):
                card.position = self.held_cards_original_position[pile_index]
            self.return_down(self.held_cards[0])

        self.held_cards = []
Exemplo n.º 2
0
class Menu:
    def __init__(self, window, world, show=True):
        self.window = window
        self.world = world
        self.joystick_check = JOYSTICK_CHECK_FREQUENCY
        self.selected_button = None
        self.show = show

        self.ui_manager = UIManager(self.window)
        self.sprite_list = arcade.SpriteList()

        def style(button):
            button.set_style_attrs(
                font_color=arcade.color.WHITE,
                font_color_hover=arcade.color.WHITE,
                font_color_press=arcade.color.WHITE,
                bg_color=(51, 139, 57),
                bg_color_hover=(51, 139, 57),
                bg_color_press=(28, 71, 32),
                border_color=(51, 139, 57),
                border_color_hover=arcade.color.WHITE,
                border_color_press=arcade.color.WHITE,
            )

        half_width = self.window.width / 2
        half_height = self.window.height / 2
        panel_height = len(BUTTONS) * (BUTTON_HEIGHT + BUTTON_MARGIN)
        half_panel_height = panel_height / 2

        def button(num, name):
            offset_y = half_panel_height - (BUTTON_HEIGHT + BUTTON_MARGIN) * num
            b = UIFlatButton(
                name,
                center_x=half_width,
                center_y=half_height + offset_y,
                width=BUTTON_WIDTH,
                height=BUTTON_HEIGHT,
            )
            style(b)
            self.ui_manager.add_ui_element(b)
            return b

        self.buttons = {}
        for num, name in enumerate(BUTTONS):
            self.buttons[name] = button(num, name)

        s = arcade.Sprite("data/images/help-image.png")
        s.center_x = 640
        s.center_y = 150
        self.sprite_list.append(s)

    def highlight_button(self, direction):
        button_count = len(BUTTONS)
        first_button = 0
        last_button = button_count - 1
        if self.selected_button is None:
            if direction > 0:
                self.selected_button = first_button
            else:
                self.selected_button = last_button
        else:
            self.selected_button += direction
            if self.selected_button < 0:
                self.selected_button = last_button
            if self.selected_button == button_count:
                self.selected_button = first_button
        for i, name in enumerate(BUTTONS):
            button = self.buttons[name]
            button.hovered = i == self.selected_button

    def update(self, dt):
        for _, input_source in self.world.get_component(InputSource):
            if input_source.state.get(MENU):
                self.show = True
        if self.show:
            self.joystick_check += dt
            menu_activator = None
            if self.joystick_check > JOYSTICK_CHECK_FREQUENCY:
                check_joysticks(self.world)
                self.joystick_check = 0

            for e, source in self.world.get_component(InputSource):
                source.state.update()
                events = source.state.events
                for event in list(events):
                    if event.input == DOWN:
                        self.highlight_button(1)
                        events.remove(event)
                    if event.input == UP:
                        self.highlight_button(-1)
                        events.remove(event)
                    if event.input == ACTIVATE and self.selected_button is not None:
                        menu_activator = source
                        arcade_button = self.buttons[BUTTONS[self.selected_button]]
                        arcade_button.pressed = True
                        arcade_button.hovered = False
                        self.selected_button = None
                        events.remove(event)

            if self.buttons[BUTTON_PLAY].pressed:
                self.show = False
                if menu_activator is None:
                    for _, input_source in self.world.get_component(InputSource):
                        if input_source.name == "Keyboard":
                            menu_activator = input_source
                self.spawn_player(menu_activator)
                self.buttons[BUTTON_PLAY].pressed = False

            if self.buttons[BUTTON_RESTART].pressed:
                dispatch(self.world, RESTART_GAME)
                self.buttons[BUTTON_RESTART].pressed = False

            if self.buttons[BUTTON_EXIT].pressed:
                arcade.close_window()

    def draw(self):
        self.ui_manager.on_draw()
        self.sprite_list.draw()

    def is_started(self, input_source):
        for _, pc in self.world.get_component(Player):
            if pc.input_source == input_source:
                return True
        return False

    def spawn_player(self, input_source):
        is_started = self.is_started(input_source)
        if not is_started:
            player.create_player(self.world, input_source)
Exemplo n.º 3
0
class Game(arcade.Window):
    # Играют по очереди, сначала делает ход первый игрок, потом второй и т.д.
    hosts: list = [
    ]  # список хостов (фракций) игроков (хост - играбельный объект, т.е. страна)
    hosts_num = 2
    active_host: int  # номер текущего активного хоста (тот, который играет)
    game_iteration: int  # номер хода

    host_init_pos = {0: (1, 10), 1: (8, 1)}

    gamer_host: int

    state = None
    select_color = "BLUE"
    select2_color = "COLUMBIA_BLUE"

    ui_margin_left = None
    ui_margin_top = None

    game_over = False

    def __init__(self):
        self.state = GameState()
        self.map = HexMap(hex_radius=MAP_HEX_RADIUS)
        self.w, self.h = self.map.get_window_size()
        super().__init__(self.w + self.w // 4, self.h, "Poliyoy")

        arcade.set_background_color(arcade.color.BLACK)

        self.ui_manager = UIManager()
        self.ui_margin_left = self.w / 15
        self.ui_margin_top = self.h / 10

        self.game_iteration = 0

        self.setup()

    def __new__(cls):
        if not hasattr(cls, 'instance'):
            cls.instance = super(Game, cls).__new__(cls)
        return cls.instance

    def init_hosts(self):
        for (e, frac) in enumerate(FRACTIONS_CONFIG.keys()):
            self.hosts.append(Fraction(**FRACTIONS_CONFIG[frac]))

            fraction = self.hosts[-1]
            self.state.append_fraction(fraction)

            if not fraction.isBot:
                self.active_host = e
                self.gamer_host = e

            self.map.place_fraction(fraction,
                                    self.host_init_pos[fraction.fraction_id])

        self.state.set_fraction(self.gamer_host)

    def setup(self):
        """
        Здесь рендеринг UI и инициализация пользовательской fraction
        Например, разместить сущности стран на карте
        :return:
        """

        self.map.create_map()
        self.init_hosts()
        self.after_init()  # размещение на карте деревьев и т.п.
        # self.map.after_init(self.hosts)  # размещение на карте деревьев и т.п.

        self.ui_manager.purge_ui_elements()
        set_ui(self)

        # back = self.state.last_mouse_tile_pos
        # back2 = self.state.last_fraction
        # self.hosts[not self.active_host].money_amount = 9999
        #
        # pos = self.hosts[not self.active_host].fraction_capital_pos
        # self.state.last_mouse_tile_pos = pos
        # self.state.last_fraction = self.hosts[not self.active_host]
        # obj = SpawnEntity(self.map, self.state, 1, UpdateGameState(self))
        # obj.execute()
        # self.state.last_mouse_tile_pos = back
        # self.state.last_fraction = back2
        # sys.exit()

    def after_init(self):
        """
        Запуск после размещения fractions
        :return:
        """
        trees = self.map.get_random_positions()
        from config import TREE_ID
        fr = self.state.get_last_fraction()
        for i in trees:
            self.map.spawn_tree(i, fr)

    def on_draw(self):
        """
        Рендеринг различных объектов
        """

        # This command has to happen before we start drawing
        arcade.start_render()
        self.map.draw()
        self.ui_manager.on_draw()

    def on_next_step_key_press(self):
        # print("before", self.hosts[1].money_amount)
        for host in self.hosts:
            for tile in host.tiles:
                self.map.unuse_entity(tile)

        self.game_over = self.state.get_last_fraction().make_step()
        self.update_screen_info()

        self.game_iteration += 1

        self.active_host = not self.active_host
        self.state.set_fraction(self.active_host)  # upd last host
        self.update_screen_info()

        fraction = self.state.get_last_fraction()
        # if fraction.village_cost_prev != fraction.village_cost:
        self.update_village_btn()

    def update_screen_info(self):
        self.ui_manager.find_by_id("money_amount").text = "Gold: " + str(
            self.state.get_last_fraction().money_amount)
        self.ui_manager.find_by_id("money_step").text = "Delta: " + str(
            self.state.get_last_fraction().step_delta)

    def update_village_btn(self):
        # Тяжелая операция, поэтому случай обрабатывается отдельно
        # # Дальше костыль для обновления текста кнопки (в либе такое, почему-то, не предусмотрено)
        update_ui(self)

    def on_mouse_press(self, x, y, button, modifiers):
        """
        Обработка пользовательского действия
        """
        col, row = self.map.locate(x, y)
        host = self.state.get_last_fraction()
        pos = (col, row)

        self.map.unselect_tiles()

        if button == 1:
            if self.map.is_in_map(col, row):
                self.map.add_tile_to_state(pos)
                self.map.select_tile(pos, self.select_color)

                self.state.set_pos(col, row)

                if pos in host.units_pos.keys():
                    self.map.show_move_range(pos, self.select_color,
                                             self.select2_color)

        elif button == 4:
            unit_pos = self.state.last_mouse_tile_pos
            if unit_pos in host.units_pos.keys():
                self.state.last_mouse_right_tile_pos = pos
                command = MoveUnit(self.map, self.state, UpdateGameState(self))
                command.execute()

            if pos in host.tiles.keys():
                pass

        # print(self.active_host, self.state.get_last_fraction().fraction_id)

    def possible_moves(self, pos):
        return self.map.show_move_range_quiet(pos)

    def bot_move(self):
        pass