Ejemplo n.º 1
0
class Button(MouseListener):
    def __init__(self, text, position, dimensions):
        self._hovered = False
        self._mouse_downed = False
        self._label = Label(position,
                            dimensions,
                            text,
                            font_size=dimensions[1],
                            padding=(constants.BUTTON_TEXT_PADDING,
                                     constants.BUTTON_TEXT_PADDING))
        self._hit_box = Rect(position, dimensions)
        self._position = position
        self._dimensions = dimensions
        super().__init__()

    def handle_mouse_motion(self, coords):
        self._hovered = self._hit_box.collidepoint(coords)

    def handle_mouse_button_up(self, coords):
        clicked = False

        if self._hovered and self._mouse_downed:
            clicked = True
        self._mouse_downed = False
        self._hovered = False
        return clicked

    def handle_mouse_button_down(self, coords):
        if self._hovered:
            self._mouse_downed = True

    def draw(self, screen):
        if self._hovered:
            border = constants.GREY
            background = constants.WHITE
        else:
            border = constants.WHITE
            background = constants.GREY
        screen.fill(border, self._hit_box)
        screen.fill(
            background,
            self._hit_box.inflate(-constants.BUTTON_BORDER_WEIGHT,
                                  -constants.BUTTON_BORDER_WEIGHT))
        self._label.draw(screen)
Ejemplo n.º 2
0
def draw_rect(surface, color, rect, image, radius=0.4):
    """
    surface : destination
    rect    : rectangle
    color   : rgb or rgba
    radius  : 0 <= radius <= 1
    """

    rect = Rect(rect)
    color = Color(*color)
    alpha = color.a
    color.a = 0
    pos = rect.topleft
    rect.topleft = 0, 0
    rectangle = Surface(rect.size, SRCALPHA)

    circle = Surface([min(rect.size) * 3] * 2, SRCALPHA)
    draw.ellipse(circle, (0, 0, 0), circle.get_rect(), 0)
    circle = transform.smoothscale(circle, [int(min(rect.size) * radius)] * 2)

    radius = rectangle.blit(circle, (0, 0))
    radius.bottomright = rect.bottomright
    rectangle.blit(circle, radius)
    radius.topright = rect.topright
    rectangle.blit(circle, radius)
    radius.bottomleft = rect.bottomleft
    rectangle.blit(circle, radius)

    rectangle.fill((0, 0, 0), rect.inflate(-radius.w, 0))
    rectangle.fill((0, 0, 0), rect.inflate(0, -radius.h))

    rectangle.fill(color, special_flags=BLEND_RGBA_MAX)
    rectangle.fill((255, 255, 255, alpha), special_flags=BLEND_RGBA_MIN)
    rectangle.blit(image, rect)

    return surface.blit(rectangle, pos)
Ejemplo n.º 3
0
class _TextBox(_Component):
    def __init__(self, font: Font, size: Vec2, text: str, border_color: Vec3,
                 text_color: Vec3, sound_player: SoundPlayer):
        super().__init__(Surface(size))
        self.surface.set_alpha(180)

        self._container_rect = Rect((0, 0), size)
        pad = 30
        self._text_area = self._container_rect.inflate(-pad, -pad)
        self._font = font
        self._border_color = border_color
        self._text_color = text_color
        self._sound_player = sound_player
        self._lines = self._split_into_lines(text)
        self._cursor = 0
        self._max_cursor_position = max(0, len(text) - 1)
        self._periodic_cursor_advance = PeriodicAction(Millis(40),
                                                       self._advance_cursor)

        self._redraw()

    def _advance_cursor(self):
        if self._cursor < self._max_cursor_position:
            self._sound_player.play_text_blip()
            self._cursor += 1
            self._redraw()

    def update(self, elapsed_time: Millis):
        self._periodic_cursor_advance.update(elapsed_time)

    def set_cursor_to_end(self):
        self._cursor = self._max_cursor_position
        self._redraw()

    def is_cursor_at_end(self) -> bool:
        return self._cursor == self._max_cursor_position

    def _split_into_lines(self, text) -> List[str]:
        return list(
            layout_text_in_area(text, lambda t: self._font.size(t)[0],
                                self._text_area.width))

    def _redraw(self):
        self.surface.fill(BLACK)
        pygame.draw.rect(self.surface,
                         self._border_color,
                         self._container_rect,
                         width=1,
                         border_radius=2)
        x, y = self._text_area.topleft
        num_chars_rendered = 0
        for line in self._lines:
            remaining = self._cursor + 1 - num_chars_rendered
            if remaining <= 0:
                return
            part_of_line = line[:remaining]
            rendered_line = self._font.render(part_of_line, True,
                                              self._text_color)
            self.surface.blit(rendered_line, (x, y))
            y += rendered_line.get_height()
            num_chars_rendered += len(part_of_line)
Ejemplo n.º 4
0
def are_rooms_too_close(room1: Rect, room2: Rect):
    return room1.inflate(2, 2).colliderect(room2.inflate(2, 2))