import os from graphics.colors import Colors class Screen: """Moteur graphique basé sur des claques""" instance = None def __init__(self, game): Screen.instance = self size = os.get_terminal_size() if size.columns < 120 or size.lines < 30: raise OSError("terminal is too small") self.x = size.columns self.y = size.lines - 2 self.frame = {} self.__layers = {} self.handlers = [] game.late_init() self.game = game def set_layer(self, layer): self.__layers[layer.name] = layer def del_layer(self, name): del self.__layers[name] def get_layer(self, name): if not name in self.__layers.keys(): raise ValueError("unknown key") return self.__layers[name] def __combine_layers(self): self.frame = {} layers = sorted(self.__layers.values(), key=lambda layer: layer.z_index) for layer in layers: layer.draw() self.frame.update(layer.frame) def draw(self): self.__combine_layers() buffer = "" for y in range(self.y): for x in range(self.x): if (x, y) in self.frame: buffer += self.frame[(x, y)] else: buffer += " " buffer += "\n" print("\033[H\033[J", end="") print(buffer) def send_key(self, key): """Envoie les touches reçues à tous les calques actifs""" for layer in list(self.__layers.values()): if layer.handle_keys == True: layer.key_handler(key) class Layer: def __init__(self, z_index, name): self.name = name self.frame = {} self.z_index = z_index self.x = Screen.instance.x self.y = Screen.instance.y self.handle_keys = True Screen.instance.set_layer(self) def put_char(self, char, x, y, colors=[]): if x > self.x or x < 0 or y > self.y or y < 0: raise ValueError("out of range pixel") self.frame[(x, y)] = "".join(colors) + char + Colors.RESET def put_string(self, string, x, y, colors=[]): if x > self.x or x < 0 or y > self.y or y < 0: raise ValueError("out of range pixel") string = string.split("\n") for string_y in range(len(string)): for string_x in range(len(string[string_y])): self.frame[(x+string_x, y+string_y)] = "".join(colors) + string[string_y][string_x] + Colors.RESET def rect(self, x1, y1, x2, y2, colors=[], template=' '): if (x1 > self.x or x1 < 0 or y1 > self.y or y1 < 0) or (x2 > self.x or x2 < 0 or y2 > self.y or y2 < 0): raise ValueError("out of range pixel") if len(template) > 1: raise ValueError("template should be 1 char long") for x in range(x1, x2+1): for y in range(y1, y2+1): self.frame[(x, y)] = "".join(colors) + template + Colors.RESET def draw(self): self.frame = {} def key_handler(self): pass