From cc599c342c02f49af4c39aa6fa881456b6c8c910 Mon Sep 17 00:00:00 2001 From: John Doe Date: Fri, 17 Oct 2025 23:40:00 +0200 Subject: [PATCH] feat: implement start dialog rendering for Pyodide compatibility --- rats.py | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 57 insertions(+), 1 deletion(-) diff --git a/rats.py b/rats.py index b0ec292..b938c9a 100644 --- a/rats.py +++ b/rats.py @@ -93,6 +93,20 @@ class MiceMaze( self.scrolling = False self.sounds = {} self.start_game() + # If running under Pyodide, try to force a single-frame render of the + # start menu so the dialog is visible even before the JS-driven + # requestAnimationFrame loop begins. This helps when the browser + # scheduling would otherwise miss the initial dialog draw. + try: + import js + try: + self.show_start_dialog() + except Exception: + # Non-fatal if the helper can't run now + pass + except Exception: + # Not running in Pyodide - ignore + pass self.background_texture = None self.configs = self.get_config() self.combined_scores = None @@ -187,7 +201,7 @@ class MiceMaze( self.render_engine.dialog(greeting_title, subtitle=full_subtitle, - image=self.assets["da"]) + image=self.assets["BMP_WEWIN"]) return self.render_engine.delete_tag("unit") self.render_engine.delete_tag("effect") @@ -221,6 +235,48 @@ class MiceMaze( except Exception: pass + def show_start_dialog(self): + """Force a single-frame render of the start menu/dialog. + + This calls the underlying render engine's `step` method once with + a small update callback that draws the dialog. Useful under Pyodide + where the JS-driven animation loop may start slightly later and the + initial dialog could be missed. + """ + try: + # Reconstruct the greeting and subtitle similar to update_maze + if self.profile_integration: + player_name = self.profile_integration.get_profile_name() + device_id = self.profile_integration.get_device_id() + else: + player_name = 'Guest' + device_id = 'Unknown Device' + + greeting_title = f"Welcome to Mice, {player_name}!" + + if self.profile_integration and self.profile_integration.current_profile: + profile = self.profile_integration.current_profile + stats_line = f"Best Score: {profile.get('best_score', 0)} | Games: {profile.get('games_played', 0)}" + full_subtitle = f"A game by Matteo, because he was bored.\nDevice: {device_id}\n{stats_line}" + else: + full_subtitle = f"A game by Matteo, because he was bored.\nDevice: {device_id}\nNo profile loaded - playing as guest" + + def do_dialog(): + try: + self.render_engine.dialog(greeting_title, + subtitle=full_subtitle, + image=self.assets.get('BMP_WEWIN')) + except Exception: + pass + + if hasattr(self.render_engine, 'step'): + # Draw background and then the dialog, flip once + self.render_engine.step(update=do_dialog, bg_update=self.draw_maze) + else: + do_dialog() + except Exception as e: + print('[DEBUG] show_start_dialog failed:', e) + def run(self): self.render_engine.mainloop(update=self.update_maze, bg_update=self.draw_maze)