diff options
Diffstat (limited to 'html')
-rw-r--r-- | html/tower/index.html | 10 | ||||
-rw-r--r-- | html/tower/js/gameState.js | 27 | ||||
-rw-r--r-- | html/tower/js/mechanics.js | 57 | ||||
-rw-r--r-- | html/tower/js/renderer.js | 60 |
4 files changed, 140 insertions, 14 deletions
diff --git a/html/tower/index.html b/html/tower/index.html index 7c9c3df..a5f1f79 100644 --- a/html/tower/index.html +++ b/html/tower/index.html @@ -96,6 +96,16 @@ <div class="tower-name">Rapid</div> <div class="tower-cost">$35</div> </div> + <div class="tower-option" draggable="true" data-tower-type="GOOP"> + <div class="tower-preview" style="background: #27ae60;"></div> + <div class="tower-name">Goop</div> + <div class="tower-cost">$30</div> + </div> + <div class="tower-option" draggable="true" data-tower-type="AOE"> + <div class="tower-preview" style="background: #e67e22;"></div> + <div class="tower-name">AOE</div> + <div class="tower-cost">$45</div> + </div> <button id="startCombat" class="start-button">Start Combat</button> </div> <canvas id="gameCanvas" width="600" height="600"></canvas> diff --git a/html/tower/js/gameState.js b/html/tower/js/gameState.js index 63270fa..79a32f1 100644 --- a/html/tower/js/gameState.js +++ b/html/tower/js/gameState.js @@ -27,6 +27,26 @@ const TowerTypes = { damage: 0.5, attackSpeed: 2, color: '#2ecc71' + }, + 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: '#e67e22', + special: 'aoe', + aoeRadius: 1 // Additional tiles affected } }; @@ -40,6 +60,13 @@ const ParticleTypes = { lifetime: 300, speed: 0.3, color: '#ffffff' + }, + AOE_EXPLOSION: { + lifetime: 500, + initialRadius: 10, + finalRadius: 60, + color: '#e67e22', + ringWidth: 3 } }; diff --git a/html/tower/js/mechanics.js b/html/tower/js/mechanics.js index c9c4202..ab9bee4 100644 --- a/html/tower/js/mechanics.js +++ b/html/tower/js/mechanics.js @@ -55,8 +55,12 @@ function updateParticles(particles, timestamp, deltaTime) { 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; + // Only update position for particles with velocity + if (particle.velocity) { + particle.position.x += particle.velocity.x * deltaTime; + particle.position.y += particle.velocity.y * deltaTime; + } + return true; }); } @@ -109,15 +113,60 @@ function findEnemiesInRange(tower, enemies) { }); } +function createAOEExplosion(position, cellSize) { + return { + position: { + x: (position.x + 0.5) * cellSize, + y: (position.y + 0.5) * cellSize + }, + createdAt: performance.now(), + type: 'AOE_EXPLOSION', + ...ParticleTypes.AOE_EXPLOSION + }; +} + function handleTowerAttack(tower, target, projectiles, particles, timestamp, cellSize) { + // Create projectile projectiles.push({ startPos: tower.position, targetPos: target.position, createdAt: timestamp, - lifetime: 300 + lifetime: 300, + towerType: tower.type }); - target.currentHealth -= tower.damage; + if (tower.special === 'aoe') { + // Find all enemies in AOE radius + const enemiesInAOE = gameState.enemies.filter(enemy => { + const dx = enemy.position.x - target.position.x; + const dy = enemy.position.y - target.position.y; + return Math.sqrt(dx * dx + dy * dy) <= tower.aoeRadius; + }); + + // Create AOE explosion effect + particles.push(createAOEExplosion(target.position, cellSize)); + + // Damage all enemies in range + enemiesInAOE.forEach(enemy => { + enemy.currentHealth -= tower.damage; + if (enemy.currentHealth <= 0) { + particles.push(...createDeathParticles(enemy, cellSize)); + } + }); + } else if (tower.special === 'slow') { + // Apply slow effect instead of damage + if (!target.slowed) { + target.speed *= (1 - tower.slowAmount); + target.slowed = true; + + // Visual indicator for slowed enemies + target.color = '#27ae60' + Math.floor(0.5 * 255).toString(16).padStart(2, '0'); + } + } else { + // Normal damage for regular towers + target.currentHealth -= tower.damage; + } + tower.lastAttackTime = timestamp; if (target.currentHealth <= 0) { diff --git a/html/tower/js/renderer.js b/html/tower/js/renderer.js index 24a18ef..ddae51d 100644 --- a/html/tower/js/renderer.js +++ b/html/tower/js/renderer.js @@ -147,16 +147,56 @@ function renderParticles(ctx, particles) { if (lifePercent <= 1) { ctx.globalAlpha = 1 - lifePercent; - ctx.fillStyle = particle.color; - ctx.beginPath(); - ctx.arc( - particle.position.x, - particle.position.y, - particle.size * (1 - lifePercent), - 0, - Math.PI * 2 - ); - ctx.fill(); + + if (particle.type === 'AOE_EXPLOSION') { + // Draw expanding circle + const radius = particle.initialRadius + + (particle.finalRadius - particle.initialRadius) * lifePercent; + + // Draw multiple rings for better effect + const numRings = 3; + for (let i = 0; i < numRings; i++) { + const ringRadius = radius * (1 - (i * 0.2)); + const ringAlpha = (1 - lifePercent) * (1 - (i * 0.3)); + + ctx.beginPath(); + ctx.arc( + particle.position.x, + particle.position.y, + ringRadius, + 0, + Math.PI * 2 + ); + ctx.strokeStyle = particle.color; + ctx.lineWidth = particle.ringWidth * (1 - (i * 0.2)); + ctx.globalAlpha = ringAlpha; + ctx.stroke(); + } + + // Draw affected area + ctx.beginPath(); + ctx.arc( + particle.position.x, + particle.position.y, + radius, + 0, + Math.PI * 2 + ); + ctx.fillStyle = particle.color + '20'; // Very transparent fill + ctx.fill(); + } else { + // Original particle rendering + ctx.fillStyle = particle.color; + ctx.beginPath(); + ctx.arc( + particle.position.x, + particle.position.y, + particle.size * (1 - lifePercent), + 0, + Math.PI * 2 + ); + ctx.fill(); + } } }); ctx.globalAlpha = 1; |