about summary refs log tree commit diff stats
path: root/html
diff options
context:
space:
mode:
authorelioat <elioat@tilde.institute>2025-02-17 09:01:36 -0500
committerelioat <elioat@tilde.institute>2025-02-17 09:01:36 -0500
commit82eb0fe6103e86cfccde9bdeb61aeb28e9ea66c3 (patch)
treeab401c415732f027670a9cd0d01c22f26da21d18 /html
parenta9562680fb39d3b6cde4e194ace4630227de306c (diff)
downloadtour-82eb0fe6103e86cfccde9bdeb61aeb28e9ea66c3.tar.gz
*
Diffstat (limited to 'html')
-rw-r--r--html/tower/js/game.js66
-rw-r--r--html/tower/js/gameState.js15
-rw-r--r--html/tower/js/mechanics.js4
3 files changed, 79 insertions, 6 deletions
diff --git a/html/tower/js/game.js b/html/tower/js/game.js
index 8d9eea7..82c6479 100644
--- a/html/tower/js/game.js
+++ b/html/tower/js/game.js
@@ -29,12 +29,14 @@ function gameLoop(timestamp) {
     
     ctx.clearRect(0, 0, canvas.width, canvas.height);
     
-    if (gameState.phase === GamePhase.COMBAT) {
-        handleCombatPhase(timestamp, deltaTime);
-        
-        // Check for level completion
-        if (gameState.checkLevelComplete()) {
-            handleLevelComplete();
+    if (!gameState.isGameOver) {
+        if (gameState.phase === GamePhase.COMBAT) {
+            handleCombatPhase(timestamp, deltaTime);
+            
+            // Check for level completion
+            if (gameState.checkLevelComplete()) {
+                handleLevelComplete();
+            }
         }
     }
     
@@ -420,4 +422,56 @@ function populateTowerPalette() {
     startButton.className = 'start-button';
     startButton.textContent = 'Start Combat';
     palette.appendChild(startButton);
+}
+
+/**
+ * Handles game over state and prompts for restart
+ */
+function handleGameOver() {
+    gameState.phase = GamePhase.TRANSITION;
+    gameState.isGameOver = true;
+    
+    const message = `
+        Game Over!
+        
+        Final Stats:
+        Level Reached: ${gameState.level}
+        Enemies Destroyed: ${gameState.enemiesDestroyed}
+        Enemies Escaped: ${gameState.enemiesEscaped}
+        
+        Would you like to restart from Level 1?
+    `;
+    
+    setTimeout(() => {
+        if (confirm(message)) {
+            restartGame();
+        }
+    }, 100);
+}
+
+/**
+ * Restarts the game from level 1 with fresh state
+ */
+function restartGame() {
+    gameState.resetGame();
+    
+    // Generate new path
+    generatePath(gameState.grid).then(path => {
+        gameState.path = path;
+        
+        // Reset enemy count to level 1
+        enemiesRemaining = 5;
+        
+        // Re-enable tower palette
+        document.querySelectorAll('.tower-option').forEach(option => {
+            option.draggable = true;
+            option.style.cursor = 'grab';
+            option.style.opacity = '1';
+        });
+        
+        // Reset start button
+        const startButton = document.getElementById('startCombat');
+        startButton.disabled = false;
+        startButton.textContent = 'Start Level 1';
+    });
 } 
\ No newline at end of file
diff --git a/html/tower/js/gameState.js b/html/tower/js/gameState.js
index f6da7aa..58a7b32 100644
--- a/html/tower/js/gameState.js
+++ b/html/tower/js/gameState.js
@@ -169,6 +169,21 @@ const gameState = {
     enemiesEscaped: 0,
     level: 1,
     
+    resetGame() {
+        this.grid = Array(20).fill().map(() => Array(20).fill('empty'));
+        this.path = [];
+        this.towers = [];
+        this.enemies = [];
+        this.currency = 100;
+        this.phase = GamePhase.PLACEMENT;
+        this.isGameOver = false;
+        this.particles = [];
+        this.projectiles = [];
+        this.enemiesDestroyed = 0;
+        this.enemiesEscaped = 0;
+        this.level = 1;
+    },
+    
     // Define the function as part of the initial object
     awardEnemyDestroyed() {
         this.enemiesDestroyed++;
diff --git a/html/tower/js/mechanics.js b/html/tower/js/mechanics.js
index c1dcb1c..e9d751a 100644
--- a/html/tower/js/mechanics.js
+++ b/html/tower/js/mechanics.js
@@ -37,6 +37,10 @@ function updateEnemies() {
             gameState.enemiesEscaped++;
             // Deduct currency when enemy escapes
             gameState.currency = Math.max(0, gameState.currency - 10);
+            // Check for game over
+            if (gameState.currency <= 0) {
+                handleGameOver();
+            }
             return false;
         }