From bb493f6de4e26fa24a23d14da69dbfa34666acd6 Mon Sep 17 00:00:00 2001 From: nfx Date: Thu, 19 Dec 2024 15:29:52 +0100 Subject: [PATCH] Supprimer 'dev_edit.py' --- dev_edit.py | 274 ---------------------------------------------------- 1 file changed, 274 deletions(-) delete mode 100644 dev_edit.py diff --git a/dev_edit.py b/dev_edit.py deleted file mode 100644 index fa209c0..0000000 --- a/dev_edit.py +++ /dev/null @@ -1,274 +0,0 @@ -""" - LEVEL EDITOR(prototype) - The file that allows to create and edit levels - THIS PROGRAM IS DEPRECATED, USE LVL_EDIT.PY TO EDIT LEVELS -""" -import pyxel -import json -import shutil - -CELL_SIZE = 20 -GRID_X = 11 -GRID_Y = 6 - -WIN_X = CELL_SIZE*GRID_X -WIN_Y = CELL_SIZE*GRID_Y - - -def clamp(n: int, a: int, b: int): - """ - :param n: The number to be clamped - :param a: The minimum limit - :param b: The maximum limit - :return: The clamped number - Returns the provided number n clamped between a and b - """ - if n < a: - return a - if n > b: - return b - return n - - -def get_file_content(lvl: int) -> list: - """ - :param lvl: (int) The id of the file to read - :return: (list) The level content of the file - Reads a level file content and returns its data - """ - file = open(f"lvl/{lvl}.json", "r", encoding="utf-8") - decoder = json.JSONDecoder() - content = decoder.decode(file.read()) - file.close() - return content - - -def can_load(lvl: int) -> bool: - """ - :param lvl: (int) The id of the file to check for - :return: Returns if the level file exists and can be loaded - """ - try: - file = get_file_content(lvl) - return len(file) == GRID_Y - except FileNotFoundError: - return False - - -class LevelManager: - def __init__(self): - self.level = 0 # the id of the currently loaded stage - self.cache = [] # the current stage state is stored there - - self.tileTypes = { # helps with tile identifiers - "empty": 0, - "wall": 1, - "player": 3, - "exit": 2, - "switch_blue": 4, - "s_wall_blue": 5 - } - - def load(self, lvl: int): - """ - :param lvl: (int) the level id - - Reloads the game using the specified level - """ - self.level = lvl - self.cache = get_file_content(lvl) - - def save(self, lvl: int): - """ - :param lvl: (int) the level id - - Saves the cache under the specified level id - """ - file = open(f"lvl/{lvl}.json", "w", encoding="utf-8") - encoder = json.JSONEncoder() - file.write(encoder.encode(self.cache)) - file.close() - - def update_tile(self, position: tuple[int, int], val: int): - """ - :param position: (tuple) The position of the tile to modify - :param val: (int) The new value of the tile - - Updates the specified tile from the cache to the specified value - """ - self.cache[position[1]][position[0]] = val - - def get_tile(self, position: tuple[int, int]) -> int: - """ - :param position: (tuple) the position of the requested tile - :return: (int) the value of the tile - Fetches the current value of the specified tile or -1 if out of range - """ - if not self.is_in_range(position): - return -1 - return self.cache[position[1]][position[0]] - - def is_in_range(self, position: tuple[int, int]) -> bool: - """ - :param position: (tuple) The position that will be checked - :return: (bool) indicates whether the said position is in map bounds - - Checks if the given position is within the map range(a level should have been loaded first) - """ - if len(self.cache) == 0: - return False - if position[0] < 0 or position[1] < 0: - return False - if position[1] > GRID_Y-1: - return False - if position[0] > GRID_X-1: - return False - return True - - def move_tile(self, tile_a, tile_b): - """ - :param tile_a: (tuple) The position of the tile to be moved - :param tile_b: (tuple) The position of the target tile - Moves the content of tile_a to tile_b(overwrites tile_b and sets tile_a to 0) - This is meant for player movement - """ - if tile_a != tile_b: - content = self.get_tile(tile_a) - self.update_tile(tile_b, content) - self.update_tile(tile_a, self.tileTypes['empty']) - - def find_object(self, elt: int) -> tuple[int, int]: - """ - :param elt: (int) The type of element to find on the map(use self.tileTypes) - :return: (tuple) The position of the tile(or (-1, -1) if not found) - Finds the first instance of the provided element on the board, and returns its position - """ - for y in range(GRID_Y): - for x in range(GRID_X): - if self.cache[y][x] == elt: - return x, y - return -1, -1 - - def find_player(self): # finds the player in the stage grid and returns its coordinates - return self.find_object(self.tileTypes['player']) - - -def input_cmd(): - cmd_txt = input("cmd => ").split(" ") - if cmd_txt[0] == "load" and len(cmd_txt) > 1 and cmd_txt[1].isnumeric() and can_load(int(cmd_txt[1])): - print(f"Now editing level {cmd_txt[1]}") - runner.level.load(int(cmd_txt[1])) - elif cmd_txt[0] == "create" and len(cmd_txt) > 1 and cmd_txt[1].isnumeric(): - print(f"Now editing level {cmd_txt[1]}") - shutil.copyfile("lvl_template.json", f'lvl/{cmd_txt[1]}.json') - runner.level.load(int(cmd_txt[1])) - elif cmd_txt[0] == "save": - runner.level.save(runner.level.level) - print(f"Saved successfully") - else: - print("Invalid Command") - - -class Editor: - def __init__(self): - self.level = LevelManager() # An instance that manages level data and navigating - self.isInit = False # Safety attribute that prevents init from running twice - self.cursor = (0, 0) # Describes the mouse position(snapped to grid) - self.toolToggle = 0 - - self.toolToggleRotation = [ - self.level.tileTypes['wall'], - self.level.tileTypes['exit'], - self.level.tileTypes['switch_blue'], - self.level.tileTypes['s_wall_blue'] - ] - - self.element_display = [ - "empty", - "wall", - "exit", - "player", - "blue switch", - "blue switch wall" - ] - - def on_click(self): # toggles the presence of an element at cursor position - tile = self.level.get_tile(self.cursor) - if tile != self.toolToggleRotation[self.toolToggle] and tile != self.level.tileTypes['player']: - self.level.update_tile(self.cursor, self.toolToggleRotation[self.toolToggle]) - elif tile != self.level.tileTypes['player']: - self.level.update_tile(self.cursor, self.level.tileTypes['empty']) - - def move_player(self): # moves the player to the cursor(overwrites said tile) - if self.cursor[0] >= 0 and self.cursor[1] >= 0: - plr_pos = self.level.find_player() - self.level.move_tile(plr_pos, self.cursor) - - def tool_rotation(self): # Changes the element that will be placed on click - next_index = self.toolToggle + 1 - if next_index >= len(self.toolToggleRotation): - self.toolToggle = 0 - else: - self.toolToggle = next_index - new_element = self.toolToggleRotation[self.toolToggle] - print(f"Now placing {self.element_display[new_element]}") - - # manages controls and tools - def upd(self): - mx, my = pyxel.mouse_x, pyxel.mouse_y - self.cursor = (mx//CELL_SIZE, my//CELL_SIZE) - if pyxel.btnp(pyxel.MOUSE_BUTTON_LEFT): - self.on_click() - elif pyxel.btnp(pyxel.KEY_E): - self.move_player() - elif pyxel.btnp(pyxel.KEY_A): - self.tool_rotation() - elif pyxel.btnp(pyxel.KEY_C): - input_cmd() - - # utility methods that draws the cursor to the mouse position - def draw_cursor(self): - x, y = self.cursor - center_x = x*CELL_SIZE+CELL_SIZE//2 - center_y = y*CELL_SIZE+CELL_SIZE//2 - pyxel.circb(center_x, center_y, 5, 4) - - # self-explanatory, manages what's seen on screen - def display(self): - pyxel.cls(0) - for y in range(GRID_Y): - for x in range(GRID_X): - tile = self.level.get_tile((x, y)) - if tile == self.level.tileTypes['wall']: - pyxel.rect(x*CELL_SIZE, y*CELL_SIZE, CELL_SIZE, CELL_SIZE, 7) - elif tile == self.level.tileTypes['exit']: - pyxel.rect(x*CELL_SIZE, y*CELL_SIZE, CELL_SIZE, CELL_SIZE, 11) - elif tile == self.level.tileTypes['player']: - pyxel.circ(x*CELL_SIZE+CELL_SIZE//2, y*CELL_SIZE+CELL_SIZE//2, CELL_SIZE//2-1, 8) - elif tile == self.level.tileTypes['switch_blue']: - pyxel.circ(x*CELL_SIZE+CELL_SIZE//2, y*CELL_SIZE+CELL_SIZE//2, CELL_SIZE//3-1, 12) - elif tile == self.level.tileTypes['s_wall_blue']: - pyxel.rect(x * CELL_SIZE, y * CELL_SIZE, CELL_SIZE, CELL_SIZE, 12) - self.draw_cursor() - - def init(self, lvl: int): # opens the editor window and loads the specified stage - if not self.isInit: - self.isInit = True - self.level.load(lvl) - pyxel.init(WIN_X, WIN_Y, title="ice_walker editor") - pyxel.mouse(True) - pyxel.run(self.upd, self.display) - - -def start_editor(): - runner.init(int(lvl_id)) - - -if __name__ == "__main__": - lvl_id = input("Please enter the id of the level to load: ") - if lvl_id.isnumeric(): - print(f"Now editing level {lvl_id}") - runner = Editor() - start_editor() - else: - print("Invalid level id provided, please rerun and try again")