const GamePhase = { PLACEMENT: 'placement', COMBAT: 'combat' }; const TowerTypes = { BASIC: { name: 'Basic Tower', cost: 20, range: 3, damage: 1, attackSpeed: 1, color: '#3498db' }, SNIPER: { name: 'Sniper Tower', cost: 40, range: 6, damage: 2, attackSpeed: 0.5, color: '#8e44ad' }, RAPID: { name: 'Rapid Tower', cost: 35, range: 2, damage: 0.5, attackSpeed: 2, color: '#16a085' }, GOOP: { name: 'Goop Tower', cost: 30, range: 3, damage: 0, attackSpeed: 1, color: '#27ae60', special: 'slow', slowAmount: 0.5 // Reduces enemy speed by 50% }, AOE: { name: 'AOE Tower', cost: 45, range: 2, damage: 1.5, attackSpeed: 0.3, color: '#d35400', special: 'aoe', aoeRadius: 1 // Additional tiles affected } }; const ParticleTypes = { DEATH_PARTICLE: { lifetime: 1000, // milliseconds speed: 0.1, colors: ['#e74c3c', '#c0392b', '#d35400', '#e67e22'] }, PROJECTILE: { lifetime: 300, speed: 0.3, color: '#ecf0f1' }, AOE_EXPLOSION: { lifetime: 500, initialRadius: 10, finalRadius: 60, color: '#d35400', ringWidth: 3 } }; const EnemyTypes = { BASIC: { color: '#c0392b', baseHealth: { min: 2, max: 6 }, speed: { min: 1, max: 1.5 }, damage: 0, isRanged: false }, RANGED: { color: '#2c3e50', baseHealth: { min: 1, max: 4 }, speed: { min: 0.7, max: 1.2 }, damage: 0.3, attackRange: 3, attackSpeed: 1, // attacks per second isRanged: true } }; function createTower(type, position) { return { ...TowerTypes[type], type, position, lastAttackTime: 0, currentHealth: 10, maxHealth: 10 }; } function createEnemy(startPosition) { // 20% chance for ranged enemy const type = Math.random() < 0.2 ? 'RANGED' : 'BASIC'; const enemyType = EnemyTypes[type]; const health = Math.floor(Math.random() * (enemyType.baseHealth.max - enemyType.baseHealth.min + 1)) + enemyType.baseHealth.min; return { position: { ...startPosition }, currentHealth: health, maxHealth: health, speed: enemyType.speed.min + Math.random() * (enemyType.speed.max - enemyType.speed.min), pathIndex: 0, type, lastAttackTime: 0, damage: enemyType.damage }; } function createParticle(type, position, angle) { return { position: { ...position }, velocity: { x: Math.cos(angle) * type.speed, y: Math.sin(angle) * type.speed }, color: Array.isArray(type.colors) ? type.colors[Math.floor(Math.random() * type.colors.length)] : type.color, createdAt: performance.now(), lifetime: type.lifetime, size: 3 + Math.random() * 2 }; } // Initialize game state at the bottom of the file const gameState = { grid: Array(20).fill().map(() => Array(20).fill('empty')), path: [], towers: [], enemies: [], currency: 100, phase: 'placement', isGameOver: false, particles: [], projectiles: [], enemiesDestroyed: 0, enemiesEscaped: 0, // Define the function as part of the initial object awardEnemyDestroyed() { this.enemiesDestroyed++; // Random reward between 1 and 3 const reward = Math.floor(Math.random() * 3) + 1; this.currency += reward; } };