about summary refs log tree commit diff stats
path: root/html/tower/js/game.js
diff options
context:
space:
mode:
Diffstat (limited to 'html/tower/js/game.js')
-rw-r--r--html/tower/js/game.js88
1 files changed, 69 insertions, 19 deletions
diff --git a/html/tower/js/game.js b/html/tower/js/game.js
index 1099c46..0e79e4e 100644
--- a/html/tower/js/game.js
+++ b/html/tower/js/game.js
@@ -113,53 +113,103 @@ function spawnEnemies(timestamp) {
 }
 
 /**
- * Renders all game elements to the canvas
+ * Renders all game elements to the canvas using a layered approach.
+ * This function demonstrates several key game development patterns:
  * 
- * Key concepts:
- * - Layer-based rendering
- * - Canvas drawing order (background to foreground)
- * - Separation of rendering and game logic
+ * 1. Canvas State Management:
+ *    - Uses save()/restore() to isolate rendering contexts
+ *    - Resets transform matrix to prevent state leaks
+ *    - Maintains clean state between rendering phases
+ * 
+ * 2. Layered Rendering Pattern:
+ *    - Renders in specific order (background → entities → UI)
+ *    - Each layer builds on top of previous layers
+ *    - Separates rendering concerns for easier maintenance
+ * 
+ * 3. Separation of Concerns:
+ *    - Each render function handles one specific type of game element
+ *    - UI rendering is isolated from game element rendering
+ *    - Clear boundaries between different rendering responsibilities
+ * 
+ * The rendering order is important:
+ * 1. Grid (background)
+ * 2. Particles (effects under entities)
+ * 3. Projectiles (dynamic game elements)
+ * 4. Towers (static game entities)
+ * 5. Enemies (moving game entities)
+ * 6. UI (top layer)
  */
 function renderGame() {
-    // Clear and reset canvas state at the start
+    // Reset the canvas transform matrix to identity
+    // This prevents any previous transformations from affecting new renders
     ctx.setTransform(1, 0, 0, 1, 0, 0);
+    
+    // Clear the entire canvas to prevent ghosting
+    // This is crucial for animation smoothness
     ctx.clearRect(0, 0, canvas.width, canvas.height);
     
-    // Save initial state
+    // Save the initial clean state
+    // This is part of the state stack pattern used in canvas rendering
     ctx.save();
     
-    // Render game elements
-    renderGrid(ctx, gameState.grid);
-    renderParticles(ctx, gameState.particles);
-    renderProjectiles(ctx, gameState.projectiles);
-    renderTowers(ctx, gameState.towers);
-    renderEnemies(ctx, gameState.enemies);
+    // Render game world elements in specific order
+    // This creates the layered effect common in 2D games
+    renderGrid(ctx, gameState.grid);          // Background layer
+    renderParticles(ctx, gameState.particles); // Effect layer
+    renderProjectiles(ctx, gameState.projectiles); // Dynamic elements
+    renderTowers(ctx, gameState.towers);       // Static entities
+    renderEnemies(ctx, gameState.enemies);     // Moving entities
     
-    // Restore to clean state before UI
+    // Restore to clean state before UI rendering
+    // This ensures UI rendering isn't affected by game world rendering
     ctx.restore();
     ctx.save();
     
-    // Render UI with clean state
+    // Render UI elements last so they appear on top
+    // UI is rendered with its own clean state to prevent interference
     renderUI(ctx, gameState);
     
-    // Final restore
+    // Final state restoration
+    // Ensures clean state for next frame
     ctx.restore();
 }
 
-// Start the game
+/**
+ * Initializes the game by:
+ * 1. Generating the path for enemies to follow
+ * 2. Setting up initial enemy count
+ * 3. Binding event listeners
+ * 4. Starting the game loop
+ * 
+ * Uses Promise-based path generation to handle async initialization
+ */
 generatePath(gameState.grid).then(path => {
     gameState.path = path;
-    enemiesRemaining = Math.floor(Math.random() * 26) + 5; // 5-30 enemies
+    // Random enemy count between 5-30 for variety
+    enemiesRemaining = Math.floor(Math.random() * 26) + 5;
     initializeEventListeners();
+    // Start the game loop using requestAnimationFrame for smooth animation
     requestAnimationFrame(gameLoop);
 });
 
+/**
+ * Transitions the game from placement to combat phase.
+ * Demonstrates state machine pattern commonly used in games.
+ * 
+ * Side effects:
+ * - Updates game phase
+ * - Disables UI elements
+ * - Updates visual feedback
+ */
 function startCombat() {
     if (gameState.phase === GamePhase.PLACEMENT && gameState.towers.length > 0) {
+        // State transition
         gameState.phase = GamePhase.COMBAT;
+        
+        // UI updates
         document.getElementById('startCombat').disabled = true;
         
-        // Disable tower palette
+        // Visual feedback for disabled state
         document.querySelectorAll('.tower-option').forEach(option => {
             option.draggable = false;
             option.style.cursor = 'not-allowed';