1313from js import document #type:ignore
1414canvas = document .getElementById ("gameCanvas" )
1515container = document .getElementById ("canvasContainer" )
16- SCREEN_W , SCREEN_H = container .clientWidth , container .clientHeight
1716log = getLogger (__name__ , False )
1817
1918# --------------------
2019# methods useful across various scenes
2120# --------------------
2221
22+ ORBITING_PLANETS_SCENE = "orbiting-planets-scene"
23+ FINAL_SCENE = "final-scene"
24+ START_SCENE = "start-scene"
2325
2426def get_controls ():
2527 return window .controls
2628
27-
2829def get_player ():
2930 return window .player
3031
31-
3232def get_asteroid_system ():
3333 return window .asteroids
3434
35-
3635def get_debris_system ():
3736 return window .debris
3837
39-
4038def get_scanner ():
4139 return window .scanner
4240
43-
4441def draw_black_background (ctx ):
4542 ctx .fillStyle = "black"
4643 ctx .fillRect (0 , 0 , window .canvas .width , window .canvas .height )
@@ -49,11 +46,12 @@ def draw_black_background(ctx):
4946# our main scene with the planets orbiting the sun
5047# --------------------
5148
52- ORBITING_PLANETS_SCENE = "orbiting-planets-scene"
53- FINAL_SCENE = "final-scene"
54-
55-
5649class OrbitingPlanetsScene (Scene ):
50+ """
51+ Scene that handles the functionality of the part of the game where planets are orbiting around the sun
52+ and the player can select a level by clicking planets
53+ """
54+
5755 def __init__ (self , name : str , scene_manager : SceneManager , solar_system : SolarSystem ):
5856 super ().__init__ (name , scene_manager )
5957
@@ -130,6 +128,8 @@ def _render_debug_complete_all_button(self, ctx):
130128 ctx .restore ()
131129
132130 def check_planet_click (self ):
131+ """Check whether a UI action needs to occur due to a click event."""
132+
133133 planet = self .solar_sys .get_object_at_position (window .controls .mouse .click )
134134 if window .controls .click and planet :
135135 planet_data = window .get_planet (planet .name )
@@ -159,6 +159,8 @@ def highlight_hovered_planet(self):
159159 planet .highlighted = True
160160
161161 def switch_planet_scene (self , planet_name ):
162+ """Prepare what is needed to transition to a gameplay scene."""
163+
162164 planet_scene_name = f"{ planet_name } -planet-scene"
163165 log .debug ("Activating planet scene: %s" , planet_scene_name )
164166
@@ -178,13 +180,16 @@ def switch_planet_scene(self, planet_name):
178180 get_scanner ().set_scan_parameters (planet .scan_multiplier )
179181 get_scanner ().reset ()
180182
181-
182183# --------------------
183184# game scene with zoomed in planet on left
184185# --------------------
185186
186-
187187class PlanetScene (Scene ):
188+ """
189+ Scene that handles the functionality of the part of the game where the player's ship is active and dodging
190+ asteroids. Also handles the scan results display as a child scene.
191+ """
192+
188193 def __init__ (self , name : str , scene_manager : SceneManager , planet : SpaceMass ):
189194 super ().__init__ (name , scene_manager )
190195
@@ -286,8 +291,8 @@ def handle_scene_completion(self):
286291 self .planet .complete = True
287292
288293 def handle_player_death (self ):
289- window .audio_handler .play_music_death (pause_it = True )
290294 """Handle when the player dies and clicks on the death screen."""
295+ window .audio_handler .play_music_death (pause_it = True )
291296 log .debug (f"Player died on { self .planet .name } ! Returning to orbiting planets scene." )
292297
293298 # Reset all planet completions when player dies
@@ -296,7 +301,6 @@ def handle_player_death(self):
296301 planet .complete = False
297302 log .debug ("All planet completions reset due to player death" )
298303
299- window .audio_handler .play_music_death (pause_it = True )
300304 window .audio_handler .play_explosion (pause_it = True )
301305 self .scene_manager .activate_scene (ORBITING_PLANETS_SCENE )
302306 get_player ().active = False
@@ -308,16 +312,15 @@ def handle_player_death(self):
308312 # special level interaction: finishing earth gives player full health back
309313 if self .planet .name .lower () == "earth" :
310314 get_player ().health = Player .FULL_HEALTH
311- window .audio_handler .play_music_death (pause_it = True )
312315 log .debug (window .audio_handler .music_death .paused )
313316
314-
315-
316317# --------------------
317- # text overlay scenes, such as scan results display
318+ # game intro scene with dialogue
318319# --------------------
319320
320321class StartScene (Scene ):
322+ """Scene for handling the alien dialogue for introducing the game."""
323+
321324 def __init__ (self , name : str , scene_manager : SceneManager , bobbing_timer = 135 , bobbing_max = 20 ):
322325 super ().__init__ (name , scene_manager )
323326 self .stars = StarSystem (
@@ -331,7 +334,7 @@ def __init__(self, name: str, scene_manager: SceneManager, bobbing_timer = 135,
331334 self .dialogue_manager = Dialogue ('dialogue' , scene_manager , window .lore )
332335 self .dialogue_manager .active = True
333336 self .dialogue_manager .margins = Position (300 , 150 )
334- self .dialogue_manager .rect = (0 , SCREEN_H - 150 , SCREEN_W , 150 ) # x, y, width, height
337+ self .dialogue_manager .rect = (0 , window . canvas . height - 150 , window . canvas . width , 150 )
335338 self .dialogue_manager .set_button ("Skip Intro" )
336339 self .dialogue_manager .button_click_callable = self .finalize_scene
337340 self .starsystem = StarSystem3d (100 , max_depth = 100 )
@@ -355,7 +358,7 @@ def render(self, ctx, timestamp):
355358 else :
356359 self .bobbing_offset -= 1
357360
358- player .y = (SCREEN_H // 2 + self .bobbing_offset )
361+ player .y = (window . canvas . height // 2 + self .bobbing_offset )
359362
360363 if abs (self .bobbing_offset ) > self .bobbing_max :
361364 self .is_bobbing_up = not self .is_bobbing_up
@@ -378,8 +381,12 @@ def finalize_scene(self):
378381 window .audio_handler .play_music_main ()
379382 self .scene_manager .activate_scene (ORBITING_PLANETS_SCENE )
380383
384+ # --------------------
385+ # final \ credits scene
386+ # --------------------
381387
382388class FinalScene (Scene ):
389+ """Scene for the final credits."""
383390 def __init__ (self , name : str , scene_manager : SceneManager ):
384391 super ().__init__ (name , scene_manager )
385392 # Sparse stars for space backdrop
@@ -416,10 +423,10 @@ def _draw_earth(self, ctx, timestamp):
416423 sy = 0
417424
418425 # Position Earth in upper-right, smaller size like the reference image
419- target_size = int (min (SCREEN_W , SCREEN_H ) * 0.15 )
426+ target_size = int (min (window . canvas . width , window . canvas . height ) * 0.15 )
420427 dw = dh = target_size
421- dx = SCREEN_W * 0.65 # Right side of screen
422- dy = SCREEN_H * 0.15 # Upper portion
428+ dx = window . canvas . width * 0.65 # Right side of screen
429+ dy = window . canvas . height * 0.15 # Upper portion
423430
424431 ctx .drawImage (
425432 self .earth_sprite .image ,
@@ -431,19 +438,20 @@ def _draw_lunar_surface(self, ctx):
431438 # Draw lunar surface with the top portion visible, like looking across the lunar terrain
432439 if self .moon_sprite and getattr (self .moon_sprite , "is_loaded" , False ):
433440 # Position moon sprite so its upper portion is visible as foreground terrain
434- surface_height = SCREEN_H * 0.5
441+ surface_height = window . canvas . height * 0.5
435442
436443 # Scale to fill screen width
437- scale = (SCREEN_W / self .moon_sprite .width )
444+ scale = (window . canvas . width / self .moon_sprite .width )
438445 sprite_scaled_height = self .moon_sprite .height * scale
439446
440447 # Position so the moon extends below the screen, showing only the top portion
441- dy = SCREEN_H - surface_height
448+ dy = window . canvas . height - surface_height
442449
443450 ctx .drawImage (
444451 self .moon_sprite .image ,
445452 0 , 0 , self .moon_sprite .width , self .moon_sprite .height ,
446- SCREEN_W - (SCREEN_W * scale )/ 1.25 , dy , SCREEN_W * scale , sprite_scaled_height
453+ window .canvas .width - (window .canvas .width * scale )/ 1.25 , dy , # target left, top
454+ window .canvas .width * scale , sprite_scaled_height # target width, height
447455 )
448456
449457 def render (self , ctx , timestamp ):
@@ -460,17 +468,17 @@ def render(self, ctx, timestamp):
460468
461469 # Mission complete text
462470 ctx .save ()
463- ctx .font = f"bold { max (18 , int (min (SCREEN_W , SCREEN_H ) * 0.04 ))} px Courier New"
471+ ctx .font = f"bold { max (18 , int (min (window . canvas . width , window . canvas . height ) * 0.04 ))} px Courier New"
464472 ctx .fillStyle = "#00FF00"
465473 message = "Mission Complete"
466474 tw = ctx .measureText (message ).width
467475 # Position text in the left side
468- ctx .fillText (message , SCREEN_W * 0.05 , SCREEN_H * 0.15 )
476+ ctx .fillText (message , window . canvas . width * 0.05 , window . canvas . height * 0.15 )
469477
470478 # Add click instruction text
471- ctx .font = f"{ max (12 , int (min (SCREEN_W , SCREEN_H ) * 0.025 ) )} px Courier New"
479+ ctx .font = f"{ max (12 , int (min (window . canvas . width , window . canvas . height )) * 0.025 )} px Courier New"
472480 instruction = "Click anywhere to return to solar system"
473- ctx .fillText (instruction , SCREEN_W * 0.05 , SCREEN_H * 0.25 )
481+ ctx .fillText (instruction , window . canvas . width * 0.05 , window . canvas . height * 0.25 )
474482 ctx .restore ()
475483
476484 # Handle click to go back to orbiting planets scene
@@ -488,13 +496,17 @@ def render(self, ctx, timestamp):
488496
489497def create_scene_manager () -> SceneManager :
490498 """
491- Create all the scenes and add them to a scene manager that can be used to switch between them
499+ Create all the scenes and add them to a scene manager that can be used to switch between them The object
500+ instance returned by this is used by the main game loop in game.py to check which scene is active when a
501+ frame is drawn and that scene's render method is called. Only one scene listed in the scene manager is
502+ active at a time, though scenes may have their own subscenes, such as textboxes that they render as part of
503+ their routine.
492504 """
493505 manager = SceneManager ()
494506 planet_scene_state = PlanetState (0 , window .canvas .height , 120.0 , x = 0 , y = window .canvas .height // 2 )
495507 solar_system = SolarSystem ([window .canvas .width , window .canvas .height ], planet_scene_state = planet_scene_state )
496508 orbiting_planets_scene = OrbitingPlanetsScene (ORBITING_PLANETS_SCENE , manager , solar_system )
497- start_scene = StartScene ("start" , manager )
509+ start_scene = StartScene (START_SCENE , manager )
498510 manager .add_scene (start_scene )
499511 manager .add_scene (orbiting_planets_scene )
500512 # Final victory scene (activated when all planets complete)
@@ -505,5 +517,5 @@ def create_scene_manager() -> SceneManager:
505517 big_planet_scene = PlanetScene (f"{ planet .name } -planet-scene" , manager , planet )
506518 manager .add_scene (big_planet_scene )
507519
508- manager .activate_scene ("start" ) # initial scene
520+ manager .activate_scene (START_SCENE ) # initial scene
509521 return manager
0 commit comments