diff --git a/squirrelbattle/display/display.py b/squirrelbattle/display/display.py index 9cc1456..949b7ea 100644 --- a/squirrelbattle/display/display.py +++ b/squirrelbattle/display/display.py @@ -15,6 +15,8 @@ class Display: height: int pad: Any + screen_lines: list = [] + def __init__(self, screen: Any, pack: Optional[TexturePack] = None): self.screen = screen self.pack = pack or TexturePack.get_pack("ascii") @@ -83,6 +85,14 @@ class Display: # Refresh the pad only if coordinates are valid pad.refresh(top_y, top_x, window_y, window_x, last_y, last_x) + height, width = self.pad.getmaxyx() + height = min(height, last_y - window_y + 1) + width = min(width, last_x - window_x + 1) + pad_str = "\n".join(pad.instr(y, top_x).decode("utf-8")[:-1] + for y in range(top_y, top_y + height)) + pad_str = self.truncate(pad_str, height, width) + Display.insert_message_in_screen(pad_str, window_y, window_x) + def display(self) -> None: raise NotImplementedError @@ -94,6 +104,42 @@ class Display: def cols(self) -> int: return curses.COLS if self.screen else 42 + @classmethod + def resize_screen_lines(cls, height: int, width: int) -> None: + cls.screen_lines = cls.screen_lines[:height] + cls.screen_lines += [width * " " + for _ in range(height - len(cls.screen_lines))] + for i in range(len(cls.screen_lines)): + cls.screen_lines[i] = cls.screen_lines[i][:width] + + @classmethod + def insert_message_in_screen(cls, message: str, y: int, x: int) -> None: + for i, line in enumerate(message.split("\n")): + if i + y <= len(cls.screen_lines): + line = line[:len(cls.screen_lines[i + y]) - x] + width = len(line) + tmp_width = 0 + true_line = "" + for c in line: + tmp_width += 1 + true_line += c + if c in TexturePack.SQUIRREL_PACK and c != " " and c != "█": + tmp_width += 1 + if tmp_width >= width: + break + line = true_line + cls.screen_lines[i + y] = cls.screen_lines[i + y][:x] + line + \ + cls.screen_lines[i + y][x + len(line):] + + @classmethod + def erase_screen_lines(cls) -> None: + cls.screen_lines = [" " * len(cls.screen_lines[i]) + for i in range(len(cls.screen_lines))] + + @classmethod + def print_screen(cls) -> str: + return "\n".join(cls.screen_lines) + class VerticalSplit(Display): diff --git a/squirrelbattle/display/display_manager.py b/squirrelbattle/display/display_manager.py index f7a0882..0dc9803 100644 --- a/squirrelbattle/display/display_manager.py +++ b/squirrelbattle/display/display_manager.py @@ -2,7 +2,7 @@ # SPDX-License-Identifier: GPL-3.0-or-later import curses -from squirrelbattle.display.display import VerticalSplit, HorizontalSplit +from squirrelbattle.display.display import VerticalSplit, HorizontalSplit, Display from squirrelbattle.display.mapdisplay import MapDisplay from squirrelbattle.display.messagedisplay import MessageDisplay from squirrelbattle.display.statsdisplay import StatsDisplay @@ -51,6 +51,9 @@ class DisplayManager: self.messagedisplay.update_message(self.game.message) def refresh(self) -> None: + self.resize_window() + Display.erase_screen_lines() + if self.game.state == GameMode.PLAY: # The map pad has already the good size self.mapdisplay.refresh(0, 0, self.rows * 4 // 5, @@ -77,13 +80,30 @@ class DisplayManager: y, x = (self.rows - height) // 2, (self.cols - width) // 2 self.messagedisplay.refresh(y, x, height, width) - self.resize_window() + with open("squirrel-battle.html", "w") as f: + f.write("\n\n\n\n" + "
\n") + f.write("\n") + for line in Display.print_screen().split("\n"): + f.write("") + for c in line: + if c in TexturePack.SQUIRREL_PACK.PLAYER and c != TexturePack.SQUIRREL_PACK.PLAYER[0] and c != " ": + continue + squirrel_pack = TexturePack.SQUIRREL_PACK + width = 2 if c in squirrel_pack and c != " " and c != "█" else 1 + f.write(f"") + f.write("") + f.write("\n
{c}
\n
\n\n\n") def resize_window(self) -> bool: """ If the window got resized, ensure that the screen size got updated. """ y, x = self.screen.getmaxyx() if self.screen else (0, 0) + Display.resize_screen_lines(y, x) if self.screen and curses.is_term_resized(self.rows, self.cols): # pragma: nocover curses.resizeterm(y, x) diff --git a/squirrelbattle/display/texturepack.py b/squirrelbattle/display/texturepack.py index dfee866..cc2f468 100644 --- a/squirrelbattle/display/texturepack.py +++ b/squirrelbattle/display/texturepack.py @@ -18,6 +18,12 @@ class TexturePack: WALL: str FLOOR: str PLAYER: str + HEDGEHOG: str + HEART: str + BOMB: str + RABBIT: str + TIGER: str + TEDDY_BEAR: str ASCII_PACK: "TexturePack" SQUIRREL_PACK: "TexturePack" @@ -30,6 +36,9 @@ class TexturePack: def __getitem__(self, item: str) -> Any: return self.__dict__[item] + def __contains__(self, item) -> bool: + return any(self[key] == item for key in self.__dict__ if key.isupper()) + @classmethod def get_pack(cls, name: str) -> "TexturePack": return cls._packs[name.lower()]