From ad0f7c6c7b5c204fd0ebbddc57e05079e93a9530 Mon Sep 17 00:00:00 2001 From: Christian Heller Date: Thu, 3 Dec 2020 01:07:57 +0100 Subject: [PATCH] In curses client, eliminate lag flickering. --- rogue_chat_curses.py | 113 ++++++++++++++++++++++--------------------- 1 file changed, 58 insertions(+), 55 deletions(-) diff --git a/rogue_chat_curses.py b/rogue_chat_curses.py index 127c989..2783e24 100755 --- a/rogue_chat_curses.py +++ b/rogue_chat_curses.py @@ -464,6 +464,8 @@ class TUI: self.input_lines = [] self.fov = '' self.flash = False + self.map_lines = [] + self.offset = YX(0,0) curses.wrapper(self.loop) def connect(self): @@ -760,64 +762,65 @@ class TUI: 'MODE: %s – %s' % (self.mode.short_desc, help)) def draw_map(): - if not self.game.turn_complete: + if not self.game.turn_complete and len(self.map_lines) == 0: return - map_lines_split = [] - for y in range(self.game.map_geometry.size.y): - start = self.game.map_geometry.size.x * y - end = start + self.game.map_geometry.size.x - if self.map_mode == 'protections': - map_lines_split += [[c + ' ' for c - in self.game.map_control_content[start:end]]] + if self.game.turn_complete: + map_lines_split = [] + for y in range(self.game.map_geometry.size.y): + start = self.game.map_geometry.size.x * y + end = start + self.game.map_geometry.size.x + if self.map_mode == 'protections': + map_lines_split += [[c + ' ' for c + in self.game.map_control_content[start:end]]] + else: + map_lines_split += [[c + ' ' for c + in self.game.map_content[start:end]]] + if self.map_mode == 'terrain + annotations': + for p in self.game.info_hints: + map_lines_split[p.y][p.x] = 'A ' + elif self.map_mode == 'terrain + things': + for p in self.game.portals.keys(): + original = map_lines_split[p.y][p.x] + map_lines_split[p.y][p.x] = original[0] + 'P' + used_positions = [] + for t in self.game.things: + symbol = self.game.thing_types[t.type_] + meta_char = ' ' + if hasattr(t, 'thing_char'): + meta_char = t.thing_char + if t.position in used_positions: + meta_char = '+' + map_lines_split[t.position.y][t.position.x] = symbol + meta_char + used_positions += [t.position] + player = self.game.get_thing(self.game.player_id) + if self.mode.shows_info or self.mode.name == 'control_tile_draw': + map_lines_split[self.explorer.y][self.explorer.x] = '??' + elif self.map_mode != 'terrain + things': + map_lines_split[player.position.y][player.position.x] = '??' + self.map_lines = [] + if type(self.game.map_geometry) == MapGeometryHex: + indent = 0 + for line in map_lines_split: + self.map_lines += [indent * ' ' + ''.join(line)] + indent = 0 if indent else 1 else: - map_lines_split += [[c + ' ' for c - in self.game.map_content[start:end]]] - if self.map_mode == 'terrain + annotations': - for p in self.game.info_hints: - map_lines_split[p.y][p.x] = 'A ' - elif self.map_mode == 'terrain + things': - for p in self.game.portals.keys(): - original = map_lines_split[p.y][p.x] - map_lines_split[p.y][p.x] = original[0] + 'P' - used_positions = [] - for t in self.game.things: - symbol = self.game.thing_types[t.type_] - meta_char = ' ' - if hasattr(t, 'thing_char'): - meta_char = t.thing_char - if t.position in used_positions: - meta_char = '+' - map_lines_split[t.position.y][t.position.x] = symbol + meta_char - used_positions += [t.position] - player = self.game.get_thing(self.game.player_id) - if self.mode.shows_info or self.mode.name == 'control_tile_draw': - map_lines_split[self.explorer.y][self.explorer.x] = '??' - elif self.map_mode != 'terrain + things': - map_lines_split[player.position.y][player.position.x] = '??' - map_lines = [] - if type(self.game.map_geometry) == MapGeometryHex: - indent = 0 - for line in map_lines_split: - map_lines += [indent * ' ' + ''.join(line)] - indent = 0 if indent else 1 - else: - for line in map_lines_split: - map_lines += [''.join(line)] - window_center = YX(int(self.size.y / 2), - int(self.window_width / 2)) - center = player.position - if self.mode.shows_info or self.mode.name == 'control_tile_draw': - center = self.explorer - center = YX(center.y, center.x * 2) - offset = center - window_center - if type(self.game.map_geometry) == MapGeometryHex and offset.y % 2: - offset += YX(0, 1) - term_y = max(0, -offset.y) - term_x = max(0, -offset.x) - map_y = max(0, offset.y) - map_x = max(0, offset.x) + for line in map_lines_split: + self.map_lines += [''.join(line)] + window_center = YX(int(self.size.y / 2), + int(self.window_width / 2)) + center = player.position + if self.mode.shows_info or self.mode.name == 'control_tile_draw': + center = self.explorer + center = YX(center.y, center.x * 2) + self.offset = center - window_center + if type(self.game.map_geometry) == MapGeometryHex and self.offset.y % 2: + self.offset += YX(0, 1) + term_y = max(0, -self.offset.y) + term_x = max(0, -self.offset.x) + map_y = max(0, self.offset.y) + map_x = max(0, self.offset.x) while (term_y < self.size.y and map_y < self.game.map_geometry.size.y): - to_draw = map_lines[map_y][map_x:self.window_width + offset.x] + to_draw = self.map_lines[map_y][map_x:self.window_width + self.offset.x] safe_addstr(term_y, term_x, to_draw) term_y += 1 map_y += 1 -- 2.30.2