Пример #1
0
    def __init__(
            self,
            orientation: str,
            position: Vec,
            screen_length: int,
            visible_length: int,
            total_length: int,
            width: int,
            fill_color: Color = (242, 242, 242),
            bar_color: Color = (64, 64, 64),
    ):
        self.length = length = screen_length
        # self.ratio = max(1, total_length / visible_length)
        self.sector_length = sector_length = length // total_length
        self.remainder = remainder = length - (sector_length * total_length)
        self.scroll_length = visible_length * sector_length + remainder
        if orientation == "y":
            dimensions = Vector(width, length)
        else:
            dimensions = Vector(length, width)

        self.orientation = orientation
        self.position = position
        self.dimensions = dimensions
        self.width = width
        self.fill_color = fill_color
        self.bar_color = bar_color

        self.display = pygame.Surface(dimensions)
        self.display.fill(fill_color)
Пример #2
0
 def get_map_xy(self) -> Vector:
     x, y = pygame.mouse.get_pos()
     sx, sy = self.screen_tile_size
     px, py = self.position
     mx, my = self.margin
     dx, dy = (px + mx, py + my)
     pos_x, pos_y = (x - dx) // sx, (y - dy) // sy
     if min(pos_x, pos_y) < 0:
         return Vector(-1, -1)
     scroll_x, scroll_y = self.curr_scroll
     return Vector(pos_x + scroll_x, pos_y + scroll_y)
Пример #3
0
    def calc_map_size(self) -> Vector:
        width, height = self.map_hw()
        map_tile_size = self.map_tile_size
        map = self.map

        sw, sh = self.width, self.height
        mw, mh = map.width, map.height
        max_scroll = Vector(max(mw - sw, 0), max(mh - sh, 0))

        dimensions = Vector(width * map_tile_size, height * map_tile_size)
        self.dimensions = dimensions
        self.max_scroll = max_scroll
        self.calc_map_display()

        return dimensions
Пример #4
0
 def get_xy(self) -> Vector:
     x, y = pygame.mouse.get_pos()
     sx, sy = self.screen_tile_size
     px, py = self.position
     mx, my = self.margin
     dx, dy = (px + mx, py + my)
     return Vector((x - dx) // sx, (y - dy) // sy)
Пример #5
0
 def move_hero_keys(
     self,
     keys: Union[MovementKeys, Tuple[str, str, str,
                                     str]] = ("up", "down", "left", "right")
 ) -> Tuple[bool, bool]:
     if not isinstance(keys, MovementKeys):
         keys = MovementKeys(*keys)
     keys = MovementKeys(*keys)
     keyboard = Window.get_keyboard()
     hx, hy = self.hero_position
     h, v = False, False
     if keyboard.key_pressed(keys.up):
         hy -= 1
         v = not v
     if keyboard.key_pressed(keys.down):
         hy += 1
         v = not v
     if keyboard.key_pressed(keys.left):
         hx -= 1
         h = not h
     if keyboard.key_pressed(keys.right):
         hx += 1
         h = not h
     hero_position = Vector(hx, hy)
     if (h or v) and self.can_move_to(hero_position):
         self.move_hero_to(hero_position)
         return h, v
     else:
         return False, False
Пример #6
0
    def scroll(self,
               delta: Union[Vec, int],
               dy: Optional[int] = None) -> Vector:
        if type(delta) == int:
            if dy is not None:
                delta = Vector(delta, dy)
            else:
                raise TypeError(
                    "scroll takes two integers or one tuple/vector")
        xmax, ymax = max_scroll = self.max_scroll
        if max(max_scroll) == 0:
            return Vector(0, 0)
        curr_scroll = self.curr_scroll
        new_scroll = clamp_2(add_v(curr_scroll, delta), (0, xmax), (0, ymax))

        self.curr_scroll = new_scroll
        return new_scroll
Пример #7
0
 def get_screen_position(self, x: int, y: int) -> Vector:
     scroll_x, scroll_y = self.curr_scroll
     cx, cy = x - scroll_x, y - scroll_y
     sx, sy = self.screen_tile_size
     px, py = self.position
     mx, my = self.margin
     dx, dy = px + mx, py + my
     return Vector(cx * sx + dx, cy * sy + dy)
Пример #8
0
    def set_scrollbar(self):
        sw, sh = self.screen_size
        sx, sy = self.curr_scroll
        vw, vh = self.size
        mw, mh = self.get_map_size()
        scroll_width = self.scroll_width

        self.has_scrollbar = True
        scroll_y_position = Vector(sw - scroll_width, 0)
        scroll_x_position = Vector(0, sh - scroll_width)

        self.scroll_bar_y = ScrollBar("y", scroll_y_position, sh, vh, mh,
                                      scroll_width)
        self.scroll_bar_x = ScrollBar("x", scroll_x_position, sw, vw, mw,
                                      scroll_width)

        self.scroll_bar_y.update(sy)
        self.scroll_bar_x.update(sx)
Пример #9
0
    def calc_map_display(self):
        sx, sy = self.screen_tile_size
        map_tile_size = self.map_tile_size
        factor = (sx / map_tile_size, sy / map_tile_size)

        width, height = self.map_hw()
        map_size = Vector(width * sx, height * sy)

        self.factor = factor
        self.map_size = map_size
Пример #10
0
    def calc_size(self, position: Vec, screen_size: Vec,
                  screen_tile_size: Vec) -> Tuple[int, int]:
        sw, sh = screen_size
        tx, ty = screen_tile_size

        height = sh - position[1]
        length = height // ty
        inner_height = length * ty
        margin = (height - inner_height) // 2

        self.height = height
        self.inner_height = inner_height
        self.length = length
        self.margin = margin

        self.screen_size = Vector(*screen_size)
        self.screen_tile_size = Vector(*screen_tile_size)
        self.width = ty
        self.position = Vector(*position)

        return height, length
Пример #11
0
    def __init__(self,
                 position: Vec,
                 size: Vec,
                 screen_size: Vec,
                 tile_size: Optional[Vec] = None,
                 *,
                 fill_color: Color = (192, 192, 192),
                 limit_margin: bool = False) -> None:
        self.calc_size(size,
                       screen_size,
                       tile_size,
                       position,
                       limit_margin=limit_margin)

        self.fill_color = fill_color
        self.curr_scroll = Vector(0, 0)
        self.max_scroll = Vector(0, 0)
        self.map_size = None
        self.bgimage_override = None

        self.screen = pygame.Surface(screen_size)
        self.screen.fill(fill_color)
Пример #12
0
def compute_dimensions() -> Tuple[Vector, Vector, Vector, Vector, Vector, Margin]:
    info = pygame.display.Info()
    (curr_w, curr_h) = current_size = Vector(info.current_w, info.current_h)

    (vw, vh) = visible_map_size = Vector(30, 16)
    (tw, th)  = (vw + 2, vh + 2)
    screen_tile_size = tx, ty = (curr_w // tw, curr_h // th)
    min_tile = min(screen_tile_size)
    # min_tile_type = "x" if min_tile == tx else "y"
    screen_tile_size = tx, ty = (min_tile, min_tile)
    (mt, mr, mb, ml) = margin = Margin(20, 0, 0, tx + 2)
    canvas_position = Vector(ml, mt)
    # canvas_size = (cw, ch) = (vw * tx, vh * ty)
    canvas_size = Vector(curr_w - mr - ml, curr_h - mt - mb)

    return (
        canvas_position,
        visible_map_size,
        canvas_size,
        current_size,
        screen_tile_size,
        margin
    )
Пример #13
0
    def set_map(self, map: Map, tileset: Optional[Tileset] = None):
        self.map = map
        self.tileset = tileset

        self.show_layers = 0b1111
        if tileset:
            self.map_tile_size = tileset.tile_size
        else:
            self.map_tile_size = self.screen_tile_size[0]

        self.curr_scroll = Vector(0, 0)

        dimensions = self.calc_map_size()

        self.display = pygame.Surface(dimensions)
Пример #14
0
 def move_hero_key_y(
     self,
     keys: Union[MovementKeys, MovementKeysUD, Tuple[str,
                                                     str]] = ("up", "down")
 ) -> bool:
     if not isinstance(keys, (MovementKeysUD, MovementKeys)):
         keys = MovementKeysUD(*keys)
     keyboard = Window.get_keyboard()
     hx, hy = self.hero_position
     moved = False
     if keyboard.key_pressed(keys.up):
         hy -= 1
         moved = not moved
     if keyboard.key_pressed(keys.down):
         hy += 1
         moved = not moved
     hero_position = Vector(hx, hy)
     if moved and self.can_move_to(hero_position):
         self.move_hero_to(hero_position)
         return moved
     return False
Пример #15
0
 def move_hero_key_x(
     self,
     keys: Union[MovementKeys, MovementKeysLR,
                 Tuple[str, str]] = ("left", "right")
 ) -> bool:
     if not isinstance(keys, (MovementKeysLR, MovementKeys)):
         keys = MovementKeysLR(*keys)
     keyboard = Window.get_keyboard()
     hx, hy = self.hero_position
     moved = False
     if keyboard.key_pressed(keys.left):
         hx -= 1
         moved = not moved
     if keyboard.key_pressed(keys.right):
         hx += 1
         moved = not moved
     hero_position = Vector(hx, hy)
     if moved and self.can_move_to(hero_position):
         self.move_hero_to(hero_position)
         return moved
     return False
Пример #16
0
    def move_hero_to(self, position: Vec):
        x, y = position
        width, height = self.get_map_size()
        if (0 <= x < width) and (0 <= y < height):
            p0 = self.hero_position

            self.hero_position = Vector(*position)

            mx, my = self.max_scroll
            if max(mx, my) > 0:
                sx, sy = self.curr_scroll
                width, height = self.size
                map_width, map_height = self.get_map_size()
                half_w, half_h = width // 2, height // 2
                rw, rh = width % 2, height % 2
                dx, dy = sub_v(p0, position)
                to_x, to_y = 0, 0

                if dx > 0 and sx > 0 and (map_width - x) > half_w:
                    # indo para a esquerda, posição atual está a > meia tela da borda direita
                    to_x = -dx
                elif dx < 0 and sx <= mx and x > half_w + rw:
                    # indo para a direita, posição atual está a > meia tela da borda esquerda
                    to_x = -dx

                if dy > 0 and sy > 0 and (map_height - y) > half_h:
                    # subindo, posição atual está a > meia tela do fundo
                    to_y = -dy
                elif dy < 0 and sy <= my and y > half_h + rh:
                    # descendo, posição atual está a > meia tela do topo
                    to_y = -dy

                self.scroll((to_x, to_y))

            hx, hy = self.get_hero_screen_position()
            self.hero.set_position(hx, hy)
Пример #17
0
    def calc_size(self,
                  size: Vec,
                  screen_size: Vec,
                  tile_size: Optional[Vec] = None,
                  position: Optional[Vec] = None,
                  *,
                  limit_margin: bool = False) -> Tuple[Vector, Vector, Vector]:
        sw, sh = screen_size
        width, height = size

        if limit_margin is None:
            limit_margin = self.limit_margin
        else:
            self.limit_margin = limit_margin

        if tile_size == None:
            tile_size = Vector(sw // width, sh // height)
            if limit_margin:
                min_tile = min(tile_size)
                tile_size = Vector(min_tile, min_tile)
        else:
            tile_size = Vector(*tile_size)

        tx, ty = tile_size
        (vw, vh) = display_size = Vector(width * tx, height * ty)
        margin = Vector((sw - vw) // 2, (sh - vh) // 2)

        self.width = width
        self.height = height
        self.margin = margin
        self.screen_tile_size = tile_size
        self.display_size = display_size
        self.screen_size = screen_size
        if position is not None: self.position = Vector(*position)

        return display_size, margin, tile_size
Пример #18
0
def add_v(a: Vec, b: Vec) -> Vector:
    return Vector(a[0] + b[0], a[1] + b[1])
Пример #19
0
 def place_hero(self, hero: Sprite, position: Vec = (0, 0)):
     self.hero = hero
     self.hero_position = Vector(*position)
Пример #20
0
 def get_display_position(self, x: int, y: int) -> Vector:
     tile_size = self.map_tile_size
     return Vector(x * tile_size, y * tile_size)
Пример #21
0
 def size(self) -> Vector:
     return Vector(self.width, self.height)
Пример #22
0
def clamp_2(values: Vec, limit_x: Vec, limit_y: Vec) -> Vector:
    x, y = values
    lx0, lx1 = limit_x
    ly0, ly1 = limit_y
    return Vector(max(lx0, min(x, lx1)), max(ly0, min(y, ly1)))
Пример #23
0
def clamp(values: Vec, limit: Vec) -> Vector:
    x, y = values
    l0, l1 = limit
    return Vector(max(l0, min(x, l1)), max(l0, min(y, l1)))
Пример #24
0
def sub_v(a: Vec, b: Vec) -> Vector:
    return Vector(a[0] - b[0], a[1] - b[1])
Пример #25
0
def get_positions(margin: Margin) -> Tuple[Vector, Vector]:
    tilebar_position = Vector(0, margin.top)
    label_position = Vector(margin.left, 2)

    return tilebar_position, label_position
Пример #26
0
 def map_hw(self) -> Vector:
     map = self.map
     map_w, map_h = map.width, map.height
     display_w, display_h = self.width, self.height
     return Vector(min(map_w, display_w), min(map_h, display_h))