Пример #1
0
 def hit_wall(x, y):
     return (
         state.board.outside(x, y)
         or is_wall(state.board.get(x, y))
         or dist(state.player.pos, (x, y)) > state.max_range
         or is_door(state.board.get(x, y))
     )
Пример #2
0
def encode_wall(board: Board, index: int) -> int:
    val = 0b10000

    x, y = index_to_pos(index, board.side)
    neighs = [(x - 1, y), (x, y + 1), (x + 1, y), (x, y - 1)]

    for i, (x_, y_) in enumerate(neighs):
        if board.outside(x_, y_) or is_wall(board.get(x_, y_)):
            val = val | (1 << i)

    return int("{0:b}".format(val))
Пример #3
0
 def draw(self, state):
     offx, offy = 48, 48
     pyxel.rect(offx - 5, offy - 5, 42, 42, 7)
     pyxel.rect(offx - 4, offy - 4, 40, 40, 0)
     pyxel.rect(offx - 2, offy - 2, 36, 36, 5)
     for x, y in state.visited:
         col = 7
         v = state.board.get(x, y)
         if is_door(v):
             col = 8 if is_locked(v) else 4
         elif is_wall(v):
             col = 1
         elif is_active_tile(v):
             col = 12
         pyxel.pix(offx + x, offy + y, col)
     x, y = state.player.pos
     pyxel.pix(offx + x, offy + y, 11)
Пример #4
0
def encode_door(board: Board, index: int) -> int:
    x, y = index_to_pos(index, board.side)
    top = x, y - 1

    top_val = board.get(*top)

    if board.outside(*top):
        return 22

    elif is_wall(top_val):
        bin_str = str(top_val)
        if bin_str[4] == "0" and bin_str[2] == "1":
            return 21
        elif bin_str[4] == "1" and bin_str[2] == "1":
            return 22
        elif bin_str[2] == "0":
            return 23

    return 20
Пример #5
0
def amend_door(board: Board, room_index: int, door_fn) -> Board:
    nodes = list(range(len(board)))
    start = board.to_index(*room_anchor(room_index))
    target = board.entrance
    neighs = partial(board_neighbours, board, lambda x: not is_wall(x))
    path = extract_path(find_paths(nodes, start, neighs), target)

    for i in path:
        if is_door(board[i]):
            board[i] = door_fn(board[i])

            botx, boty = board.to_pos(i)
            boty += 1
            # might rencode floor below
            if is_empty(board.get(botx, boty)):
                i = board.to_index(botx, boty)
                floor = encode_floor(board, i)
                board.set(botx, boty, floor)

            return board

    return board
Пример #6
0
def encode_floor(board: Board, index: int) -> int:
    x, y = index_to_pos(index, board.side)
    top = x, y - 1

    top_val = board.get(*top)

    if board.outside(*top):
        return 32

    elif is_wall(top_val):
        bin_str = str(top_val)
        if bin_str[4] == "0" and bin_str[2] == "1":
            return 31
        elif bin_str[4] == "1" and bin_str[2] == "1":
            return 32
        elif bin_str[4] == "1" and bin_str[2] == "0":
            return 33
        elif bin_str[4] == "0" and bin_str[2] == "0":
            return 34

    elif top_val == 20:  # front door
        return 35

    return 30
Пример #7
0
def draw(state: State):
    pyxel.cls(0)

    non_walls = {
        0: (32, 16),
        30: (40, 24),
        31: (0, 24),
        32: (8, 24),
        33: (16, 24),
        34: (40, 16),
        35: (48, 8),
        40: (40, 32),
        41: (32, 32),
        42: (32, 32),
        43: (32, 32),
        20: (48, 0),
        21: (56, 16),
        22: (56, 8),
        23: (56, 0),
        25: (64, 0),
        26: (72, 16),
        27: (72, 8),
        28: (72, 0),
        66: (64, 16),  # UP
        99: (64, 24),  # DOWN
    }

    # draw in range
    for x, y in state.visible:
        # for i in range(len(state.board)):
        #     x, y = index_to_pos(i, state.board.side)
        if state.board.outside(x, y):
            continue
        v = state.board.get(x, y)
        x, y = state.to_cam_space((x, y))
        colors = WALLS if is_wall(v) else non_walls
        u_, v_ = colors[v]
        pyxel.blt(
            x * CELL_SIZE, y * CELL_SIZE, 0, u_, v_, CELL_SIZE, CELL_SIZE
        )

    # draw collectibles and stuff
    for item in state.level.items:
        if item.square not in state.visible:
            continue
        x, y = state.to_cam_space(item.square)
        pyxel.blt(x * CELL_SIZE, y * CELL_SIZE, 0, *item.sprite)

    x, y = state.to_cam_space(state.player.pos)
    sp = state.player.sprite
    pyxel.blt(
        x * CELL_SIZE - sp.center[0],
        y * CELL_SIZE - sp.center[1],
        0,
        *sp.uv,
        CELL_SIZE * state.player.orientation,
        CELL_SIZE,
        1,
    )

    enemies = sorted(state.enemies, key=lambda e: e.zindex)
    for enemy in enemies:
        if enemy.square not in state.visible:
            continue
        x, y = state.to_cam_space(enemy.pos)
        sp = enemy.sprite
        pyxel.blt(
            x * CELL_SIZE - sp.center[0],
            y * CELL_SIZE - sp.center[1],
            0,
            *sp.uv,
            enemy.sprite.size[0] * enemy.orientation,
            enemy.sprite.size[1],
            1,
        )

    for p in state.particles:
        p.draw(state)

    # Active Tool
    if state.active_tool is not None:
        state.active_tool.draw(state)

    if state.text_box is not None:
        state.text_box.draw(state)

    # HUD
    pyxel.rect(3, 3, 2 * state.player.pv, 7, 2)
    pyxel.rect(3, 3, 2 * state.player.pv, 5, 8)
    pyxel.rect(4, 4, 2 * state.player.pv - 2, 1, 14)
    pyxel.rectb(2, 2, 42, 8, 1)

    for i in range(state.player.keys):
        pyxel.blt(3 + i * 7, 12, 0, *ITEMS["key"])

    for i, flag in enumerate(
        ["wand", "teleport", "thunder", "armor", "tri", "triB", "triA"]
    ):
        if flag in state.player.flags:
            if flag in {"triA", "triB"} and "tri" in state.player.flags:
                continue
            pyxel.blt(117 - i * 8, 2, 0, *ITEMS[flag])

    # MENU
    menu_ = menu(state)
    if state.menu_index is not None:
        h = 4 + len(menu_) * 8
        pyxel.rect(40, 40, 48, h, 0)
        pyxel.rectb(40, 40, 48, h, 5)

        for i, (code, item, _) in enumerate(menu_):
            col = 5 if state.player.cooldown(code) else 7
            pyxel.text(50, 43 + i * 8, item, col)

        pyxel.blt(41, 42 + state.menu_index * 8, 0, *ITEMS["dot"])
        pyxel.rect(17, 121, 128, 7, 0)
        pyxel.text(19, 122, "X: Exit / C: Confirm", 7)
    elif state.text_box is not None:
        pyxel.text(3, 122, "X/C: Close", 7)
    else:
        pyxel.text(3, 122, "C: Menu", 7)
Пример #8
0
def player_action(state: State):
    if state.player.is_busy():
        return

    x, y = state.player.square
    _end = end_turn(state)

    if state.active_tool is not None:
        return state.active_tool.update(state, _end)
    elif pyxel.btnr(pyxel.KEY_X) and state.menu_index is not None:
        state.menu_index = None
        return
    elif pyxel.btnr(pyxel.KEY_C):
        if state.menu_index is None:
            state.menu_index = 0
            return
        else:
            menu_select = menu_item(state)
            if state.player.cooldown(menu_select[0]):
                return
            state.menu_index = None
            return menu_select[2](state)

    if state.menu_index is not None:
        return update_menu(state)

    elif pyxel.btn(pyxel.KEY_DOWN):
        delta = 0, 1
    elif pyxel.btn(pyxel.KEY_UP):
        delta = 0, -1
    elif pyxel.btn(pyxel.KEY_LEFT):
        delta = -1, 0
    elif pyxel.btn(pyxel.KEY_RIGHT):
        delta = 1, 0

    elif pyxel.btn(pyxel.KEY_SPACE):
        for _ in range(50):
            state.particles.append(Aura(_center(state.player.pos)))
        return
    else:
        return

    target = x + delta[0], y + delta[1]

    val = state.board.get(*target)
    entity = find_entity(state, *target)
    item = find_item(state, *target)

    if entity:
        a = state.player.attack(entity, _end)
        pyxel.play(3, 50)
        draw_damage(state, entity.pos, a, 12)
    elif item:
        item.interact(state)
        state.player.wait(FPS * 0.3, _end)
    elif can_walk(state.board, *target):

        def _change_level(val, caller):
            if val == 66:
                state.change_level(-1)
            elif val == 99:
                state.change_level(1)
            return _end(caller)

        if is_active_tile(val):
            state.player.move(*target, partial(_change_level, val))
        else:
            state.player.move(*target, _end)

    elif is_door(val):
        if is_locked(state.board.get(*target)):
            if state.player.keys:
                unlock_door(state, target)
                pyxel.play(3, 53)
            else:
                pyxel.play(3, 54)
        else:
            open_door(state, target)
            pyxel.play(3, 49)
        state.player.wait(FPS * 0.3, _end)
    elif is_wall(val) or state.board.outside(*target):
        state.player.bump_to(target, _end)

    elif is_hole(val):
        if can_teleport(state):
            target = tuple(sum(e) for e in zip(target, delta))
            for _ in range(50):
                state.particles.append(
                    Molecule(_center(state.player.pos), _center(target), TPV)
                )
            state.player.teleport(*target, _end, TPV)
        else:
            state.player.bump_to(target, _end)
    else:
        state.player.wait(FPS * 0.3, _end)