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.js142
1 files changed, 33 insertions, 109 deletions
diff --git a/html/tower/js/game.js b/html/tower/js/game.js
index 263d25c..5c28f31 100644
--- a/html/tower/js/game.js
+++ b/html/tower/js/game.js
@@ -26,126 +26,50 @@ function gameLoop(timestamp) {
     const deltaTime = timestamp - lastTimestamp;
     lastTimestamp = timestamp;
     
-    // Clear canvas
     ctx.clearRect(0, 0, canvas.width, canvas.height);
     
     if (gameState.phase === GamePhase.COMBAT) {
-        // Spawn enemies
-        if (enemiesRemaining > 0 && timestamp - lastEnemySpawn > ENEMY_SPAWN_INTERVAL) {
-            gameState.enemies.push(createEnemy({ x: 0, y: gameState.path[0].y }));
-            lastEnemySpawn = timestamp;
-            enemiesRemaining--;
-        }
-        
-        // Update enemy positions
-        gameState.enemies.forEach(enemy => {
-            if (enemy.pathIndex < gameState.path.length - 1) {
-                const targetPos = gameState.path[enemy.pathIndex + 1];
-                const dx = targetPos.x - enemy.position.x;
-                const dy = targetPos.y - enemy.position.y;
-                const distance = Math.sqrt(dx * dx + dy * dy);
-                
-                if (distance < enemy.speed * deltaTime / 1000) {
-                    enemy.position = { ...targetPos };
-                    enemy.pathIndex++;
-                } else {
-                    enemy.position.x += (dx / distance) * enemy.speed * deltaTime / 1000;
-                    enemy.position.y += (dy / distance) * enemy.speed * deltaTime / 1000;
-                }
-            }
-        });
-        
-        // Update particles
-        gameState.particles = gameState.particles.filter(particle => {
-            const age = timestamp - particle.createdAt;
-            if (age > particle.lifetime) return false;
-            
-            particle.position.x += particle.velocity.x * deltaTime;
-            particle.position.y += particle.velocity.y * deltaTime;
-            return true;
-        });
-        
-        // Update projectiles
-        gameState.projectiles = gameState.projectiles.filter(projectile => {
-            return timestamp - projectile.createdAt < projectile.lifetime;
-        });
-        
-        // Process tower attacks
-        gameState.towers.forEach(tower => {
-            if (timestamp - tower.lastAttackTime > 1000 / tower.attackSpeed) {
-                const enemiesInRange = gameState.enemies.filter(enemy => {
-                    const dx = enemy.position.x - tower.position.x;
-                    const dy = enemy.position.y - tower.position.y;
-                    return Math.sqrt(dx * dx + dy * dy) <= tower.range;
-                });
-                
-                if (enemiesInRange.length > 0) {
-                    const target = enemiesInRange[0];
-                    
-                    // Create projectile
-                    gameState.projectiles.push({
-                        startPos: tower.position,
-                        targetPos: target.position,
-                        createdAt: timestamp,
-                        lifetime: 300 // 300ms travel time
-                    });
-                    
-                    // Apply damage
-                    target.currentHealth -= tower.damage;
-                    tower.lastAttackTime = timestamp;
-                    
-                    // Create death particles if enemy dies
-                    if (target.currentHealth <= 0) {
-                        const cellSize = canvas.width / 20;
-                        const centerX = (target.position.x + 0.5) * cellSize;
-                        const centerY = (target.position.y + 0.5) * cellSize;
-                        
-                        // Create explosion particles with random angles and speeds
-                        const particleCount = 8 + Math.floor(Math.random() * 8); // Random number of particles (8-15)
-                        for (let i = 0; i < particleCount; i++) {
-                            // Random angle with some clustering
-                            const baseAngle = (Math.PI * 2 * i) / particleCount;
-                            const randomAngle = baseAngle + (Math.random() - 0.5) * 1.5; // Add up to ±0.75 radians of randomness
-                            
-                            // Random speed multiplier
-                            const speedMultiplier = 0.7 + Math.random() * 0.6; // Speed varies from 0.7x to 1.3x
-                            
-                            // Random offset from center
-                            const startOffset = Math.random() * 5;
-                            const startX = centerX + Math.cos(randomAngle) * startOffset;
-                            const startY = centerY + Math.sin(randomAngle) * startOffset;
-                            
-                            gameState.particles.push(
-                                createParticle(
-                                    {
-                                        ...ParticleTypes.DEATH_PARTICLE,
-                                        speed: ParticleTypes.DEATH_PARTICLE.speed * speedMultiplier,
-                                        lifetime: ParticleTypes.DEATH_PARTICLE.lifetime * (0.8 + Math.random() * 0.4) // Random lifetime 80%-120%
-                                    },
-                                    { x: startX, y: startY },
-                                    randomAngle
-                                )
-                            );
-                        }
-                    }
-                }
-            }
-        });
-        
-        // Remove dead enemies
-        gameState.enemies = gameState.enemies.filter(enemy => enemy.currentHealth > 0);
+        handleCombatPhase(timestamp, deltaTime);
     }
     
-    // Render game state
+    renderGame();
+    requestAnimationFrame(gameLoop);
+}
+
+function handleCombatPhase(timestamp, deltaTime) {
+    spawnEnemies(timestamp);
+    updateEnemies(gameState.enemies, gameState.path, deltaTime);
+    gameState.particles = updateParticles(gameState.particles, timestamp, deltaTime);
+    gameState.projectiles = gameState.projectiles.filter(p => timestamp - p.createdAt < p.lifetime);
+    
+    const cellSize = canvas.width / 20;
+    processTowerAttacks(
+        gameState.towers,
+        gameState.enemies,
+        gameState.projectiles,
+        gameState.particles,
+        timestamp,
+        cellSize
+    );
+    
+    gameState.enemies = gameState.enemies.filter(enemy => enemy.currentHealth > 0);
+}
+
+function spawnEnemies(timestamp) {
+    if (enemiesRemaining > 0 && timestamp - lastEnemySpawn > ENEMY_SPAWN_INTERVAL) {
+        gameState.enemies.push(createEnemy({ x: 0, y: gameState.path[0].y }));
+        lastEnemySpawn = timestamp;
+        enemiesRemaining--;
+    }
+}
+
+function renderGame() {
     renderGrid(ctx, gameState.grid);
     renderProjectiles(ctx, gameState.projectiles);
     renderEnemies(ctx, gameState.enemies);
     renderTowers(ctx, gameState.towers);
     renderParticles(ctx, gameState.particles);
     renderUI(ctx, gameState);
-    
-    // Request next frame
-    requestAnimationFrame(gameLoop);
 }
 
 // Start the game