Ejemplo n.º 1
0
class MessageLog(UIWindow):
    def __init__(self, rect, manager):
        self.text = Message("Welcome to Vibe!").html_text + "<br>"
        self.rect = rect
        self.text_box = None
        self.manager = manager
        super().__init__(self.rect, manager, ["message_log"])
        self.text_box = UITextBox(self.text, self.rect, self.manager, wrap_to_height=False, layer_starting_height=1)

    def add_message(self, message):
        self.text += message.html_text + "<br>"
        if self.text_box:
            self.text_box.kill()
        
        self.text_box = UITextBox(self.text,
            pygame.Rect((0, 0), (self.rect.width, self.rect.height)), self.manager, wrap_to_height=False, layer_starting_height=1, container=self.get_container())
        self.text_box.parse_html_into_style_data()

        """
        got this from Snayff, not quite sure how it works
        sauce: https://bitbucket.org/Snayff/notquiteparadise/src/develop/scripts/engine/ui/elements/message_log.py
        """

        if self.text_box.scroll_bar:
            scroll_bar = self.text_box.scroll_bar
            scroll_bar.scroll_wheel_down = False
            scroll_bar.scroll_position += (250 * 1)
            scroll_bar.scroll_position = min(scroll_bar.scroll_position,
                                           scroll_bar.bottom_limit - scroll_bar.sliding_button.rect.height)
            x_pos = scroll_bar.rect.x + scroll_bar.shadow_width + scroll_bar.border_width
            y_pos = scroll_bar.scroll_position + scroll_bar.rect.y + scroll_bar.shadow_width + \
                    scroll_bar.border_width + scroll_bar.button_height
            scroll_bar.sliding_button.set_position(pygame.math.Vector2(x_pos, y_pos))

            scroll_bar.start_percentage = scroll_bar.scroll_position / scroll_bar.scrollable_height
            if not scroll_bar.has_moved_recently:
                scroll_bar.has_moved_recently = True

    def kill(self):
        self.text_box.kill()
Ejemplo n.º 2
0
class Chat(UIContainer):
    # region Docstring
    """
    Class to display the game chat
    """

    # endregion

    def __init__(
        self,
        size: tuple[int, int],
        manager: IUIManagerInterface,
        udp: UDP_P2P,
        username: str,
    ) -> None:
        # region Docstring
        """
        Creates a `Chat` object

        ### Arguments
            `size {(int, int)}`:
                `summary`: the size of the chat window
            `manager {UIManager}`:
                `summary`: the UIManager that manages this element.
            `udp {UDP_P2P}`:
                `summary`: the udp object
            `username {str}`:
                `summary`: the username of this host
        """
        # endregion
        super().__init__(relative_rect=Rect((Game.SIZE[0], 0), size),
                         manager=manager)

        # region Element creation

        self.textbox = UITextBox(
            html_text="",
            relative_rect=Rect((0, 0), (size[0], size[1] - 25)),
            manager=manager,
            container=self,
        )

        self.entryline = UITextEntryLine(
            relative_rect=Rect((0, size[1] - 28), (size[0] - 50, 20)),
            manager=manager,
            container=self,
        )
        self.entryline.set_text_length_limit(100)

        self.enterbtn = UIButton(
            text="Enter",
            relative_rect=Rect((size[0] - 50, size[1] - 28), (50, 30)),
            manager=manager,
            container=self,
        )

        # endregion

        self.record = ""
        self.size = size
        self.udp = udp
        self.username = username

    def process_event(self, event: Event) -> Union[bool, None]:
        # region Docstring
        """
        Overridden method to handle the gui events

        ### Arguments
            `event {Event}`:
                `summary`: the fired event

        ### Returns
            `bool | None`: return if the event has been handled
        """
        # endregion

        handled = super().process_event(event)
        if event.type != USEREVENT:
            return

        if (event.user_type == UI_TEXT_ENTRY_FINISHED and event.ui_element
                == self.entryline) or (event.user_type == UI_BUTTON_PRESSED
                                       and event.ui_element == self.enterbtn):
            self.__send()
            handled = True

        return handled

    def __send(self) -> None:
        # region Docstring
        """
        Handles the press of the enter `UIButton`, sending the user message.\n
        """
        # endregion

        if len(self.entryline.get_text().strip()) > 0:
            self.udp.transmission("CHA", "01", self.username,
                                  self.entryline.get_text().strip())
            self.__addmsg(
                f"<b>(YOU): </b><br>{self.entryline.get_text().strip()}<br>")
            self.entryline.set_text("")

    def receive(self, data: Packet, addr: Tuple[str, int],
                time: datetime) -> None:
        # region Docstring
        """
        Method that handles the received data, address and time of reception

        ### Arguments
            `data {Packet}`:
                `summary`: the data received
            `addr {Tuple[str, int]}`:
                `summary`: the source address and port
                example: (192.168.0.1, 6000)
            `time {datetime}`:
                `summary`: the time of the packet reception
        """
        # endregion

        n = UDP_P2P.latency(
            datetime.strptime(time.strftime("%H%M%S%f"), "%H%M%S%f"),
            datetime.strptime(data.time + "000", "%H%M%S%f"),
        )

        self.record += f"<b>({data.nick.strip()} - {addr[0]} - {n}ms): </b><br>{data.msg.strip()}<br>"

    def update(self, time_delta: float) -> None:
        # region Docstring
        """
        Overridden method to update the element

        ### Arguments
            `time_delta {float}`:
                `summary`: the time passed between frames, measured in seconds.
        """
        # endregion

        super().update(time_delta)
        if self.record != self.textbox.html_text:
            self.textbox.kill()
            self.textbox = UITextBox(
                html_text=self.record,
                relative_rect=Rect((0, 0), (self.size[0], self.size[1] - 25)),
                container=self,
                manager=self.ui_manager,
            )

    def __addmsg(self, msg: str) -> None:
        # region Docstring
        """
        Method to insert text in the `UITextBox` element

        ### Arguments
            `msg {str}`:
                `summary`: the text to insert
        """
        # endregion
        self.record += msg
        self.textbox.kill()
        self.textbox = UITextBox(
            html_text=self.record,
            relative_rect=Rect((0, 0), (self.size[0], self.size[1] - 25)),
            container=self,
            manager=self.ui_manager,
        )
Ejemplo n.º 3
0
class GUIopediaWindow(pygame_gui.elements.UIWindow):
    def __init__(self, manager):
        super().__init__(pygame.Rect((200, 50), (420, 520)),
                         manager,
                         window_display_title='GUIopedia!',
                         object_id="#guiopedia_window")

        search_bar_top_margin = 2
        search_bar_bottom_margin = 2
        self.search_box = pygame_gui.elements.UITextEntryLine(pygame.Rect((150,
                                                                           search_bar_top_margin),
                                                                          (240, 20)),
                                                              manager=manager,
                                                              container=self,
                                                              parent_element=self)

        self.search_label = pygame_gui.elements.UILabel(pygame.Rect((90,
                                                                     search_bar_top_margin),
                                                                    (56,
                                                                     self.search_box.rect.height)),
                                                        "Search:",
                                                        manager=manager,
                                                        container=self,
                                                        parent_element=self)

        self.home_button = pygame_gui.elements.UIButton(pygame.Rect((20, search_bar_top_margin),
                                                                    (29, 29)),
                                                        '',
                                                        manager=manager,
                                                        container=self,
                                                        parent_element=self,
                                                        object_id='#home_button')

        self.remaining_window_size = (self.get_container().get_size()[0],
                                      (self.get_container().get_size()[1] -
                                       (self.search_box.rect.height +
                                        search_bar_top_margin +
                                        search_bar_bottom_margin)))

        self.pages = {}
        page_path = 'data/guiopedia/'
        file_paths = [join(page_path, f) for f in listdir(page_path) if isfile(join(page_path, f))]
        for file_path in file_paths:
            with open(file_path, 'r') as page_file:
                file_id = splitext(basename(file_path))[0]
                file_data = ""
                for line in page_file:
                    line = line.rstrip(linesep).lstrip()
                    # kind of hacky way to add back spaces at the end of new lines that
                    # are removed by the pyCharm HTML
                    # editor. perhaps our HTML parser needs to handle this case
                    # (turning new lines into spaces
                    # but removing spaces at the start of rendered lines?)
                    if len(line) > 0:
                        if line[-1] != '>':
                            line += ' '
                        file_data += line
                self.pages[file_id] = file_data

        index_page = self.pages['index']
        self.page_y_start_pos = (self.search_box.rect.height +
                                 search_bar_top_margin +
                                 search_bar_bottom_margin)
        self.page_display = UITextBox(index_page,
                                      pygame.Rect((0, self.page_y_start_pos),
                                                  self.remaining_window_size),
                                      manager=manager,
                                      container=self,
                                      parent_element=self)

    def process_event(self, event):
        handled = super().process_event(event)
        if event.type != pygame.USEREVENT:
            return
        if event.user_type == pygame_gui.UI_TEXT_BOX_LINK_CLICKED:
            self.open_new_page(event.link_target)
            handled = True

        if (event.user_type == pygame_gui.UI_TEXT_ENTRY_FINISHED and
                event.ui_element == self.search_box):
            results = self.search_pages(event.text)
            self.create_search_results_page(results)
            self.open_new_page('results')
            handled = True

        if (event.user_type == pygame_gui.UI_BUTTON_PRESSED and
                event.ui_object_id == '#guiopedia_window.#home_button'):
            self.open_new_page('index')
            handled = True

        return handled

    def search_pages(self, search_string: str):
        results = {}
        words = search_string.split()

        for page in self.pages.keys():
            total_occurances_of_search_words = 0
            for word in words:
                word_occurances = self.search_text_for_occurrences_of_word(word, self.pages[page])
                total_occurances_of_search_words += word_occurances
            if total_occurances_of_search_words > 0:
                results[page] = total_occurances_of_search_words

        sorted_results = sorted(results.items(), key=lambda item: item[1], reverse=True)
        return OrderedDict(sorted_results)

    @staticmethod
    def search_text_for_occurrences_of_word(word_to_search_for: str, text_to_search: str) -> int:
        return sum(1 for _ in re.finditer(r'\b%s\b' % re.escape(word_to_search_for),
                                          text_to_search,
                                          flags=re.IGNORECASE))

    def open_new_page(self, page_link: str):
        self.page_display.kill()
        self.page_display = None
        if page_link in self.pages:
            text = self.pages[page_link]

            self.page_display = UITextBox(text,
                                          pygame.Rect((0,
                                                       self.page_y_start_pos),
                                                      self.remaining_window_size),
                                          manager=self.ui_manager,
                                          container=self,
                                          parent_element=self)

    def create_search_results_page(self, results):
        results_text = '<font size=5>Search results</font>'
        if len(results) == 0:
            results_text += '<br><br> No Results Found.'
        else:
            results_text += '<br><br>' + str(len(results)) + ' results found:'
            for result in results.keys():
                results_text += '<br><br> - <a href=\"' + result + '\">' + result + '</a>'

        self.pages['results'] = results_text
Ejemplo n.º 4
0
class Game:
    def __init__(self):
        # Start up Pygame.
        pygame.init()

        # Title the window our game runs in.
        pygame.display.set_caption(config.game_name)
        
        self.options = Options()

        # Define the dimensions of our game's window.
        self.window_surface = pygame.display.set_mode(self.options.resolution)
        self.window_surface.blit(pygame.image.load("media/images/background.png"), (0, 0))

        self.start_up = True
        self.enter_mines = False
        self.enter_busstop = False
        self.enter_uptown = False

        self.background_surface = None

        self.ui_manager = UIManager(self.options.resolution, PackageResource(package='media.themes', resource='theme.json'))

        self.text_block = None
        self.text_entry = None

        self.message_window = None

        self.recreate_ui()

        self.clock = pygame.time.Clock()
        self.time_delta_stack = deque([])
        self.running = True

    def recreate_ui(self):
        self.ui_manager.set_window_resolution(self.options.resolution)
        self.ui_manager.clear_and_reset()

        self.background_surface = pygame.Surface(self.options.resolution)

        if self.start_up == True:
            self.image = UIImage(pygame.Rect((0, 0), self.options.resolution), title_screen_image, self.ui_manager)
        elif self.enter_mines == True:
            self.image = UIImage(pygame.Rect((0, 0), self.options.resolution), mines_image, self.ui_manager)
        elif self.enter_busstop == True:
            self.image = UIImage(pygame.Rect((0, 0), self.options.resolution), busstop_image, self.ui_manager)
        elif self.enter_uptown == True:
            self.image = UIImage(pygame.Rect((0, 0), self.options.resolution), uptown_image, self.ui_manager)
        else: 
            self.background_surface.fill(self.ui_manager.get_theme().get_colour('dark_bg'))
            self.background_surface.blit(pygame.image.load("media/images/background.png"), (0, 0))
            
            global response_history
            response = response_history
            response_history = response
            self.text_entry = UITextEntryLine(pygame.Rect((50, 550), (700, 50)), self.ui_manager, object_id = "#text_entry")
            self.text_block = UITextBox(response, pygame.Rect((50, 25), (700, 500)), self.ui_manager, object_id = "#text_block")

    def process_events(self):
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                self.running = False

            self.ui_manager.process_events(event)            

            if event.type==pygame.KEYDOWN:
                if event.key== pygame.K_UP:              
                    if self.start_up == True:
                        self.start_up = False
                        self.recreate_ui()
                    if self.enter_mines == True:
                        self.enter_mines = False
                        self.recreate_ui()
                    if self.enter_busstop == True:
                        self.enter_busstop = False
                        self.recreate_ui()
                    if self.enter_uptown == True:
                        self.enter_uptown = False
                        self.recreate_ui()
            if event.type == pygame.USEREVENT:
                if (event.user_type == pygame_gui.UI_TEXT_ENTRY_FINISHED and event.ui_object_id == '#text_entry'):
                    if event.text != "":
                        # Turn the user's input into a string.
                        message = event.text

                        # Begin the response message. Start with repeating the user's input.
                        response = "<b><i>> {message}</i></b>".format(message = message)

                        # Create a player object using the player's save data.
                        player_data = player.Player()

                        # Check to see if the player is in a scripted sequence.
                        if player_data.scene is not None: # If they are...
                            if player_data.scene == config.scene_id_newgame: # If the player has started the game for the first time.
                                command_response = scenes.Introduction(message)
                                response += ("<br>" * 4) + command_response
                        else: # If they aren't...
                            command_response = utilities.parse_message(message)
                            response += ("<br>" * 4) + command_response

                        # End the response with some decoration. ^_^
                        response += ("<br>" * 4) + ("-" * 20) + ("<br>" * 4)

                        # Add this response to our response history, and then send the entire history to be rendered.
                        global response_history
                        response += response_history
                        response_history = response
                        # Render the response.
                        self.text_entry.set_text("")
                        self.text_block.kill()
                        self.text_block = UITextBox(response, pygame.Rect((50, 25), (700, 500)), self.ui_manager, object_id = "#text_block")
                        
                        if command_response == "You enter the Mines.":
                            self.enter_mines = True
                            self.recreate_ui()
                        if command_response == "You enter a Bus Stop.":
                            self.enter_busstop = True
                            self.recreate_ui()
                        if command_response == "You enter Uptown.":
                            self.enter_uptown = True
                            self.recreate_ui()
    def run(self):
        while self.running:
            time_delta = self.clock.tick() / 1000
            
            # Check for inputs from the player.
            self.process_events()

            # Respond to inputs.
            self.ui_manager.update(time_delta)

            # Draw the graphics.
            self.window_surface.blit(self.background_surface, (0, 0))
            self.ui_manager.draw_ui(self.window_surface)

            pygame.display.update()