diff options
Diffstat (limited to 'html/tower/js/game.js')
-rw-r--r-- | html/tower/js/game.js | 142 |
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 |