class UIColourChannelEditor(UIElement):
    """
    This colour picker specific element lets us edit a single colour channel (Red, Green, Blue,
    Hue etc). It's bundled along with the colour picker class because I don't see much use for it
    outside of a colour picker, but it still seemed sensible to make a class for a pattern in the
    colour picker that is repeated six times.

    :param relative_rect: The relative rectangle for sizing and positioning the element, relative
                          to the anchors.
    :param manager: The UI manager for the UI system.
    :param name: Name for this colour channel, (e.g 'R:' or 'B:'). Used for the label.
    :param channel_index: Index for the colour channel (e.g. red is 0, blue is 1, hue is also 0,
                          saturation is 1)
    :param value_range: Range of values for this channel (0 to 255 for R,G,B - 0 to 360 for hue, 0
                        to 100 for the rest)
    :param initial_value: Starting value for this colour channel.
    :param container: UI container for this element.
    :param parent_element: An element to parent this element, used for theming hierarchies and
                           events.
    :param object_id: A specific theming/event ID for this element.
    :param anchors: A dictionary of anchors used for setting up what this element's relative_rect
                    is relative to.
    :param visible: Whether the element is visible by default. Warning - container visibility
                    may override this.
    """
    def __init__(self,
                 relative_rect: pygame.Rect,
                 manager: IUIManagerInterface,
                 name: str,
                 channel_index: int,
                 value_range: Tuple[int, int],
                 initial_value: int,
                 container: Union[IContainerLikeInterface, None] = None,
                 parent_element: UIElement = None,
                 object_id: Union[ObjectID, str, None] = None,
                 anchors: Dict[str, str] = None,
                 visible: int = 1):

        super().__init__(relative_rect,
                         manager,
                         container,
                         starting_height=1,
                         layer_thickness=1,
                         anchors=anchors,
                         visible=visible)

        self._create_valid_ids(container=container,
                               parent_element=parent_element,
                               object_id=object_id,
                               element_id='colour_channel_editor')

        self.range = value_range
        self.current_value = initial_value
        self.channel_index = channel_index

        self.set_image(self.ui_manager.get_universal_empty_surface())

        self.element_container = UIContainer(relative_rect,
                                             self.ui_manager,
                                             container=self.ui_container,
                                             parent_element=self,
                                             anchors=anchors,
                                             visible=self.visible)

        default_sizes = {
            'space_between': 3,
            'label_width': 17,
            'entry_width': 43,
            'line_height': 29,
            'slider_height': 21,
            'slider_vert_space': 4
        }

        self.label = UILabel(pygame.Rect(0, 0, -1,
                                         default_sizes['line_height']),
                             text=name,
                             manager=self.ui_manager,
                             container=self.element_container,
                             parent_element=self,
                             anchors={
                                 'left': 'left',
                                 'right': 'left',
                                 'top': 'top',
                                 'bottom': 'bottom'
                             })

        self.entry = UITextEntryLine(pygame.Rect(-default_sizes['entry_width'],
                                                 0,
                                                 default_sizes['entry_width'],
                                                 default_sizes['line_height']),
                                     manager=self.ui_manager,
                                     container=self.element_container,
                                     parent_element=self,
                                     anchors={
                                         'left': 'right',
                                         'right': 'right',
                                         'top': 'top',
                                         'bottom': 'bottom'
                                     })

        slider_width = (self.entry.rect.left - self.label.rect.right) - (
            2 * default_sizes['space_between'])

        self.slider = UIHorizontalSlider(pygame.Rect(
            (self.label.get_abs_rect().width + default_sizes['space_between']),
            default_sizes['slider_vert_space'], slider_width,
            default_sizes['slider_height']),
                                         start_value=initial_value,
                                         value_range=value_range,
                                         manager=self.ui_manager,
                                         container=self.element_container,
                                         parent_element=self,
                                         anchors={
                                             'left': 'left',
                                             'right': 'right',
                                             'top': 'top',
                                             'bottom': 'bottom'
                                         })

        self.entry.set_allowed_characters('numbers')
        self.entry.set_text(str(initial_value))
        self.entry.set_text_length_limit(3)

    def process_event(self, event: pygame.event.Event) -> bool:
        """
        Handles events that this UI element is interested in. In this case we are responding to the
        slider being moved and the user finishing entering text in the text entry element.

        :param event: The pygame Event to process.

        :return: True if event is consumed by this element and should not be passed on to other
                 elements.

        """
        consumed_event = super().process_event(event)
        if event.type == UI_TEXT_ENTRY_FINISHED and event.ui_element == self.entry:
            int_value = self.current_value
            try:
                int_value = int(self.entry.get_text())
            except ValueError:
                int_value = 0
            finally:
                self._set_value_from_entry(int_value)

        if event.type == UI_HORIZONTAL_SLIDER_MOVED and event.ui_element == self.slider:
            int_value = self.current_value
            try:
                int_value = int(self.slider.get_current_value())
            except ValueError:
                int_value = 0
            finally:
                self._set_value_from_slider(int_value)

        return consumed_event

    def _set_value_from_slider(self, new_value: int):
        """
        For updating the value in the text entry element when we've moved the slider. Also sends
        out an event for the color picker.

        :param new_value: The new value to set.

        """
        clipped_value = min(self.range[1], max(self.range[0], new_value))
        if clipped_value != self.current_value:
            self.current_value = clipped_value
            self.entry.set_text(str(self.current_value))
            # old event - to be removed in 0.8.0
            event_data = {
                'user_type': OldType(UI_COLOUR_PICKER_COLOUR_CHANNEL_CHANGED),
                'value': self.current_value,
                'channel_index': self.channel_index,
                'ui_element': self,
                'ui_object_id': self.most_specific_combined_id
            }
            pygame.event.post(pygame.event.Event(pygame.USEREVENT, event_data))

            # new event
            event_data = {
                'value': self.current_value,
                'channel_index': self.channel_index,
                'ui_element': self,
                'ui_object_id': self.most_specific_combined_id
            }
            pygame.event.post(
                pygame.event.Event(UI_COLOUR_PICKER_COLOUR_CHANNEL_CHANGED,
                                   event_data))

    def _set_value_from_entry(self, new_value: int):
        """
        For updating the value the slider element is set to when we've edited the text entry. The
        slider may have much less precision than the text entry depending on it's available width
        so we need to be careful to make the change one way. Also sends out an event for the color
        picker and clips the value to within the allowed value range.

        :param new_value: The new value to set.

        """
        clipped_value = min(self.range[1], max(self.range[0], new_value))
        if clipped_value != new_value:
            self.entry.set_text(str(clipped_value))
        if clipped_value != self.current_value:
            self.current_value = clipped_value
            self.slider.set_current_value(self.current_value)

            # old event - to be removed in 0.8.0
            event_data = {
                'user_type': OldType(UI_COLOUR_PICKER_COLOUR_CHANNEL_CHANGED),
                'value': self.current_value,
                'channel_index': self.channel_index,
                'ui_element': self,
                'ui_object_id': self.most_specific_combined_id
            }
            colour_channel_changed_event = pygame.event.Event(
                pygame.USEREVENT, event_data)
            pygame.event.post(colour_channel_changed_event)

            event_data = {
                'value': self.current_value,
                'channel_index': self.channel_index,
                'ui_element': self,
                'ui_object_id': self.most_specific_combined_id
            }
            colour_channel_changed_event = pygame.event.Event(
                UI_COLOUR_PICKER_COLOUR_CHANNEL_CHANGED, event_data)
            pygame.event.post(colour_channel_changed_event)

    def set_value(self, new_value: int):
        """
        For when we need to set the value of the colour channel from outside, usually from
        adjusting the colour elsewhere in the colour picker. Makes sure the new value is within the
        allowed range.

        :param new_value: Value to set.

        """
        clipped_value = min(self.range[1], max(self.range[0], new_value))
        if clipped_value != self.current_value:
            self.current_value = clipped_value
            self.entry.set_text(str(self.current_value))
            self.slider.set_current_value(self.current_value)

    def set_position(self, position: Union[pygame.math.Vector2,
                                           Tuple[int, int], Tuple[float,
                                                                  float]]):
        """
        Sets the absolute screen position of this channel, updating all subordinate elements at the
        same time.

        :param position: The absolute screen position to set.

        """
        super().set_position(position)
        self.element_container.set_relative_position(
            self.relative_rect.topleft)

    def set_relative_position(self, position: Union[pygame.math.Vector2,
                                                    Tuple[int, int],
                                                    Tuple[float, float]]):
        """
        Sets the relative screen position of this channel, updating all subordinate elements at the
        same time.

        :param position: The relative screen position to set.

        """
        super().set_relative_position(position)
        self.element_container.set_relative_position(
            self.relative_rect.topleft)

    def set_dimensions(self, dimensions: Union[pygame.math.Vector2,
                                               Tuple[int, int], Tuple[float,
                                                                      float]]):
        """
        Method to directly set the dimensions of an element.

        :param dimensions: The new dimensions to set.

        """
        super().set_dimensions(dimensions)
        self.element_container.set_dimensions(self.relative_rect.size)

    def show(self):
        """
        In addition to the base UIElement.show() - call show() of the element_container
        - which will propagate to the sub-elements - label, entry and slider.
        """
        super().show()

        self.element_container.show()

    def hide(self):
        """
        In addition to the base UIElement.hide() - call hide() of the element_container
        - which will propagate to the sub-elements - label, entry and slider.
        """
        super().hide()

        self.element_container.hide()
    def __init__(self,
                 relative_rect: pygame.Rect,
                 manager: IUIManagerInterface,
                 name: str,
                 channel_index: int,
                 value_range: Tuple[int, int],
                 initial_value: int,
                 container: Union[IContainerLikeInterface, None] = None,
                 parent_element: UIElement = None,
                 object_id: Union[ObjectID, str, None] = None,
                 anchors: Dict[str, str] = None,
                 visible: int = 1):

        super().__init__(relative_rect,
                         manager,
                         container,
                         starting_height=1,
                         layer_thickness=1,
                         anchors=anchors,
                         visible=visible)

        self._create_valid_ids(container=container,
                               parent_element=parent_element,
                               object_id=object_id,
                               element_id='colour_channel_editor')

        self.range = value_range
        self.current_value = initial_value
        self.channel_index = channel_index

        self.set_image(self.ui_manager.get_universal_empty_surface())

        self.element_container = UIContainer(relative_rect,
                                             self.ui_manager,
                                             container=self.ui_container,
                                             parent_element=self,
                                             anchors=anchors,
                                             visible=self.visible)

        default_sizes = {
            'space_between': 3,
            'label_width': 17,
            'entry_width': 43,
            'line_height': 29,
            'slider_height': 21,
            'slider_vert_space': 4
        }

        self.label = UILabel(pygame.Rect(0, 0, -1,
                                         default_sizes['line_height']),
                             text=name,
                             manager=self.ui_manager,
                             container=self.element_container,
                             parent_element=self,
                             anchors={
                                 'left': 'left',
                                 'right': 'left',
                                 'top': 'top',
                                 'bottom': 'bottom'
                             })

        self.entry = UITextEntryLine(pygame.Rect(-default_sizes['entry_width'],
                                                 0,
                                                 default_sizes['entry_width'],
                                                 default_sizes['line_height']),
                                     manager=self.ui_manager,
                                     container=self.element_container,
                                     parent_element=self,
                                     anchors={
                                         'left': 'right',
                                         'right': 'right',
                                         'top': 'top',
                                         'bottom': 'bottom'
                                     })

        slider_width = (self.entry.rect.left - self.label.rect.right) - (
            2 * default_sizes['space_between'])

        self.slider = UIHorizontalSlider(pygame.Rect(
            (self.label.get_abs_rect().width + default_sizes['space_between']),
            default_sizes['slider_vert_space'], slider_width,
            default_sizes['slider_height']),
                                         start_value=initial_value,
                                         value_range=value_range,
                                         manager=self.ui_manager,
                                         container=self.element_container,
                                         parent_element=self,
                                         anchors={
                                             'left': 'left',
                                             'right': 'right',
                                             'top': 'top',
                                             'bottom': 'bottom'
                                         })

        self.entry.set_allowed_characters('numbers')
        self.entry.set_text(str(initial_value))
        self.entry.set_text_length_limit(3)
Exemplo n.º 3
0
    def __init__(self, rect, ui_manager):
        super().__init__(rect,
                         ui_manager,
                         window_display_title='Everything Container',
                         object_id='#everything_window',
                         resizable=True)

        self.test_slider = UIHorizontalSlider(pygame.Rect(
            (int(self.rect.width / 2), int(self.rect.height * 0.70)),
            (240, 25)),
                                              50.0, (0.0, 100.0),
                                              self.ui_manager,
                                              container=self)

        self.slider_label = UILabel(
            pygame.Rect(
                (int(self.rect.width / 2) + 250, int(self.rect.height * 0.70)),
                (27, 25)),
            str(int(self.test_slider.get_current_value())),
            self.ui_manager,
            container=self)

        self.test_text_entry = UITextEntryLine(pygame.Rect(
            (int(self.rect.width / 2), int(self.rect.height * 0.50)),
            (200, -1)),
                                               self.ui_manager,
                                               container=self)
        self.test_text_entry.set_forbidden_characters('numbers')

        current_resolution_string = 'Item 1'
        self.test_drop_down_menu = UIDropDownMenu(
            [
                'Item 1', 'Item 2', 'Item 3', 'Item 4', 'Item 5', 'Item 6',
                'Item 7', 'Item 8', 'Item 9', 'Item 10', 'Item 11', 'Item 12',
                'Item 13', 'Item 14', 'Item 15', 'Item 16', 'Item 17',
                'Item 18', 'Item 19', 'Item 20', 'Item 21', 'Item 22',
                'Item 23', 'Item 24', 'Item 25', 'Item 26', 'Item 27',
                'Item 28', 'Item 29', 'Item 30'
            ],
            current_resolution_string,
            pygame.Rect(
                (int(self.rect.width / 2), int(self.rect.height * 0.3)),
                (200, 25)),
            self.ui_manager,
            container=self)

        self.health_bar = UIScreenSpaceHealthBar(pygame.Rect(
            (int(self.rect.width / 9), int(self.rect.height * 0.7)),
            (200, 20)),
                                                 self.ui_manager,
                                                 container=self)

        loaded_test_image = pygame.image.load(
            'data/images/splat.png').convert_alpha()

        self.test_image = UIImage(pygame.Rect(
            (int(self.rect.width / 9), int(self.rect.height * 0.3)),
            loaded_test_image.get_rect().size),
                                  loaded_test_image,
                                  self.ui_manager,
                                  container=self)
Exemplo n.º 4
0
    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)
        self.background_surface.fill(self.ui_manager.get_theme().get_colour(
            None, None, 'dark_bg'))

        self.test_button = UIButton(
            pygame.Rect((int(self.options.resolution[0] / 2),
                         int(self.options.resolution[1] * 0.90)), (100, 40)),
            '',
            self.ui_manager,
            tool_tip_text="<font face=fira_code color=normal_text size=2>"
            "<b><u>Test Tool Tip</u></b>"
            "<br><br>"
            "A little <i>test</i> of the "
            "<font color=#FFFFFF><b>tool tip</b></font>"
            " functionality."
            "<br><br>"
            "Unleash the Kraken!"
            "</font>",
            object_id='#hover_me_button')

        self.test_button_2 = UIButton(pygame.Rect(
            (int(self.options.resolution[0] / 3),
             int(self.options.resolution[1] * 0.90)), (100, 40)),
                                      'EVERYTHING',
                                      self.ui_manager,
                                      object_id='#everything_button')

        self.test_button_3 = UIButton(pygame.Rect(
            (int(self.options.resolution[0] / 6),
             int(self.options.resolution[1] * 0.90)), (100, 40)),
                                      'Scaling?',
                                      self.ui_manager,
                                      object_id='#scaling_button')

        self.test_slider = UIHorizontalSlider(pygame.Rect(
            (int(self.options.resolution[0] / 2),
             int(self.options.resolution[1] * 0.70)), (240, 25)),
                                              25.0, (0.0, 100.0),
                                              self.ui_manager,
                                              object_id='#cool_slider')

        self.test_text_entry = UITextEntryLine(pygame.Rect(
            (int(self.options.resolution[0] / 2),
             int(self.options.resolution[1] * 0.50)), (200, -1)),
                                               self.ui_manager,
                                               object_id='#main_text_entry')

        current_resolution_string = (str(self.options.resolution[0]) + 'x' +
                                     str(self.options.resolution[1]))
        self.test_drop_down = UIDropDownMenu(
            ['640x480', '800x600', '1024x768'], current_resolution_string,
            pygame.Rect((int(self.options.resolution[0] / 2),
                         int(self.options.resolution[1] * 0.3)),
                        (200, 25)), self.ui_manager)

        self.panel = UIPanel(pygame.Rect(50, 50, 200, 300),
                             starting_layer_height=4,
                             manager=self.ui_manager)

        UIButton(pygame.Rect(10, 10, 174, 30),
                 'Panel Button',
                 manager=self.ui_manager,
                 container=self.panel)

        UISelectionList(pygame.Rect(10, 50, 174, 200),
                        item_list=[
                            'Item 1', 'Item 2', 'Item 3', 'Item 4', 'Item 5',
                            'Item 6', 'Item 7', 'Item 8', 'Item 9', 'Item 10',
                            'Item 11', 'Item 12', 'Item 13', 'Item 14',
                            'Item 15', 'Item 16', 'Item 17', 'Item 18',
                            'Item 19', 'Item 20'
                        ],
                        manager=self.ui_manager,
                        container=self.panel,
                        allow_multi_select=True)
Exemplo n.º 5
0
    def __init__(self):
        pygame.init()

        pygame.display.set_caption("Pathfinding Algorithms")
        self.window_surface = pygame.display.set_mode((800, 600))

        self.ui_manager = pygame_gui.UIManager(
            (800, 600), "pathfinding/data/ui_theme.json")
        self.ui_manager.preload_fonts([{
            'name': 'fira_code',
            'point_size': 14,
            'style': 'bold'
        }])

        self.background_surface = pygame.Surface((800, 600))
        self.background_surface.fill(
            self.ui_manager.get_theme().get_colour('dark_bg'))

        self.playing_pathfinder = False
        self.play_speed = 0.5
        self.play_speed_acc = 0.0

        pathfinding_algorithms = [
            'A*', "Breadth First", "Depth First", "Dijkstra's", "Uniform Cost"
        ]
        self.pathfinder_drop_down = UIDropDownMenu(
            pathfinding_algorithms, 'A*', pygame.Rect((620, 50), (150, 25)),
            self.ui_manager)

        self.pathfinder_label = pygame_gui.elements.UILabel(
            pygame.Rect((520, 50), (100, 25)), "Algorithm: ", self.ui_manager)

        map_sizes = ['20x20', "40x40", "80x80"]
        self.map_size_drop_down = UIDropDownMenu(
            map_sizes, '20x20', pygame.Rect((620, 225), (150, 25)),
            self.ui_manager)

        self.map_size_label = pygame_gui.elements.UILabel(
            pygame.Rect((520, 225), (100, 25)), "Map size: ", self.ui_manager)

        self.random_start_button = UIButton(pygame.Rect((620, 350), (150, 25)),
                                            "Random start", self.ui_manager)

        self.increment_pathfinder_button = UIButton(
            pygame.Rect((620, 385), (150, 25)), "Increment", self.ui_manager)

        self.play_button = UIButton(pygame.Rect((620, 420), (150, 25)), "Play",
                                    self.ui_manager)

        self.speed_slider = UIHorizontalSlider(
            pygame.Rect((620, 455), (150, 25)), self.play_speed, (1.0, 0.017),
            self.ui_manager)

        self.speed_slider_label = pygame_gui.elements.UILabel(
            pygame.Rect((520, 455), (100, 25)), "Play speed: ",
            self.ui_manager)

        self.tool_tip = None

        self.wall_colour = pygame.Color("#FFFFFF")

        self.available_maze_space = 450
        self.wall_size = 4
        self.maze_dimension = 20

        self.maze_square_size = int(
            self.available_maze_space / self.maze_dimension) + 1
        self.walls, self.junctions, self.entrance, self.exit = create_maze(
            top_left=(20, 20),
            square_size=self.maze_square_size,
            width=self.maze_dimension,
            height=self.maze_dimension)

        self.nav_node_graph = [
            junction.nav_node for junction in self.junctions
        ]
        self.font = pygame.font.Font(None, 12)
        self.current_finder = AStarFinder(self.entrance.nav_node,
                                          self.exit.nav_node,
                                          incremental=True)

        self.clock = pygame.time.Clock()
        self.running = True
Exemplo n.º 6
0
class PathfindingApp:
    def __init__(self):
        pygame.init()

        pygame.display.set_caption("Pathfinding Algorithms")
        self.window_surface = pygame.display.set_mode((800, 600))

        self.ui_manager = pygame_gui.UIManager(
            (800, 600), "pathfinding/data/ui_theme.json")
        self.ui_manager.preload_fonts([{
            'name': 'fira_code',
            'point_size': 14,
            'style': 'bold'
        }])

        self.background_surface = pygame.Surface((800, 600))
        self.background_surface.fill(
            self.ui_manager.get_theme().get_colour('dark_bg'))

        self.playing_pathfinder = False
        self.play_speed = 0.5
        self.play_speed_acc = 0.0

        pathfinding_algorithms = [
            'A*', "Breadth First", "Depth First", "Dijkstra's", "Uniform Cost"
        ]
        self.pathfinder_drop_down = UIDropDownMenu(
            pathfinding_algorithms, 'A*', pygame.Rect((620, 50), (150, 25)),
            self.ui_manager)

        self.pathfinder_label = pygame_gui.elements.UILabel(
            pygame.Rect((520, 50), (100, 25)), "Algorithm: ", self.ui_manager)

        map_sizes = ['20x20', "40x40", "80x80"]
        self.map_size_drop_down = UIDropDownMenu(
            map_sizes, '20x20', pygame.Rect((620, 225), (150, 25)),
            self.ui_manager)

        self.map_size_label = pygame_gui.elements.UILabel(
            pygame.Rect((520, 225), (100, 25)), "Map size: ", self.ui_manager)

        self.random_start_button = UIButton(pygame.Rect((620, 350), (150, 25)),
                                            "Random start", self.ui_manager)

        self.increment_pathfinder_button = UIButton(
            pygame.Rect((620, 385), (150, 25)), "Increment", self.ui_manager)

        self.play_button = UIButton(pygame.Rect((620, 420), (150, 25)), "Play",
                                    self.ui_manager)

        self.speed_slider = UIHorizontalSlider(
            pygame.Rect((620, 455), (150, 25)), self.play_speed, (1.0, 0.017),
            self.ui_manager)

        self.speed_slider_label = pygame_gui.elements.UILabel(
            pygame.Rect((520, 455), (100, 25)), "Play speed: ",
            self.ui_manager)

        self.tool_tip = None

        self.wall_colour = pygame.Color("#FFFFFF")

        self.available_maze_space = 450
        self.wall_size = 4
        self.maze_dimension = 20

        self.maze_square_size = int(
            self.available_maze_space / self.maze_dimension) + 1
        self.walls, self.junctions, self.entrance, self.exit = create_maze(
            top_left=(20, 20),
            square_size=self.maze_square_size,
            width=self.maze_dimension,
            height=self.maze_dimension)

        self.nav_node_graph = [
            junction.nav_node for junction in self.junctions
        ]
        self.font = pygame.font.Font(None, 12)
        self.current_finder = AStarFinder(self.entrance.nav_node,
                                          self.exit.nav_node,
                                          incremental=True)

        self.clock = pygame.time.Clock()
        self.running = True

    def set_current_pathfinder(self, finder_name):
        if self.current_finder is not None:
            self.current_finder.shutdown()

        if finder_name == "Breadth First":
            self.current_finder.shutdown()
            self.current_finder = BreadthFirstFinder(self.entrance.nav_node,
                                                     self.exit.nav_node,
                                                     incremental=True,
                                                     allow_revisiting=False)
        elif finder_name == "A*":
            self.current_finder.shutdown()
            self.current_finder = AStarFinder(self.entrance.nav_node,
                                              self.exit.nav_node,
                                              incremental=True)
        elif finder_name == "Uniform Cost":
            self.current_finder.shutdown()
            self.current_finder = UniformCostFinder(self.entrance.nav_node,
                                                    self.exit.nav_node,
                                                    incremental=True,
                                                    allow_revisiting=False)
        elif finder_name == "Depth First":
            self.current_finder.shutdown()
            self.current_finder = DepthFirstFinder(self.entrance.nav_node,
                                                   self.exit.nav_node,
                                                   incremental=True,
                                                   allow_revisiting=False)
        elif finder_name == "Dijkstra's":
            self.current_finder.shutdown()
            self.current_finder = DijkstraFinder(self.entrance.nav_node,
                                                 self.exit.nav_node,
                                                 self.nav_node_graph,
                                                 incremental=True)

    def run(self):
        while self.running:
            time_delta = self.clock.tick(
                60) / 1000.0  # time_delta is time between loops in seconds

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

                self.ui_manager.process_events(event)

                if event.type == pygame_gui.UI_BUTTON_PRESSED:
                    if event.ui_element == self.increment_pathfinder_button:
                        self.playing_pathfinder = False
                        self.current_finder.increment_algorithm()
                    if event.ui_element == self.play_button:
                        if self.playing_pathfinder:
                            self.playing_pathfinder = False
                            self.play_button.set_text('Play')
                        else:
                            self.playing_pathfinder = True
                            self.play_button.set_text('Stop')

                    if event.ui_element == self.random_start_button:
                        start_nav_node = random.choice(self.nav_node_graph)
                        while start_nav_node == self.exit.nav_node:
                            start_nav_node = random.choice(self.nav_node_graph)
                        self.entrance = PathFinderNode(start_nav_node, None, 0)
                        self.set_current_pathfinder(
                            self.current_finder.get_name())

                if event.type == pygame_gui.UI_DROP_DOWN_MENU_CHANGED:
                    if event.ui_element == self.map_size_drop_down:
                        self.maze_dimension = int(event.text.split('x')[0])
                        self.maze_square_size = int(self.available_maze_space /
                                                    self.maze_dimension) + 1
                        result = create_maze(top_left=(20, 20),
                                             square_size=self.maze_square_size,
                                             width=self.maze_dimension,
                                             height=self.maze_dimension)
                        self.walls = result[0]
                        self.junctions = result[1]
                        self.entrance = result[2]
                        self.exit = result[3]
                        self.nav_node_graph = [
                            junction.nav_node for junction in self.junctions
                        ]

                        self.set_current_pathfinder(
                            self.current_finder.get_name())

                    elif event.ui_element == self.pathfinder_drop_down:
                        self.set_current_pathfinder(event.text)

            if self.playing_pathfinder:
                self.play_speed = self.speed_slider.get_current_value()
                self.play_speed_acc += time_delta
                if self.play_speed_acc >= self.play_speed:
                    self.play_speed_acc = 0.0
                    self.current_finder.increment_algorithm()

            self.ui_manager.update(time_delta)
            self.current_finder.update()

            self.window_surface.blit(self.background_surface, (0, 0))

            for wall in self.walls:
                pygame.draw.line(self.window_surface, self.wall_colour,
                                 wall.start_pos, wall.end_pos, self.wall_size)

            self.current_finder.draw_information(self.window_surface,
                                                 self.ui_manager,
                                                 self.maze_square_size)

            if self.entrance is not None:
                entrance_rect = pygame.Rect(0, 0, self.maze_square_size,
                                            self.maze_square_size)
                entrance_rect.center = self.entrance.nav_node.position
                pygame.draw.rect(self.window_surface, pygame.Color('#FFCC00'),
                                 entrance_rect)

            if self.exit is not None:
                exit_rect = pygame.Rect(0, 0, self.maze_square_size,
                                        self.maze_square_size)
                exit_rect.center = self.exit.nav_node.position
                pygame.draw.rect(self.window_surface, pygame.Color('#FF7700'),
                                 exit_rect)

            self.ui_manager.draw_ui(self.window_surface)

            pygame.display.update()
Exemplo n.º 7
0
    def build_gui(self):
        super().build_gui()
        panel_rect = Rect(
            0, 0, 500,
            self.display.get_rect().height - (get_param('panel_padding') * 2))
        panel_rect.centerx = self.display.get_rect().centerx
        panel_rect.y = get_param('panel_padding')
        self.ui_elements['panel'] = UIPanel(panel_rect, 1, self.gui)
        # all other elements are relative
        scene_label_rect = Rect(0, 0, 400, get_param('element_height'))
        scene_label_rect.y = get_param('element_padding')
        scene_label_rect.centerx = panel_rect.w // 2  # midpoint of the panel
        self.ui_elements['scene_label'] = UILabel(scene_label_rect,
                                                  "Generate Random Map",
                                                  self.gui,
                                                  self.ui_elements['panel'])
        # map size
        label_rect = Rect(0, 0, 150, get_param('element_height'))
        label_rect.y += scene_label_rect.bottom + get_param('element_padding')
        dd_rect = Rect(0, 0, 250, get_param('element_height'))
        dd_rect.y = label_rect.y
        label_rect.centerx = 125
        dd_rect.centerx = 325
        self.ui_elements['d_size_label'] = UILabel(label_rect, "Map Size",
                                                   self.gui,
                                                   self.ui_elements['panel'])
        self.ui_elements['dd_map_size'] = UIDropDownMenu(
            ['64', '128', '256'], '64', dd_rect, self.gui,
            self.ui_elements['panel'])
        # Seed
        label_rect.y += get_param('element_height') + get_param(
            'element_padding')
        ip_rect = Rect(0, 0, 180, get_param('element_height'))
        ip_rect.centerx = (panel_rect.w // 2) + 30
        ip_rect.y = label_rect.y
        s_btn_rect = Rect(0, 0, 60, get_param('element_height'))
        s_btn_rect.x = ip_rect.right + get_param('element_padding')
        s_btn_rect.y = ip_rect.y
        self.ui_elements['seed_label'] = UILabel(label_rect, 'Map Seed',
                                                 self.gui,
                                                 self.ui_elements['panel'])
        self.ui_elements['input_seed'] = UITextEntryLine(
            ip_rect, self.gui, self.ui_elements['panel'])
        self.ui_elements['btn_rnd_seed'] = UIButton(s_btn_rect, 'Random',
                                                    self.gui,
                                                    self.ui_elements['panel'])
        # I want to add two sliders, 1 for mountains and 1 for water, these would be used to control the upper
        # and lower limits of the height mapping.
        h_sl_ops = (0, 100)
        h_sl_sel = 50
        label_rect.y += get_param('element_height') + get_param(
            'element_padding')
        h_sl_rect = Rect(0, 0, 200, get_param('element_height'))
        h_sl_rect.centerx = (panel_rect.w //
                             2) + get_param('element_padding') + 30
        h_sl_rect.y = label_rect.y
        self.ui_elements['hsl_grass'] = UILabel(label_rect, 'Grass', self.gui,
                                                self.ui_elements['panel'])
        self.ui_elements['hs_grass'] = UIHorizontalSlider(
            h_sl_rect, h_sl_sel, h_sl_ops, self.gui, self.ui_elements['panel'])

        label_rect.y += get_param('element_height') + get_param(
            'element_padding')
        h_sl_rect.y = label_rect.y
        self.ui_elements['hsl_water'] = UILabel(label_rect, 'Water', self.gui,
                                                self.ui_elements['panel'])
        self.ui_elements['hs_water'] = UIHorizontalSlider(
            h_sl_rect, h_sl_sel, h_sl_ops, self.gui, self.ui_elements['panel'])

        label_rect.y += get_param('element_height') + get_param(
            'element_padding')
        h_sl_rect.y = label_rect.y
        self.ui_elements['hsl_mountain'] = UILabel(label_rect, 'Mountain',
                                                   self.gui,
                                                   self.ui_elements['panel'])
        self.ui_elements['hs_mountain'] = UIHorizontalSlider(
            h_sl_rect, h_sl_sel, h_sl_ops, self.gui, self.ui_elements['panel'])

        # buttons
        button_rect = Rect(0, 0, 200, get_param('element_height'))
        button_rect.centerx = panel_rect.w // 2
        button_rect.y = label_rect.bottom + get_param('element_padding')
        self.ui_elements['btn_preview'] = UIButton(button_rect,
                                                   "Generate Preview",
                                                   self.gui,
                                                   self.ui_elements['panel'])
        button_rect.w = 200
        button_rect.y += get_param('element_height') + get_param(
            'element_padding')
        button_rect.centerx = (panel_rect.w // 2) - 100
        self.ui_elements['btn_back'] = UIButton(button_rect, "Back", self.gui,
                                                self.ui_elements['panel'])
        # the apply button always starts off disabled
        button_rect.centerx = (panel_rect.w // 2) + 100
        self.ui_elements['btn_next'] = UIButton(button_rect, "Next", self.gui,
                                                self.ui_elements['panel'])
        pv_rect = Rect(0, 0, 300, 300)
        pv_rect.centerx = panel_rect.w // 2
        pv_rect.y = button_rect.bottom + get_param('element_padding')
        self.ui_elements['pv_image'] = UIImage(pv_rect, self.pv_img, self.gui,
                                               self.ui_elements['panel'])