You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
98 lines
3.1 KiB
98 lines
3.1 KiB
2 years ago
|
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
|