From 938a88862378955a21c52c2077bf235ebb03cafd Mon Sep 17 00:00:00 2001 From: HSMarieK Date: Mon, 30 Mar 2026 19:03:48 +0200 Subject: [PATCH 01/14] minimap_and_minor_refactoring --- lineflow/simulation/visualization.py | 92 ++++++++++++++++++++-------- 1 file changed, 66 insertions(+), 26 deletions(-) diff --git a/lineflow/simulation/visualization.py b/lineflow/simulation/visualization.py index 94204a8..0890d4b 100644 --- a/lineflow/simulation/visualization.py +++ b/lineflow/simulation/visualization.py @@ -19,17 +19,21 @@ def __init__( if size is None: size = (1280, 720) - self.size = size - if viewpoint is None: - viewpoint = (0, 0, 1) - self.viewpoint = pygame.Vector3(viewpoint) - self.view = pygame.Vector2(self.viewpoint.x, self.viewpoint.y) + self.size = pygame.Vector2(size) + + if viewpoint is not None: + self.viewpoint = pygame.Vector3(viewpoint) + else: + self.viewpoint = viewpoint + + if self.viewpoint is not None: + self.view = pygame.Vector2(self.viewpoint.x, self.viewpoint.y) self.connection = connection self.stop_event = stop_event self.halt_event = halt_event - self.center = pygame.Vector2(self.size[0]/2, self.size[1]/2) + self.center = pygame.Vector2(self.size.x/2, self.size.y/2) self.stations = [] self.connectors = [] @@ -39,7 +43,8 @@ def __init__( self.connection_data = [] self.initial_view_data = False - self.has_set_initial_view = False + + self.show_minimap = True def set_initial_viewpoint(self): x_positions = [] @@ -49,17 +54,21 @@ def set_initial_viewpoint(self): y_positions.append(station['position'].y) line_width = max(x_positions)-min(x_positions) line_height = max(y_positions)-min(y_positions) - line_center = pygame.Vector2(min(x_positions)+line_width/2,min(y_positions)+line_height/2) - self.viewpoint.x = -line_center.x - self.viewpoint.y = -line_center.y - x_scalar = line_width / (self.size[0]-100) - y_scalar = line_height / (self.size[1]-100) + line_center = pygame.Vector2( + min(x_positions)+line_width/2, + min(y_positions)+line_height/2 + ) + x = -line_center.x + y = -line_center.y + x_scalar = line_width / (self.size.x-100) + y_scalar = line_height / (self.size.y-100) scalar = max(x_scalar,y_scalar) if scalar < 1: - self.viewpoint.z = 1 + z = 1 else: - self.viewpoint.z = round(scalar,1) - self.has_set_initial_view = True + z = round(scalar,1) + self.viewpoint = pygame.Vector3(x, y, z) + self.view = pygame.Vector2(x, y) def clear(self): self.screen.fill('white') @@ -68,7 +77,7 @@ def get_from_connection(self): while True: try: self.connection_data = self.connection.get_nowait() - if not self.has_set_initial_view: + if self.viewpoint is None: self.initial_view_data = True except Empty: break @@ -260,7 +269,7 @@ def draw_user_input(self): 'black', 'white' ) - self.screen.blit(text,text.get_rect(left=50,top=self.size[1]-40)) + self.screen.blit(text,text.get_rect(left=50,top=self.size.y-40)) def draw_loading(self): font = pygame.font.SysFont(None, 48) @@ -274,6 +283,32 @@ def draw_shutdown(self): def draw_cursor(self): pygame.draw.circle(self.screen, 'blue', self.center, 10, 1) + + def draw_minimap(self): + downscale = 5 + minimap_size = pygame.Vector2(self.size / downscale) + minimap = pygame.Surface(minimap_size) + minimap.fill('white') + pygame.draw.rect(minimap, 'blue', pygame.Rect((0, 0), minimap_size), width=2) + + for connector in self.connectors: + pygame.draw.line( + minimap, + 'gray', + connector['start']/downscale, + connector['end']/downscale, + ) + for station in self.stations: + pygame.draw.circle(minimap, 'green', station['position']/downscale, 5) + for carrier in self.carriers: + pygame.draw.circle(minimap, 'orange', carrier['position']/downscale, 3) + + view_outline = pygame.Rect( + -1 * self.view / downscale - (self.size / downscale * self.viewpoint.z) / 2, + self.size / downscale * self.viewpoint.z + ) + pygame.draw.rect(minimap, 'red', view_outline, width=1) + self.screen.blit(minimap, (self.size.x-minimap_size.x, 0)) def check_user_input(self): for event in pygame.event.get(): @@ -310,26 +345,31 @@ def run(self): if self.stop_event.is_set(): break - if not self.check_user_input(): + # Why do we check if the check_user_input returns True? + if self.viewpoint is not None and not self.check_user_input(): break self.check_connection() - if not self.has_set_initial_view and self.initial_view_data: + if self.viewpoint is None and self.initial_view_data: self.set_initial_viewpoint() self.clear() - self.draw_connectors() - self.draw_stations() - self.draw_carriers() - self.draw_user_input() - self.draw_info() - self.draw_actions() - if not self.has_set_initial_view: + + if self.viewpoint is None: self.draw_loading() else: + self.draw_connectors() + self.draw_stations() + self.draw_carriers() + self.draw_user_input() + self.draw_info() + self.draw_actions() self.draw_cursor() + if self.viewpoint is not None and self.show_minimap: + self.draw_minimap() + if self.halt_event.is_set(): self.clear() self.draw_shutdown() From 03e1271c2d46cb87fc48fd23c88ad8ee049aeb2d Mon Sep 17 00:00:00 2001 From: HSMarieK Date: Thu, 2 Apr 2026 15:27:21 +0200 Subject: [PATCH 02/14] improved_minimap_sizing_and_information --- lineflow/simulation/visualization.py | 86 +++++++++++++++++++++++----- 1 file changed, 73 insertions(+), 13 deletions(-) diff --git a/lineflow/simulation/visualization.py b/lineflow/simulation/visualization.py index 0890d4b..f02872a 100644 --- a/lineflow/simulation/visualization.py +++ b/lineflow/simulation/visualization.py @@ -44,9 +44,10 @@ def __init__( self.initial_view_data = False + self.line_bounds = None self.show_minimap = True - def set_initial_viewpoint(self): + def find_line_size(self): x_positions = [] y_positions = [] for station in self.stations: @@ -58,6 +59,14 @@ def set_initial_viewpoint(self): min(x_positions)+line_width/2, min(y_positions)+line_height/2 ) + self.line_bounds = dict( + upper_left=pygame.Vector2(min(x_positions), min(y_positions)), + lower_right=pygame.Vector2(max(x_positions), max(y_positions)) + ) + return line_width, line_height, line_center + + def set_initial_viewpoint(self): + line_width, line_height, line_center = self.find_line_size() x = -line_center.x y = -line_center.y x_scalar = line_width / (self.size.x-100) @@ -285,36 +294,87 @@ def draw_cursor(self): pygame.draw.circle(self.screen, 'blue', self.center, 10, 1) def draw_minimap(self): + if self.line_bounds is None: + self.find_line_size() + downscale = 5 + buffer = pygame.Vector2(10, 10) + line_diagonal = self.line_bounds['lower_right'] - self.line_bounds['upper_left'] + minimap_upper_left = pygame.Vector2( + self.size.x - line_diagonal.x / downscale - buffer.x, + buffer.y + ) + draw_position = minimap_upper_left - self.line_bounds['upper_left'] / downscale minimap_size = pygame.Vector2(self.size / downscale) - minimap = pygame.Surface(minimap_size) - minimap.fill('white') - pygame.draw.rect(minimap, 'blue', pygame.Rect((0, 0), minimap_size), width=2) + pygame.draw.rect( + self.screen, + 'white', + pygame.Rect(minimap_upper_left - buffer, line_diagonal / downscale + buffer*2) + ) + pygame.draw.rect( + self.screen, + 'blue', + pygame.Rect(minimap_upper_left - buffer, line_diagonal / downscale + buffer*2), + width=2 + ) for connector in self.connectors: pygame.draw.line( - minimap, + self.screen, 'gray', - connector['start']/downscale, - connector['end']/downscale, + draw_position + connector['start'] / downscale, + draw_position + connector['end'] / downscale, ) for station in self.stations: - pygame.draw.circle(minimap, 'green', station['position']/downscale, 5) + color = 'black' + if not 'mode' in station: + pass + elif station['mode'] == 'working': + color = 'green' + elif station['mode'] == 'waiting': + color = 'yellow' + elif station['mode'] == 'failing': + color = 'red' + elif station['mode'] == 'off': + color = 'gray' + pygame.draw.circle( + self.screen, + color, + draw_position + station['position'] / downscale, + 5 + ) for carrier in self.carriers: - pygame.draw.circle(minimap, 'orange', carrier['position']/downscale, 3) + pygame.draw.circle( + self.screen, + 'orange', + draw_position + carrier['position'] / downscale, + 3 + ) view_outline = pygame.Rect( - -1 * self.view / downscale - (self.size / downscale * self.viewpoint.z) / 2, + draw_position - self.view / downscale - self.size / downscale * self.viewpoint.z / 2, self.size / downscale * self.viewpoint.z ) - pygame.draw.rect(minimap, 'red', view_outline, width=1) - self.screen.blit(minimap, (self.size.x-minimap_size.x, 0)) + pygame.draw.line( + self.screen, + 'red', + draw_position - self.view / downscale + (3,0), + draw_position - self.view / downscale - (3,0) + ) + pygame.draw.line( + self.screen, + 'red', + draw_position - self.view / downscale + (0,3), + draw_position - self.view / downscale - (0,3) + ) + if self.viewpoint.z < 1: + pygame.draw.rect(self.screen, 'red', view_outline, width=1) def check_user_input(self): for event in pygame.event.get(): if event.type == pygame.QUIT: return False - + keys = pygame.key.get_pressed() if keys[pygame.K_q]: self.viewpoint.z -= 3*self.dt From 0998e3e9faa9c0739d82b9cfb1fde59e58171807 Mon Sep 17 00:00:00 2001 From: HSMarieK Date: Thu, 2 Apr 2026 15:36:32 +0200 Subject: [PATCH 03/14] M_to_toggle_minimap --- lineflow/simulation/visualization.py | 44 +++++++++++++--------------- 1 file changed, 20 insertions(+), 24 deletions(-) diff --git a/lineflow/simulation/visualization.py b/lineflow/simulation/visualization.py index f02872a..dc969f8 100644 --- a/lineflow/simulation/visualization.py +++ b/lineflow/simulation/visualization.py @@ -137,23 +137,26 @@ def draw_connectors(self): self.view/self.viewpoint.z + self.center + connector['start']/self.viewpoint.z + snippet*(n+1), int(10/self.viewpoint.z) ) + def set_station_color(self, station): + color = 'black' + if not 'mode' in station: + pass + elif station['mode'] == 'working': + color = 'green' + elif station['mode'] == 'waiting': + color = 'yellow' + elif station['mode'] == 'failing': + color = 'red' + elif station['mode'] == 'off': + color = 'gray' + return color def draw_stations(self): width = 30 height = 30 font = pygame.font.SysFont(None,int(20/self.viewpoint.z)) for station in self.stations: - color = 'black' - if not 'mode' in station: - pass - elif station['mode'] == 'working': - color = 'green' - elif station['mode'] == 'waiting': - color = 'yellow' - elif station['mode'] == 'failing': - color = 'red' - elif station['mode'] == 'off': - color = 'gray' + color = self.set_station_color(station) pygame.draw.rect( self.screen, @@ -273,7 +276,7 @@ def draw_actions(self): def draw_user_input(self): font = pygame.font.SysFont(None, 24) text = font.render( - "W: up, S: down, A: left, D: right, Q: zoom in, E: zoom out, Shift+H: Exit", + "W: up, S: down, A: left, D: right, Q: zoom in, E: zoom out, Shift+H: Exit, M: toggle minimap", True, 'black', 'white' @@ -326,17 +329,7 @@ def draw_minimap(self): draw_position + connector['end'] / downscale, ) for station in self.stations: - color = 'black' - if not 'mode' in station: - pass - elif station['mode'] == 'working': - color = 'green' - elif station['mode'] == 'waiting': - color = 'yellow' - elif station['mode'] == 'failing': - color = 'red' - elif station['mode'] == 'off': - color = 'gray' + color = self.set_station_color(station) pygame.draw.circle( self.screen, color, @@ -374,7 +367,10 @@ def check_user_input(self): for event in pygame.event.get(): if event.type == pygame.QUIT: return False - + elif event.type == pygame.KEYDOWN: + if event.key == pygame.K_m: + self.show_minimap = not self.show_minimap + keys = pygame.key.get_pressed() if keys[pygame.K_q]: self.viewpoint.z -= 3*self.dt From c65a00e01f0e4fef656441f018ca728aaaf0dd7d Mon Sep 17 00:00:00 2001 From: HSMarieK Date: Wed, 8 Apr 2026 17:41:08 +0200 Subject: [PATCH 04/14] fix_off_state_communication --- lineflow/simulation/stations.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/lineflow/simulation/stations.py b/lineflow/simulation/stations.py index 1758705..cff704b 100644 --- a/lineflow/simulation/stations.py +++ b/lineflow/simulation/stations.py @@ -171,11 +171,14 @@ def worker_skill(self): return 1.0 def get_visualization_data(self): + mode = self.state['mode'].to_str() + if self.state['on'].to_str() is False: + mode = 'off' data = dict( type='station', name=self.name, position=self.position, - mode=self.state['mode'].to_str() + mode=mode ) data = self._add_visualization_info(data) return data From 66ae15a230fbec1943a59b091e677ae99c3701f7 Mon Sep 17 00:00:00 2001 From: HSMarieK Date: Wed, 8 Apr 2026 17:45:10 +0200 Subject: [PATCH 05/14] property_for_viewpoint_is_set --- lineflow/simulation/visualization.py | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/lineflow/simulation/visualization.py b/lineflow/simulation/visualization.py index dc969f8..55c7c8c 100644 --- a/lineflow/simulation/visualization.py +++ b/lineflow/simulation/visualization.py @@ -47,6 +47,10 @@ def __init__( self.line_bounds = None self.show_minimap = True + @property + def viewpoint_is_set(self): + return self.viewpoint is not None + def find_line_size(self): x_positions = [] y_positions = [] @@ -401,18 +405,17 @@ def run(self): if self.stop_event.is_set(): break - # Why do we check if the check_user_input returns True? - if self.viewpoint is not None and not self.check_user_input(): + if viewpoint_is_set and not self.check_user_input(): break self.check_connection() - if self.viewpoint is None and self.initial_view_data: + if not viewpoint_is_set and self.initial_view_data: self.set_initial_viewpoint() self.clear() - if self.viewpoint is None: + if not viewpoint_is_set: self.draw_loading() else: self.draw_connectors() @@ -423,7 +426,7 @@ def run(self): self.draw_actions() self.draw_cursor() - if self.viewpoint is not None and self.show_minimap: + if viewpoint_is_set and self.show_minimap: self.draw_minimap() if self.halt_event.is_set(): From 91adc1bc1c8510c8688b434b3af25703e99066bb Mon Sep 17 00:00:00 2001 From: HSMarieK Date: Wed, 8 Apr 2026 17:54:02 +0200 Subject: [PATCH 06/14] color_mapping_for_station_mode --- lineflow/simulation/visualization.py | 35 +++++++++++++--------------- 1 file changed, 16 insertions(+), 19 deletions(-) diff --git a/lineflow/simulation/visualization.py b/lineflow/simulation/visualization.py index 55c7c8c..6c2ae79 100644 --- a/lineflow/simulation/visualization.py +++ b/lineflow/simulation/visualization.py @@ -47,6 +47,13 @@ def __init__( self.line_bounds = None self.show_minimap = True + self.color_mapping = { + 'working': 'green', + 'waiting': 'yellow', + 'failing': 'red', + 'off': 'gray' + } + @property def viewpoint_is_set(self): return self.viewpoint is not None @@ -141,26 +148,16 @@ def draw_connectors(self): self.view/self.viewpoint.z + self.center + connector['start']/self.viewpoint.z + snippet*(n+1), int(10/self.viewpoint.z) ) - def set_station_color(self, station): - color = 'black' - if not 'mode' in station: - pass - elif station['mode'] == 'working': - color = 'green' - elif station['mode'] == 'waiting': - color = 'yellow' - elif station['mode'] == 'failing': - color = 'red' - elif station['mode'] == 'off': - color = 'gray' - return color + + def get_station_color(self, station): + return self.color_mapping[station['mode']] def draw_stations(self): width = 30 height = 30 font = pygame.font.SysFont(None,int(20/self.viewpoint.z)) for station in self.stations: - color = self.set_station_color(station) + color = self.get_station_color(station) pygame.draw.rect( self.screen, @@ -333,7 +330,7 @@ def draw_minimap(self): draw_position + connector['end'] / downscale, ) for station in self.stations: - color = self.set_station_color(station) + color = self.get_station_color(station) pygame.draw.circle( self.screen, color, @@ -405,17 +402,17 @@ def run(self): if self.stop_event.is_set(): break - if viewpoint_is_set and not self.check_user_input(): + if self.viewpoint_is_set and not self.check_user_input(): break self.check_connection() - if not viewpoint_is_set and self.initial_view_data: + if not self.viewpoint_is_set and self.initial_view_data: self.set_initial_viewpoint() self.clear() - if not viewpoint_is_set: + if not self.viewpoint_is_set: self.draw_loading() else: self.draw_connectors() @@ -426,7 +423,7 @@ def run(self): self.draw_actions() self.draw_cursor() - if viewpoint_is_set and self.show_minimap: + if self.viewpoint_is_set and self.show_minimap: self.draw_minimap() if self.halt_event.is_set(): From 19ac829eb41d066cd70d659d05175092fb8e2507 Mon Sep 17 00:00:00 2001 From: HSMarieK Date: Wed, 8 Apr 2026 17:59:42 +0200 Subject: [PATCH 07/14] minor_refactoring --- lineflow/simulation/visualization.py | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/lineflow/simulation/visualization.py b/lineflow/simulation/visualization.py index 6c2ae79..97ce01b 100644 --- a/lineflow/simulation/visualization.py +++ b/lineflow/simulation/visualization.py @@ -22,13 +22,10 @@ def __init__( self.size = pygame.Vector2(size) if viewpoint is not None: - self.viewpoint = pygame.Vector3(viewpoint) - else: - self.viewpoint = viewpoint - - if self.viewpoint is not None: - self.view = pygame.Vector2(self.viewpoint.x, self.viewpoint.y) - + viewpoint = pygame.Vector3(viewpoint) + self.view = pygame.Vector2(viewpoint.x, viewpoint.y) + self.viewpoint = viewpoint + self.connection = connection self.stop_event = stop_event self.halt_event = halt_event From 628795e58339c2be105c73e12f1cc894cb78646c Mon Sep 17 00:00:00 2001 From: HSMarieK Date: Wed, 8 Apr 2026 18:15:57 +0200 Subject: [PATCH 08/14] mouse_zoom_and_panning --- lineflow/simulation/visualization.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/lineflow/simulation/visualization.py b/lineflow/simulation/visualization.py index 97ce01b..fe53cd1 100644 --- a/lineflow/simulation/visualization.py +++ b/lineflow/simulation/visualization.py @@ -368,6 +368,14 @@ def check_user_input(self): elif event.type == pygame.KEYDOWN: if event.key == pygame.K_m: self.show_minimap = not self.show_minimap + elif event.type == pygame.MOUSEWHEEL: + self.viewpoint.z += 5 * event.y * self.dt + + _mouse = pygame.mouse.get_pressed() + mouse_rel = pygame.mouse.get_rel() + if _mouse[1]: + self.viewpoint.x += mouse_rel[0] * self.viewpoint.z + self.viewpoint.y += mouse_rel[1] * self.viewpoint.z keys = pygame.key.get_pressed() if keys[pygame.K_q]: From 9367f267ee0fb8e33c30a2c32e7b7d65f65c34a8 Mon Sep 17 00:00:00 2001 From: HSMarieK Date: Wed, 8 Apr 2026 19:51:27 +0200 Subject: [PATCH 09/14] split_line-bounds_and_line-size_functions_plus_minimap-surface --- lineflow/simulation/visualization.py | 55 ++++++++++++++-------------- 1 file changed, 28 insertions(+), 27 deletions(-) diff --git a/lineflow/simulation/visualization.py b/lineflow/simulation/visualization.py index 97ce01b..50f9ba9 100644 --- a/lineflow/simulation/visualization.py +++ b/lineflow/simulation/visualization.py @@ -55,22 +55,23 @@ def __init__( def viewpoint_is_set(self): return self.viewpoint is not None - def find_line_size(self): + def find_line_bounds(self): x_positions = [] y_positions = [] for station in self.stations: x_positions.append(station['position'].x) y_positions.append(station['position'].y) - line_width = max(x_positions)-min(x_positions) - line_height = max(y_positions)-min(y_positions) - line_center = pygame.Vector2( - min(x_positions)+line_width/2, - min(y_positions)+line_height/2 - ) self.line_bounds = dict( upper_left=pygame.Vector2(min(x_positions), min(y_positions)), lower_right=pygame.Vector2(max(x_positions), max(y_positions)) ) + + def find_line_size(self): + if self.line_bounds is None: + self.find_line_bounds() + line_width = self.line_bounds['lower_right'].x - self.line_bounds['upper_left'].x + line_height = self.line_bounds['lower_right'].y - self.line_bounds['upper_left'].y + line_center = self.line_bounds['upper_left'] + (line_width/2,line_height/2) return line_width, line_height, line_center def set_initial_viewpoint(self): @@ -296,32 +297,31 @@ def draw_cursor(self): def draw_minimap(self): if self.line_bounds is None: - self.find_line_size() + self.find_line_bounds() downscale = 5 - buffer = pygame.Vector2(10, 10) + buffer = pygame.Vector2(20, 20) line_diagonal = self.line_bounds['lower_right'] - self.line_bounds['upper_left'] - minimap_upper_left = pygame.Vector2( - self.size.x - line_diagonal.x / downscale - buffer.x, - buffer.y + minimap_surface_size = pygame.Vector2(line_diagonal / downscale + buffer) + minimap_surface = pygame.Surface(minimap_surface_size) + minimap_surface.fill('white') + minimap_surface_pos = pygame.Vector2( + self.size.x - minimap_surface_size.x, + 0 ) - draw_position = minimap_upper_left - self.line_bounds['upper_left'] / downscale + minimap_upper_left = pygame.Vector2(0,0) + draw_position = minimap_upper_left - self.line_bounds['upper_left'] / downscale + buffer /2 minimap_size = pygame.Vector2(self.size / downscale) pygame.draw.rect( - self.screen, - 'white', - pygame.Rect(minimap_upper_left - buffer, line_diagonal / downscale + buffer*2) - ) - pygame.draw.rect( - self.screen, + minimap_surface, 'blue', - pygame.Rect(minimap_upper_left - buffer, line_diagonal / downscale + buffer*2), + pygame.Rect(minimap_upper_left, minimap_surface_size), width=2 ) for connector in self.connectors: pygame.draw.line( - self.screen, + minimap_surface, 'gray', draw_position + connector['start'] / downscale, draw_position + connector['end'] / downscale, @@ -329,14 +329,14 @@ def draw_minimap(self): for station in self.stations: color = self.get_station_color(station) pygame.draw.circle( - self.screen, + minimap_surface, color, draw_position + station['position'] / downscale, 5 ) for carrier in self.carriers: pygame.draw.circle( - self.screen, + minimap_surface, 'orange', draw_position + carrier['position'] / downscale, 3 @@ -347,19 +347,20 @@ def draw_minimap(self): self.size / downscale * self.viewpoint.z ) pygame.draw.line( - self.screen, + minimap_surface, 'red', draw_position - self.view / downscale + (3,0), draw_position - self.view / downscale - (3,0) ) pygame.draw.line( - self.screen, + minimap_surface, 'red', draw_position - self.view / downscale + (0,3), draw_position - self.view / downscale - (0,3) ) - if self.viewpoint.z < 1: - pygame.draw.rect(self.screen, 'red', view_outline, width=1) + + pygame.draw.rect(minimap_surface, 'red', view_outline, width=1) + self.screen.blit(minimap_surface,minimap_surface_pos) def check_user_input(self): for event in pygame.event.get(): From 1798dd7d43a7f88343161c478ad6217a67545c0e Mon Sep 17 00:00:00 2001 From: Tobias Windisch Date: Wed, 8 Apr 2026 20:51:01 +0200 Subject: [PATCH 10/14] tiny update Signed-off-by: Tobias Windisch --- lineflow/simulation/visualization.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/lineflow/simulation/visualization.py b/lineflow/simulation/visualization.py index fe53cd1..b1ad397 100644 --- a/lineflow/simulation/visualization.py +++ b/lineflow/simulation/visualization.py @@ -371,9 +371,10 @@ def check_user_input(self): elif event.type == pygame.MOUSEWHEEL: self.viewpoint.z += 5 * event.y * self.dt - _mouse = pygame.mouse.get_pressed() + _mouse = pygame.mouse.get_pressed(num_buttons=3) mouse_rel = pygame.mouse.get_rel() - if _mouse[1]: + + if _mouse[0]: self.viewpoint.x += mouse_rel[0] * self.viewpoint.z self.viewpoint.y += mouse_rel[1] * self.viewpoint.z From a2c93de10e4244494ab0e10dc3f75c11088397fb Mon Sep 17 00:00:00 2001 From: HSMarieK Date: Fri, 10 Apr 2026 15:32:51 +0200 Subject: [PATCH 11/14] beautifications_and_cleanup --- lineflow/simulation/visualization.py | 70 ++++++++++------------------ 1 file changed, 25 insertions(+), 45 deletions(-) diff --git a/lineflow/simulation/visualization.py b/lineflow/simulation/visualization.py index f2c0b44..b72a1a5 100644 --- a/lineflow/simulation/visualization.py +++ b/lineflow/simulation/visualization.py @@ -240,18 +240,8 @@ def draw_carriers(self): def draw_info(self): if self.info is not None: font = pygame.font.SysFont(None, 20) - time = font.render( - 'T={:.2f}'.format(self.info['time']), - True, - 'black', - 'white' - ) - n_parts = font.render( - f"#Parts={self.info['n_parts']}", - True, - 'black', - 'white' - ) + time = font.render( 'T={:.2f}'.format(self.info['time']), True, 'black', 'white') + n_parts = font.render( f"#Parts={self.info['n_parts']}", True, 'black', 'white') self.screen.blit(time, time.get_rect(center=(30, 30))) self.screen.blit(n_parts, n_parts.get_rect(center=(30, 50))) @@ -264,12 +254,7 @@ def draw_actions(self): actions = "".join(f"{action[0]}={action[1]}" for action in actor_actions[1].items()) else: actions = "".join(f"{action[0]}={action[1]}, " for action in actor_actions[1].items()) - text = font.render( - f'{actor}: {actions}', - True, - 'black', - 'white' - ) + text = font.render( f'{actor}: {actions}', True, 'black', 'white') self.screen.blit(text, text.get_rect(center=(self.center.x, 30+n*22))) def draw_user_input(self): @@ -292,36 +277,29 @@ def draw_shutdown(self): text = font.render("Shutting down...", True, 'black') self.screen.blit(text, text.get_rect(center=self.center)) - def draw_cursor(self): - pygame.draw.circle(self.screen, 'blue', self.center, 10, 1) + def draw_crosshair(self): + pygame.draw.line( self.screen, 'red', self.center + (10,0), self.center - (10,0)) + pygame.draw.line( self.screen, 'red', self.center + (0,10), self.center - (0,10)) def draw_minimap(self): if self.line_bounds is None: self.find_line_bounds() + #setup minimap downscale = 5 buffer = pygame.Vector2(20, 20) line_diagonal = self.line_bounds['lower_right'] - self.line_bounds['upper_left'] - minimap_surface_size = pygame.Vector2(line_diagonal / downscale + buffer) - minimap_surface = pygame.Surface(minimap_surface_size) - minimap_surface.fill('white') - minimap_surface_pos = pygame.Vector2( - self.size.x - minimap_surface_size.x, - 0 - ) - minimap_upper_left = pygame.Vector2(0,0) - draw_position = minimap_upper_left - self.line_bounds['upper_left'] / downscale + buffer /2 - minimap_size = pygame.Vector2(self.size / downscale) - pygame.draw.rect( - minimap_surface, - 'blue', - pygame.Rect(minimap_upper_left, minimap_surface_size), - width=2 - ) - + minimap_size = pygame.Vector2(line_diagonal / downscale + buffer) + minimap = pygame.Surface(minimap_size) + minimap.fill('white') + minimap_pos = pygame.Vector2(self.size.x - minimap_size.x, 0) + draw_position = - self.line_bounds['upper_left'] / downscale + buffer /2 + pygame.draw.rect(minimap, 'black', pygame.Rect((0,0), minimap_size), width=2) + + #draw on minimap for connector in self.connectors: pygame.draw.line( - minimap_surface, + minimap, 'gray', draw_position + connector['start'] / downscale, draw_position + connector['end'] / downscale, @@ -329,38 +307,40 @@ def draw_minimap(self): for station in self.stations: color = self.get_station_color(station) pygame.draw.circle( - minimap_surface, + minimap, color, draw_position + station['position'] / downscale, 5 ) for carrier in self.carriers: pygame.draw.circle( - minimap_surface, + minimap, 'orange', draw_position + carrier['position'] / downscale, 3 ) + #draw outline of current view and crosshair view_outline = pygame.Rect( draw_position - self.view / downscale - self.size / downscale * self.viewpoint.z / 2, self.size / downscale * self.viewpoint.z ) pygame.draw.line( - minimap_surface, + minimap, 'red', draw_position - self.view / downscale + (3,0), draw_position - self.view / downscale - (3,0) ) pygame.draw.line( - minimap_surface, + minimap, 'red', draw_position - self.view / downscale + (0,3), draw_position - self.view / downscale - (0,3) ) + pygame.draw.rect(minimap, 'red', view_outline, width=1) - pygame.draw.rect(minimap_surface, 'red', view_outline, width=1) - self.screen.blit(minimap_surface,minimap_surface_pos) + #blit minimap onto screen + self.screen.blit(minimap,minimap_pos) def check_user_input(self): for event in pygame.event.get(): @@ -428,7 +408,7 @@ def run(self): self.draw_user_input() self.draw_info() self.draw_actions() - self.draw_cursor() + self.draw_crosshair() if self.viewpoint_is_set and self.show_minimap: self.draw_minimap() From 2ba6a8a03afc2f6872c5f37421c44f4426b95fce Mon Sep 17 00:00:00 2001 From: HSMarieK Date: Fri, 10 Apr 2026 15:52:16 +0200 Subject: [PATCH 12/14] improved_zoom_behavior --- lineflow/simulation/visualization.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/lineflow/simulation/visualization.py b/lineflow/simulation/visualization.py index b72a1a5..e520c13 100644 --- a/lineflow/simulation/visualization.py +++ b/lineflow/simulation/visualization.py @@ -350,7 +350,7 @@ def check_user_input(self): if event.key == pygame.K_m: self.show_minimap = not self.show_minimap elif event.type == pygame.MOUSEWHEEL: - self.viewpoint.z += 5 * event.y * self.dt + self.viewpoint.z += 5 * event.y * self.viewpoint.z * self.dt _mouse = pygame.mouse.get_pressed(num_buttons=3) mouse_rel = pygame.mouse.get_rel() @@ -361,17 +361,17 @@ def check_user_input(self): keys = pygame.key.get_pressed() if keys[pygame.K_q]: - self.viewpoint.z -= 3*self.dt + self.viewpoint.z -= 3*self.viewpoint.z*self.dt if keys[pygame.K_e]: - self.viewpoint.z += 3*self.dt + self.viewpoint.z += 3*self.viewpoint.z*self.dt if keys[pygame.K_w] or keys[pygame.K_UP]: - self.viewpoint.y += 300*self.dt + self.viewpoint.y += 300*self.viewpoint.z*self.dt if keys[pygame.K_s] or keys[pygame.K_DOWN]: - self.viewpoint.y -= 300*self.dt + self.viewpoint.y -= 300*self.viewpoint.z*self.dt if keys[pygame.K_a] or keys[pygame.K_LEFT]: - self.viewpoint.x += 300*self.dt + self.viewpoint.x += 300*self.viewpoint.z*self.dt if keys[pygame.K_d] or keys[pygame.K_RIGHT]: - self.viewpoint.x -= 300*self.dt + self.viewpoint.x -= 300*self.viewpoint.z*self.dt if keys[pygame.K_h] and keys[pygame.K_LSHIFT]: self.halt_event.set() self.viewpoint.z = max(0.5,min(10,self.viewpoint.z)) From 5eb6982f325456a7a0d9e5307eae454ab474e8da Mon Sep 17 00:00:00 2001 From: Tobias Windisch Date: Sat, 11 Apr 2026 08:29:03 +0200 Subject: [PATCH 13/14] bump version Signed-off-by: Tobias Windisch --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 0d91a54..1d0ba9e 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.3.0 +0.4.0 From d9e3b3e98b4dcbbef58668b58a37cac08ec1f33b Mon Sep 17 00:00:00 2001 From: Tobias Windisch Date: Sat, 11 Apr 2026 08:30:41 +0200 Subject: [PATCH 14/14] tiny --- lineflow/simulation/visualization.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lineflow/simulation/visualization.py b/lineflow/simulation/visualization.py index e520c13..e99adca 100644 --- a/lineflow/simulation/visualization.py +++ b/lineflow/simulation/visualization.py @@ -265,7 +265,7 @@ def draw_user_input(self): 'black', 'white' ) - self.screen.blit(text,text.get_rect(left=50,top=self.size.y-40)) + self.screen.blit(text, text.get_rect(left=50,top=self.size.y-40)) def draw_loading(self): font = pygame.font.SysFont(None, 48)