Exemple #1
0
def read_level(filename, w, h, types, bonuses):
    """
    Gets level information from file and returns new level based on it

    w, h - level size
    types - amount of each type of ball
    """
    with open(filename, 'r') as f:
        data = json.load(f)
        name = data.get('Name')
        amount = data.get('Amount')
        radius = data.get('Raduis')
        ball_speed = data.get('BallSpeed')
        bull_speed = data.get('BulletSpeed')
        tex_prefix = data.get('TexturesPrefix')
        points = [(i[0], i[1]) for i in data.get('Checkpoints')]
        highscores = data.get('Highscores')
        pos = data.get('PlayerPos')
        player_pos = (pos[0], pos[1])
        while len(highscores) < 5:
            highscores.append(0)
        return Level(name, w, h, types, points, amount, radius, ball_speed,
                     player_pos, 3, bull_speed, tex_prefix, highscores,
                     bonuses)
def load_level(filename) -> Level:
    with open(filename, "rb") as f:
        board, palette = pickle.load(f)
    
    return Level(board, palette)


test_board = Board({
    (1, 3): [ResourceTile(Color.RED)],
    (3, 0): [Boostpad(Direction.WEST)],
    (-5, 9): [ResourceTile(Color.BLUE)],
    (-5, -3): [Target(Color.VIOLET, 5)],
})

test_palette = Palette([
    (EntityPrototype(ResourceExtractor), 2),
    (EntityPrototype(Boostpad), 1),
])

test_level = Level(test_board, test_palette)


# a, b = choice(list(Color)), choice(list(Color))
a, b = Color.RED, Color.BLUE

test_board2 = Board({
    (-3, 0): [ResourceTile(a), ResourceExtractor(Direction.EAST)],
    (3, 0): [ResourceTile(b), ResourceExtractor(Direction.WEST)],
    (0, 0): [Boostpad(Direction.NORTH)],
    (5, -8): [Target(a + b, 10)],
    (5, -5): [Piston()],
    (7, -7): [Piston()],
    (10, -7): [Piston()],
    # (5, -6): [Barrel(Color.YELLOW)],
    # (5, -7): [Barrel(Color.BLUE)],
title_menu = TitleMenu(
    name="TITLE",
    titles={
        "en": "Tomb Raider",
        "de": "Tomb Raider",
    },
    track=TR1TrackId.MainTheme,
    secrets=0,
)

lara_home = Level(
    name="GYM",
    titles={
        "en": "Lara's home",
        "de": "Laras Haus",
    },
    track=TR1TrackId.Ambience1,
    secrets=0,
    use_alternative_lara=True,
)

level_sequence = [
    Video("SNOW.RPL"),
    Level(
        name="LEVEL1",
        titles={
            "en": "Caves",
            "de": "Die Kavernen",
        },
        track=TR1TrackId.Ambience1,
        secrets=3,
Exemple #5
0
from engine import Board, Level, Palette
from entities import *
from level_helpers import disk, random_flood


level_1 = Level(
    Board({
        **random_flood((0, 0), 10, ResourceTile(Color.BLUE)),
        (12, 0): [Target(Color.BLUE, count=10)],
    }),
    Palette([
        (EntityPrototype(ResourceExtractor), 1)
    ]),
    name="Level 1"
)


level_2 = Level(
    Board({
        **random_flood((0, 0), 10, ResourceTile(Color.RED)),
        (8, 8): [Target(Color.RED, count=10)],
    }),
    Palette([
        (EntityPrototype(ResourceExtractor), 1),
        (EntityPrototype(Boostpad), 1),
    ]),
    name="Level 2"
)


level_3 = Level(
def run_editor(board=None):
    level_filename = None

    board_width, board_height = None, None
    root_viewport_rect, main_viewport_rect, palette_viewport_rect = None, None, None

    # initialize screen; VIDEORESIZE event is generated immediately
    screen = get_initialized_screen(STARTING_SCREEN_WIDTH,
                                    STARTING_SCREEN_HEIGHT)
    board_layer_cache = None

    if board is None:
        board = [[[] for _ in range(BOARD_DEFAULT_DIMS[0])]
                 for _ in range(BOARD_DEFAULT_DIMS[1])]

    selected_entity = None

    key_mods = pygame.key.get_mods()

    board_save_state = board_copy(board)

    playtest_process = None

    # discard selected entity and update screen (if CAPS-LOCK is not enabled)
    def discard_selected_item():
        nonlocal selected_entity
        nonlocal root_viewport_rect, main_viewport_rect, palette_viewport_rect
        if selected_entity:
            if not key_mods & pygame.KMOD_CAPS:
                # discard selected entity
                selected_entity = None
                update_screen(screen, board, main_viewport_rect,
                              palette_viewport_rect)
            else:
                # keep selected entity
                update_screen(screen,
                              board,
                              main_viewport_rect,
                              palette_viewport_rect,
                              redraw_board=True,
                              selected_entity=selected_entity,
                              cursor_position=event.pos)

    # recalculate board dimensions, recalculate viewports, and update screen
    def refresh_layout():
        nonlocal board_width, board_height
        board_width, board_height = len(board[0]), len(board)

        nonlocal root_viewport_rect, main_viewport_rect, palette_viewport_rect
        root_viewport_rect, main_viewport_rect, palette_viewport_rect =\
            get_viewport_rects(new_screen_width, new_screen_height, board_width, board_height)
        update_screen(screen, board, main_viewport_rect, palette_viewport_rect)

    # update window caption based off level_filename
    def refresh_caption():
        if level_filename:
            caption = level_filename
        else:
            caption = "~ Unsaved Level ~"
        pygame.display.set_caption(caption)

    refresh_caption()

    # main game loop
    clock = pygame.time.Clock()
    editor_alive = True
    while editor_alive:
        clock.tick(TARGET_FPS)

        # process input
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                if board_save_state != board:
                    # if board_save_state is None or any(any(row) for row in board):
                    if not ask_yes_no(
                            "Level Editor",
                            "You have unsaved work. Are you sure you want to quit?"
                    ):
                        continue
                editor_alive = False

            elif event.type == pygame.VIDEORESIZE:
                new_screen_width = max(event.w, MIN_SCREEN_WIDTH)
                new_screen_height = max(event.h, MIN_SCREEN_HEIGHT)
                screen = get_initialized_screen(new_screen_width,
                                                new_screen_height)
                refresh_layout()

            elif event.type == pygame.MOUSEBUTTONDOWN:
                if event.button == 1:
                    # handle main viewport clicks
                    if main_viewport_rect.collidepoint(event.pos):
                        x_tiles, y_tiles = pixels_to_tiles(
                            *event.pos, main_viewport_rect, board_width,
                            board_height)
                        clicked_tile = board[y_tiles][x_tiles]
                        if selected_entity is None:
                            # select an entity and redraw
                            if len(clicked_tile) > 0:
                                selected_entity = clicked_tile.pop(
                                )  # remove top entity
                                update_screen(screen,
                                              board,
                                              main_viewport_rect,
                                              palette_viewport_rect,
                                              redraw_board=True,
                                              selected_entity=selected_entity,
                                              cursor_position=event.pos)

                        else:
                            # deselect the entity and redraw
                            clicked_tile.append(selected_entity)
                            discard_selected_item()

                    # handle palette viewport clicks
                    elif palette_viewport_rect.collidepoint(event.pos):
                        if selected_entity:
                            selected_entity = None
                            update_screen(screen, board, main_viewport_rect,
                                          palette_viewport_rect)
                        else:
                            x_tiles, y_tiles = pixels_to_tiles_palette(
                                *event.pos, palette_viewport_rect,
                                PALETTE_WIDTH, PALETTE_HEIGHT)
                            choice = PALETTE_LAYOUT[y_tiles][x_tiles]
                            selected_entity = choice
                            update_screen(screen,
                                          board,
                                          main_viewport_rect,
                                          palette_viewport_rect,
                                          redraw_board=True,
                                          selected_entity=selected_entity,
                                          cursor_position=event.pos)

                    # handle background clicks (i.e. no viewports)
                    else:
                        discard_selected_item()

                elif event.button == 3:
                    discard_selected_item()

            elif event.type == pygame.MOUSEMOTION:
                if selected_entity:
                    if root_viewport_rect.collidepoint(event.pos):
                        update_screen(screen,
                                      board,
                                      main_viewport_rect,
                                      palette_viewport_rect,
                                      redraw_board=False,
                                      selected_entity=selected_entity,
                                      cursor_position=event.pos)

            elif event.type == pygame.KEYDOWN:
                key_mods = pygame.key.get_mods()

                # handle board size changes
                board_size_changed = False
                decreasing = key_mods & pygame.KMOD_SHIFT
                increasing = not decreasing
                # # format (x, y, delta)
                # size_delta = [0, 0, 0]  # one of (0,0,0), (-1,0,1),  (1,0,1),  (0,-1,1),  (0,1,1),
                #                         #                 (-1,0,-1), (1,0,-1), (0,-1,-1), (0,1,-1)
                if event.key == pygame.K_UP:
                    if increasing and board_height < BOARD_HEIGHT_RANGE[1]:
                        board.insert(0, [[] for _ in range(board_width)])
                        board_size_changed = True
                    elif decreasing and board_height > BOARD_HEIGHT_RANGE[0]:
                        board.pop(0)
                        board_size_changed = True
                elif event.key == pygame.K_DOWN:
                    if increasing and board_height < BOARD_HEIGHT_RANGE[1]:
                        board.append([[] for _ in range(board_width)])
                        board_size_changed = True
                    elif decreasing and board_height > BOARD_HEIGHT_RANGE[0]:
                        board.pop()
                        board_size_changed = True
                elif event.key == pygame.K_RIGHT:
                    if increasing and board_width < BOARD_WIDTH_RANGE[1]:
                        for row in board:
                            row.append([])
                        board_size_changed = True
                    elif decreasing and board_height > BOARD_WIDTH_RANGE[0]:
                        for row in board:
                            row.pop()
                        board_size_changed = True
                elif event.key == pygame.K_LEFT:
                    if increasing and board_width < BOARD_WIDTH_RANGE[1]:
                        for row in board:
                            row.insert(0, [])
                        board_size_changed = True
                    elif decreasing and board_height > BOARD_WIDTH_RANGE[0]:
                        for row in board:
                            row.pop()
                        board_size_changed = True

                if board_size_changed:
                    refresh_layout()

                # handle keyboard shortcuts
                if key_mods & pygame.KMOD_CTRL:
                    if event.key == pygame.K_o:
                        # Open
                        if board_save_state != board:
                            if not ask_yes_no(
                                    "Level Editor",
                                    "You have unsaved work that will be overwitten by opening another level. Are you sure you want to continue?"
                            ):
                                continue
                        if res := ask_open_filename(**FILE_DIALOG_OPTIONS):
                            level_filename = res
                            board = read_level(level_filename)
                            board_save_state = board_copy(board)
                            refresh_layout()
                            refresh_caption()
                            print(f"opened {level_filename}")

                    elif event.key == pygame.K_s:
                        if key_mods & pygame.KMOD_SHIFT:
                            # Save as
                            if res := ask_save_as_filename(
                                    **FILE_DIALOG_OPTIONS):
                                level_filename = res
                                write_level(level_filename, board)
                                board_save_state = board_copy(board)
                                refresh_caption()
                                print(f"saved to {level_filename}")
                        else:
                            # Save
                            if level_filename is None:
                                if res := ask_save_as_filename(
                                        **FILE_DIALOG_OPTIONS):
                                    level_filename = res
                            if level_filename:
                                write_level(level_filename, board)
                                board_save_state = board_copy(board)
                                refresh_caption()
                                print(f"saved to {level_filename}")

                elif event.key == pygame.K_SPACE:
                    # spawn a new process running play_level (can only have one alive at a time)
                    if playtest_process is None or not playtest_process.is_alive(
                    ):
                        playtest_process = Process(target=play_level,
                                                   args=(Level(
                                                       board_copy(board),
                                                       logging=False), ))
                        playtest_process.start()
Exemple #7
0
                if event.key == currently_pressed:
                    currently_pressed = None
                    repeating_inputs = False
            elif event.type == pygame.VIDEORESIZE:
                new_screen_width = max(event.w, MIN_SCREEN_WIDTH)
                new_screen_height = max(event.h, MIN_SCREEN_HEIGHT)
                screen = get_initialized_screen(new_screen_width, new_screen_height)
                pygame.display.update()
                viewport_rect = get_viewport_rect(new_screen_width, new_screen_height, level.width, level.height)
                update_screen(screen, level, viewport_rect)

        if currently_pressed is not None:
            current_timestamp = pygame.time.get_ticks()

            if current_timestamp - last_input_timestamp > INPUT_REPEAT_BUFFER_MS:
                repeating_inputs = True

            if repeating_inputs and current_timestamp - last_input_timestamp > INPUT_REPEAT_PERIOD_MS:
                process_keypress(event.key)

        if level.has_won:
            print("\nCongrats! You beat the level!")
            pygame.time.wait(1000)
            level_alive = False


if __name__ == "__main__":
    # load a test level (with logging disabled)
    test_level = Level(levels[2], logging=False)
    play_level(test_level)
Exemple #8
0
title_menu = TitleMenu(
    name="DATA/TITLE.PHD",
    titles={
        "en_GB": "Tomb Raider",
        "de_DE": "Tomb Raider",
    },
    track=TR1TrackId.MainTheme,
)

lara_home = [
    Video("FMV/MANSION.RPL"),
    Level(
        name="DATA/GYM.PHD",
        titles={
            "en_GB": "Lara's home",
            "de_DE": "Laras Haus",
        },
        secrets=0,
        use_alternative_lara=True,
        allow_save=False,
    ),
]

level_sequence = [
    Video("FMV/SNOW.RPL"),
    ModifyInventory(
        add_inventory={TR1ItemId.Pistols: 1},
    ),
    Level(
        name="DATA/LEVEL1.PHD",
        titles={
            "en_GB": "Caves",