def __init__(self, parent_game): self.parent_game = parent_game super().__init__(parent_game.window_surface, pos=(0, 0, 0, 0), fill=False, darken_background=False, blocking=False) self.chatlog = PopupBox(parent_game.window_surface, pos=(chatlog_x, chatlog_y, chatlog_width, chatlog_height), color=GREY, darken_background=False, blocking=False, transparent=True, alpha_color=80) self.setup_chat_sender() self.is_chatlog_folded = True self.current_lifes = MAX_PLAYER_TANK_HP # Начальные жизни игрока self.lifes = [] for i in range(MAX_PLAYER_TANK_HP): image_life = MenuImage( parent_game.window_surface, (chatlog_x + 48 * i, chatlog_y - 64, 48, 48), parent_game.image_loader.get_image_by_name("life"), shadow=True) self.lifes.append(image_life)
def add_wait_for_start_popupbox(game): # Всплывающее окно "Ожидайте начала игры": popupbox = PopupBox(game.window_surface, pos=(game.window_surface.get_width() / 2 - 150, game.window_surface.get_height() / 2 - 75, 300, 150), color=MAIN_MENU_BACKGROUND_COLOR) label_popupbox_title = Label(game.window_surface, pos=(popupbox.rect.x + popupbox.rect.w / 2, popupbox.rect.y + 15, 0, 0), text="Вы подключёны к серверу", text_color=MENU_WHITE, font_size=20, font="main_menu") label_popupbox_title_shadow = Label(game.window_surface, pos=(popupbox.rect.x + popupbox.rect.w / 2 + 2, popupbox.rect.y + 17, 0, 0), text="Вы подключёны к серверу", text_color=BLACK, font_size=20, font="main_menu") label_popupbox_title2 = Label(game.window_surface, pos=(popupbox.rect.x + popupbox.rect.w / 2, popupbox.rect.y + 45, 0, 0), text="Ожидайте начала игры", text_color=BUTTON_YELLOW, font_size=28, font="main_menu") label_popupbox_title2_shadow = Label(game.window_surface, pos=(popupbox.rect.x + popupbox.rect.w / 2 + 2, popupbox.rect.y + 47, 0, 0), text="Ожидайте начала игры", text_color=BLACK, font_size=28, font="main_menu") label_popupbox_esc = Label(game.window_surface, pos=(popupbox.rect.x + popupbox.rect.w / 2, popupbox.rect.y + 125, 0, 0), text="Нажмите ESC, чтобы отключиться", text_color=BUTTON_YELLOW, font_size=16, font="main_menu") label_popupbox_esc_shadow = Label(game.window_surface, pos=(popupbox.rect.x + popupbox.rect.w / 2 + 2, popupbox.rect.y + 127, 0, 0), text="Нажмите ESC, чтобы отключиться", text_color=BLACK, font_size=16, font="main_menu") buttontrigger_popupbox_quit_esc = ButtonTrigger(key=pygame.K_ESCAPE, function_list=[ remove_wait_popupbox_and_return_to_menu], args_list=[game]) popupbox.add_object(buttontrigger_popupbox_quit_esc) popupbox.add_object(label_popupbox_title_shadow) popupbox.add_object(label_popupbox_title) popupbox.add_object(label_popupbox_title2_shadow) popupbox.add_object(label_popupbox_title2) popupbox.add_object(label_popupbox_esc_shadow) popupbox.add_object(label_popupbox_esc) with game.any_popup_box_lock: game.any_popup_box = None game.any_popup_box = popupbox
def add_you_win_popupbox(game): # Всплывающее окно "Победа! Ваша миссия в данном регионе окончена!": popupbox = PopupBox(game.window_surface, pos=(game.window_surface.get_width() / 2 - 100, game.window_surface.get_height() / 2 - 50, 200, 100), color=MAIN_MENU_BACKGROUND_COLOR) label_popupbox_title = Label(game.window_surface, pos=(popupbox.rect.x + popupbox.rect.w / 2, popupbox.rect.y + 15, 0, 0), text="Победа!".upper(), text_color=MENU_WHITE, font_size=20, font="main_menu") label_popupbox_title_shadow = Label(game.window_surface, pos=(popupbox.rect.x + popupbox.rect.w / 2 + 2, popupbox.rect.y + 17, 0, 0), text="Победа!".upper(), text_color=BLACK, font_size=20, font="main_menu") label_popupbox_title2 = Label(game.window_surface, pos=(popupbox.rect.x + popupbox.rect.w / 2, popupbox.rect.y + 45, 0, 0), text="Ваша миссия в данном регионе окончена!", text_color=BUTTON_YELLOW, font_size=28, font="main_menu") label_popupbox_title2_shadow = Label(game.window_surface, pos=(popupbox.rect.x + popupbox.rect.w / 2 + 2, popupbox.rect.y + 47, 0, 0), text="Ваша миссия в данном регионе окончена!", text_color=BLACK, font_size=28, font="main_menu") label_popupbox_esc = Label(game.window_surface, pos=(popupbox.rect.x + popupbox.rect.w / 2, popupbox.rect.y + 85, 0, 0), text="Нажмите ESC, чтобы вернуться в меню", text_color=BUTTON_YELLOW, font_size=16, font="main_menu") label_popupbox_esc_shadow = Label(game.window_surface, pos=(popupbox.rect.x + popupbox.rect.w / 2 + 2, popupbox.rect.y + 87, 0, 0), text="Нажмите ESC, чтобы вернуться в меню", text_color=BLACK, font_size=16, font="main_menu") buttontrigger_popupbox_quit_esc = ButtonTrigger(key=pygame.K_ESCAPE, function_list=[ remove_popupbox_and_return_to_menu], args_list=[game]) popupbox.add_object(buttontrigger_popupbox_quit_esc) popupbox.add_object(label_popupbox_title_shadow) popupbox.add_object(label_popupbox_title) popupbox.add_object(label_popupbox_title2_shadow) popupbox.add_object(label_popupbox_title2) popupbox.add_object(label_popupbox_esc_shadow) popupbox.add_object(label_popupbox_esc) with game.any_popup_box_lock: game.any_popup_box = None game.any_popup_box = popupbox
def add_game_over_player_died_popupbox(game, player_name): # Всплывающее окно "Игра закончена Игрок # потерял все жизни.": popupbox = PopupBox(game.window_surface, pos=(game.window_surface.get_width() / 2 - 100, game.window_surface.get_height() / 2 - 50, 200, 100), color=MAIN_MENU_BACKGROUND_COLOR) label_popupbox_title = Label(game.window_surface, pos=(popupbox.rect.x + popupbox.rect.w / 2, popupbox.rect.y + 15, 0, 0), text="Game over!".upper(), text_color=MENU_WHITE, font_size=20, font="main_menu") label_popupbox_title_shadow = Label(game.window_surface, pos=(popupbox.rect.x + popupbox.rect.w / 2 + 2, popupbox.rect.y + 17, 0, 0), text="Game over!".upper(), text_color=BLACK, font_size=20, font="main_menu") label_popupbox_title2 = Label(game.window_surface, pos=(popupbox.rect.x + popupbox.rect.w / 2, popupbox.rect.y + 45, 0, 0), text=f"Игрок {player_name} потерял все доступные жизни!", text_color=BUTTON_YELLOW, font_size=28, font="main_menu") label_popupbox_title2_shadow = Label(game.window_surface, pos=(popupbox.rect.x + popupbox.rect.w / 2 + 2, popupbox.rect.y + 47, 0, 0), text=f"Игрок {player_name} потерял все доступные жизни!", text_color=BLACK, font_size=28, font="main_menu") label_popupbox_esc = Label(game.window_surface, pos=(popupbox.rect.x + popupbox.rect.w / 2, popupbox.rect.y + 85, 0, 0), text="Нажмите ESC, чтобы вернуться в меню", text_color=BUTTON_YELLOW, font_size=16, font="main_menu") label_popupbox_esc_shadow = Label(game.window_surface, pos=(popupbox.rect.x + popupbox.rect.w / 2 + 2, popupbox.rect.y + 87, 0, 0), text="Нажмите ESC, чтобы вернуться в меню", text_color=BLACK, font_size=16, font="main_menu") buttontrigger_popupbox_quit_esc = ButtonTrigger(key=pygame.K_ESCAPE, function_list=[ remove_popupbox_and_return_to_menu], args_list=[game]) popupbox.add_object(buttontrigger_popupbox_quit_esc) popupbox.add_object(label_popupbox_title_shadow) popupbox.add_object(label_popupbox_title) popupbox.add_object(label_popupbox_title2_shadow) popupbox.add_object(label_popupbox_title2) popupbox.add_object(label_popupbox_esc_shadow) popupbox.add_object(label_popupbox_esc) with game.any_popup_box_lock: game.any_popup_box = None game.any_popup_box = popupbox
def add_server_started_popupbox(game): # Всплывающее окно "Сервер закрыт": popupbox = PopupBox(game.window_surface, pos=(game.window_surface.get_width() / 2 - 100, game.window_surface.get_height() / 2 - 50, 200, 100), color=MAIN_MENU_BACKGROUND_COLOR) label_popupbox_title = Label(game.window_surface, pos=(popupbox.rect.x + popupbox.rect.w / 2, popupbox.rect.y + 15, 0, 0), text="Сервер запущен", text_color=MENU_WHITE, font_size=20, font="main_menu") label_popupbox_title_shadow = Label(game.window_surface, pos=(popupbox.rect.x + popupbox.rect.w / 2 + 2, popupbox.rect.y + 17, 0, 0), text="Сервер запущен:", text_color=BLACK, font_size=20, font="main_menu") label_popupbox_title2 = Label(game.window_surface, pos=(popupbox.rect.x + popupbox.rect.w / 2, popupbox.rect.y + 45, 0, 0), text="Ожидание клиентов", text_color=BUTTON_YELLOW, font_size=28, font="main_menu") label_popupbox_title2_shadow = Label(game.window_surface, pos=(popupbox.rect.x + popupbox.rect.w / 2 + 2, popupbox.rect.y + 47, 0, 0), text="Ожидание клиентов", text_color=BLACK, font_size=28, font="main_menu") label_popupbox_esc = Label(game.window_surface, pos=(popupbox.rect.x + popupbox.rect.w / 2, popupbox.rect.y + 85, 0, 0), text="Нажмите ESC, чтобы закрыть сервер", text_color=BUTTON_YELLOW, font_size=16, font="main_menu") label_popupbox_esc_shadow = Label(game.window_surface, pos=(popupbox.rect.x + popupbox.rect.w / 2 + 2, popupbox.rect.y + 87, 0, 0), text="Нажмите ESC, чтобы закрыть сервер", text_color=BLACK, font_size=16, font="main_menu") buttontrigger_popupbox_quit_esc = ButtonTrigger(key=pygame.K_ESCAPE, function_list=[ remove_server_started_popupbox_and_return_to_menu], args_list=[game]) popupbox.add_object(buttontrigger_popupbox_quit_esc) popupbox.add_object(label_popupbox_title_shadow) popupbox.add_object(label_popupbox_title) popupbox.add_object(label_popupbox_title2_shadow) popupbox.add_object(label_popupbox_title2) popupbox.add_object(label_popupbox_esc_shadow) popupbox.add_object(label_popupbox_esc) with game.any_popup_box_lock: game.any_popup_box = None game.any_popup_box = popupbox
def setup_chat_sender(self) -> None: """ Инициализирует поле chat_sender класса. """ # class MessageSentState: # message_sent = False # def send_msg(message_sent_state: MessageSentState): def send_msg(): # if not message_sent_state.message_sent: # message = textbox_message.text_str # if len(message) > 0: # self.parent_game.send_chat_message(message) # textbox_message.text_str = "" # self.hide_chat_sender() # message_sent_state.message_sent = True message = textbox_message.text_str if len(message) > 0: self.parent_game.send_chat_message(message) textbox_message.text_str = "" self.hide_chat_sender() # mss = MessageSentState() self.chat_sender = PopupBox(self.parent_game.window_surface, pos=(0, 0, 0, 0), fill=False, darken_background=True) textbox_message = TextBox(self.parent_game.window_surface, pos=(chat_textbox_x, chat_textbox_y, chat_textbox_width, chat_textbox_height), empty_text="Введите сюда своё сообщение...", font="main_menu", font_size=chat_font_size, function_onEnter=send_msg, arg_onEnter=None, active=True) button_send_message_width = chat_textbox_width * 0.1 button_send_message_x = chat_textbox_x + chat_textbox_width - button_send_message_width button_send_message_shadow = Label( self.parent_game.window_surface, pos=(button_send_message_x + 2, chat_textbox_y + 2, button_send_message_width, chat_textbox_height), text=">>", text_color=BLACK, font_size=chat_font_size, font="main_menu") button_send_message = Button( self.parent_game.window_surface, pos=(button_send_message_x, chat_textbox_y, button_send_message_width, chat_textbox_height), transparent=True, text_color=GREY, selected_text_color=MENU_WHITE, text=">>", font_size=chat_font_size, font="main_menu", function_onClick_list=[send_msg], args_list=[None]) # args_list=[mss]) buttontrigger_popupbox_quit_esc = ButtonTrigger( key=pygame.K_ESCAPE, function_list=[self.hide_chat_sender], args_list=[None]) buttontrigger_send_message_enter = ButtonTrigger( key=pygame.K_RETURN, function_list=[send_msg], args_list=[None]) # args_list=[mss]) self.chat_sender.add_object(buttontrigger_popupbox_quit_esc) self.chat_sender.add_object(buttontrigger_send_message_enter) self.chat_sender.add_object(textbox_message) self.chat_sender.add_object(button_send_message_shadow) self.chat_sender.add_object(button_send_message) self.is_chat_sender_shown = False
class GUI(PopupBox): parent_game = None # Игра, в которой отображается данный GUI chatlog: PopupBox = None # Чатлог chat_sender: PopupBox = None # Строка для отправки сообщения. current_lifes: int = None # Количество жизней у игрока. lifes: List[MenuImage] = None # Жизни игрока is_chatlog_folded: bool = None # Свёрнут ли чатлог? is_chat_sender_shown: bool = None # Показывается ли строка отправки сообщения # TODO: Может, сделать такую штуку для любой кнопки? is_change_chatlog_action_button_pressed: bool = False # Флаг нажатия клавиши (для предотвращения # складывания/раскладывания чатлога) def __init__(self, parent_game): self.parent_game = parent_game super().__init__(parent_game.window_surface, pos=(0, 0, 0, 0), fill=False, darken_background=False, blocking=False) self.chatlog = PopupBox(parent_game.window_surface, pos=(chatlog_x, chatlog_y, chatlog_width, chatlog_height), color=GREY, darken_background=False, blocking=False, transparent=True, alpha_color=80) self.setup_chat_sender() self.is_chatlog_folded = True self.current_lifes = MAX_PLAYER_TANK_HP # Начальные жизни игрока self.lifes = [] for i in range(MAX_PLAYER_TANK_HP): image_life = MenuImage( parent_game.window_surface, (chatlog_x + 48 * i, chatlog_y - 64, 48, 48), parent_game.image_loader.get_image_by_name("life"), shadow=True) self.lifes.append(image_life) def setup_chat_sender(self) -> None: """ Инициализирует поле chat_sender класса. """ # class MessageSentState: # message_sent = False # def send_msg(message_sent_state: MessageSentState): def send_msg(): # if not message_sent_state.message_sent: # message = textbox_message.text_str # if len(message) > 0: # self.parent_game.send_chat_message(message) # textbox_message.text_str = "" # self.hide_chat_sender() # message_sent_state.message_sent = True message = textbox_message.text_str if len(message) > 0: self.parent_game.send_chat_message(message) textbox_message.text_str = "" self.hide_chat_sender() # mss = MessageSentState() self.chat_sender = PopupBox(self.parent_game.window_surface, pos=(0, 0, 0, 0), fill=False, darken_background=True) textbox_message = TextBox(self.parent_game.window_surface, pos=(chat_textbox_x, chat_textbox_y, chat_textbox_width, chat_textbox_height), empty_text="Введите сюда своё сообщение...", font="main_menu", font_size=chat_font_size, function_onEnter=send_msg, arg_onEnter=None, active=True) button_send_message_width = chat_textbox_width * 0.1 button_send_message_x = chat_textbox_x + chat_textbox_width - button_send_message_width button_send_message_shadow = Label( self.parent_game.window_surface, pos=(button_send_message_x + 2, chat_textbox_y + 2, button_send_message_width, chat_textbox_height), text=">>", text_color=BLACK, font_size=chat_font_size, font="main_menu") button_send_message = Button( self.parent_game.window_surface, pos=(button_send_message_x, chat_textbox_y, button_send_message_width, chat_textbox_height), transparent=True, text_color=GREY, selected_text_color=MENU_WHITE, text=">>", font_size=chat_font_size, font="main_menu", function_onClick_list=[send_msg], args_list=[None]) # args_list=[mss]) buttontrigger_popupbox_quit_esc = ButtonTrigger( key=pygame.K_ESCAPE, function_list=[self.hide_chat_sender], args_list=[None]) buttontrigger_send_message_enter = ButtonTrigger( key=pygame.K_RETURN, function_list=[send_msg], args_list=[None]) # args_list=[mss]) self.chat_sender.add_object(buttontrigger_popupbox_quit_esc) self.chat_sender.add_object(buttontrigger_send_message_enter) self.chat_sender.add_object(textbox_message) self.chat_sender.add_object(button_send_message_shadow) self.chat_sender.add_object(button_send_message) self.is_chat_sender_shown = False def hide_chat_sender(self): self.is_chat_sender_shown = False self.blocking = False def show_chat_sender(self): self.is_chat_sender_shown = True self.blocking = True def update_chatlog(self) -> None: """ Удаляет все старые сообещния в чатлоге и создаёт новые Labels основываясь на chat_history в Game. """ if self.parent_game.chat_history.has_new_messages: self.chatlog.clear() # Очистка всех сообщений for (i, message) in enumerate( self.parent_game.chat_history.read_messages()): if i > max_messages_in_chatlog: break temp_message_y = chatlog_y + chatlog_height - ( one_message_height * (i + 1)) temp_label_message = Label(self.parent_game.window_surface, pos=(chat_textbox_x, temp_message_y, chatlog_width, one_message_height), text=message, font_size=chat_font_size, text_color=BUTTON_YELLOW, font="main_menu", alignment=LEFT_ALIGNMENT) temp_label_message_shadow = Label( self.parent_game.window_surface, pos=(chat_textbox_x + 2, temp_message_y + 2, chatlog_width, one_message_height), text=message, font_size=chat_font_size, text_color=BLACK, font="main_menu", alignment=LEFT_ALIGNMENT) self.chatlog.add_object(temp_label_message_shadow) self.chatlog.add_object(temp_label_message) def show_chatlog(self) -> None: """ Показывает (разворачивает) чатлог. """ self.is_chatlog_folded = False def fold_chatlog(self) -> None: """ Сворачивает (скрывает) чатлог. """ self.is_chatlog_folded = True def change_chatlog_action(self): if not self.is_change_chatlog_action_button_pressed: self.is_chatlog_folded = not self.is_chatlog_folded self.is_change_chatlog_action_button_pressed = True def reset_button(self): self.is_change_chatlog_action_button_pressed = False def set_lifes(self, new_lifes: int) -> None: """ Устанавливает количество видимых значков жизни. :param new_lifes: Целочисленное значение от 0 до MAX_PLAYER_TANK_HP. """ self.current_lifes = max(min(MAX_PLAYER_TANK_HP, new_lifes), 0) # 0 <= new_lifes <= MAX_PLAYER_TANK_HP for life in self.lifes[self.current_lifes:]: life.active = False for life in self.lifes[:self.current_lifes]: life.active = True def decrease_lifes(self): new_lifes = max(min(MAX_PLAYER_TANK_HP, self.current_lifes - 1), 0) self.set_lifes(new_lifes) def draw(self): if not self.is_chatlog_folded: # Отрисовка чатлога self.chatlog.draw() if self.is_chat_sender_shown: self.chat_sender.draw() for life in self.lifes: life.draw() def update(self): self.update_chatlog() # Апдейт чатлога if self.is_chat_sender_shown: self.chat_sender.update() if not self.parent_game.multi: # Обновление жизней в одиночке current_player_lifes = self.parent_game.world.objects_id_dict[ self.parent_game.client_world_object_id].lifes if self.current_lifes != current_player_lifes: self.set_lifes(current_player_lifes) def handle_event(self, event: EventType): if self.is_chat_sender_shown: self.chat_sender.handle_event(event)