User prompt
Ya no suena cuando construyo la trompeta
User prompt
pero al momento de construir la trompeta quiero que siga sonando normal
User prompt
Solo el pòryectil de la trompeta, que suene un 1%
User prompt
Quiero que el volumen de proyectil de la trompeta suene a un 5%
User prompt
Quiero que al construir una torre trompeta suene ese sonido, tambien cuando ataca
User prompt
Quiero que la torre de trompeta haga un sonido especifico al atacar y ser construida, (que sea el mismo sonido) con la diferencia de que en assets el sonido se llame sonido trompeta
User prompt
Quiero que el proyectil que suelten las torres (instrumentos) sea aleatorio entre todos los tipos de bullet (proyectil) que hay, ademas quiero que la estadistica de oro y de vidas sea mas grande y vistozo ademas de que wave 4 este ubicado abajo a ola izquiera
User prompt
Los numeros pares de tambores que sigo poniendo (ejemplo tambor numero 2, tambor numero 4, etc, etc...) siguen sin atacar
User prompt
A veces cuando construyo un tambor no ataca arregla eso, ademas quiero que los precios se vean un poco mas grande ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
En el menu de inicio se sobreponen las tablas de madera arregla eso, ademas quiero que el interfaz de eleccion de torre sea circular, sigo sin poder construir tambores arregla eso ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Que el wave 1 solo se vea al inicio de la partida justo despues de el level 1 go ademas de reubicar de forma que de a los caminos las plataformas ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Quiero que el icono del oro se llame gold en assets y tambien el de vidas que se llame lives en assets, ademas quiero que suene la musica de fondo que llame "1" en assets al inciar el juego de musica, ademas quieroq ue ubiques bien los lugares donde se pueden construir torres
User prompt
Ahora quiero que en la parte de gold haya un icono en lugar de la palabra, en lives que sea otro icono y que wave sea mas vistozo, tabmein al iniciar el juego queiro que diga level 1, Go! ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
tengo un problema, el tutorial no se alcanza a leer ya que lo cubre las tablas de madera, ademas no me deja construir mas de un tambor
User prompt
Quiero que los enemigos hagan una aniamcion de caminar,a demas de añadir un menu principal donde pongas start y tambien exista un boton de tutorial por donde se pueda ingresar a un tutorial de como jugar donde se explique como poner torres y donde. como ultima orden quiero que hagas 5 diferentes estilos de proyectil ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Quiero que de fondo de todo este una tabla gigante (que este debajo de todo) ademas de reorganizar los lugares donde se pueden poner las torres de forma logica
User prompt
Que se vea mas estetico, que la ubicacion de las cosas tengan sentido
User prompt
Ahora quiero que inviertas el camino de los enemigos en lugar de ir de arriba hacia abajo quiero que vayan de abajo ahcia arriba, ademas de que quiero que llenes con algo el faltante de escenario que se ve un poco vacio
User prompt
Que todo el camino este conectado de buena forma, ademas quiero que quites ya toda la madera exceptuando el camino
User prompt
Quiero que el camino que sigan sea mas bonito y que sea de madera
User prompt
Ahora te voy a pasar una serie de costos, daño, velocidad de ataque y cantidad de torres: 🎺 TORRES MUSICALES (x5) Tambor Básico Percusión 15 Rápido (0.5s) Corto 50 Golpea a enemigos cercanos en área pequeña. Ideal para early game. Trompeta de Choque Viento 35 Medio (1s) Medio 80 Empuja levemente al enemigo golpeado. Guitarra Eléctrica Cuerda eléctrica 20 x 3 (Cadena) Lento (1.5s) Largo 120 Rebota el ataque hasta 3 enemigos. Violín Congelante Cuerda clásica 10 Medio (1s) Largo 100 25% de chance de ralentizar por 2s. DJ Ritmico Electrónica / Boss 50 Muy lento (2.5s) Grande 200 Ataque en área + ciega brevemente a enemigos (reduce su velocidad).
User prompt
si haz eso
User prompt
Si, haz eso ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Ajusta la posicion
User prompt
Haz la opcion mas optima y conveniente ↪💡 Consider importing and using the following plugins: @upit/tween.v1
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ var BuildSpot = Container.expand(function () { var self = Container.call(this); var spotGraphics = self.attachAsset('buildSpot', { anchorX: 0.5, anchorY: 0.5 }); self.occupied = false; self.down = function (x, y, obj) { console.log("Build spot clicked, occupied:", self.occupied, "showingBuildMenu:", showingBuildMenu); if (!self.occupied && !showingBuildMenu) { console.log("Showing build menu for spot at:", self.x, self.y); showBuildMenu(self); } }; return self; }); var Bullet = Container.expand(function (startX, startY, target, damage, towerType, specialData) { var self = Container.call(this); // Choose random bullet asset from all available types var bulletTypes = ['bullet', 'drumBullet', 'trumpetBullet', 'guitarBullet', 'violinBullet', 'djBullet']; var bulletAsset = bulletTypes[Math.floor(Math.random() * bulletTypes.length)]; var bulletGraphics = self.attachAsset(bulletAsset, { anchorX: 0.5, anchorY: 0.5 }); self.x = startX; self.y = startY; self.target = target; self.damage = damage; self.speed = 8; self.towerType = towerType || 'drum'; self.specialData = specialData || {}; self.hitTargets = []; // For chain attacks self.update = function () { if (!self.target || self.target.health <= 0) { self.destroy(); return; } var dx = self.target.x - self.x; var dy = self.target.y - self.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance < 20) { // Hit target var died = false; // Handle different tower effects if (self.towerType === 'drum') { // Area damage around target died = self.target.takeDamage(self.damage); // Damage other enemies in area for (var i = 0; i < enemies.length; i++) { var enemy = enemies[i]; if (enemy !== self.target) { var dx2 = enemy.x - self.target.x; var dy2 = enemy.y - self.target.y; var areaDist = Math.sqrt(dx2 * dx2 + dy2 * dy2); if (areaDist <= (self.specialData.areaRadius || 60)) { enemy.takeDamage(self.damage); } } } } else if (self.towerType === 'trumpet') { // Damage and pushback died = self.target.takeDamage(self.damage); // Apply pushback effect if (!died && self.target.pathIndex < pathPoints.length - 2) { self.target.pathIndex = Math.max(0, self.target.pathIndex - 1); } } else if (self.towerType === 'guitar') { // Chain attack died = self.target.takeDamage(self.damage); self.hitTargets.push(self.target); var chainsLeft = (self.specialData.chainCount || 3) - self.hitTargets.length; if (chainsLeft > 0) { // Find next target for chain var nextTarget = null; var closestDist = 150; // Chain range for (var i = 0; i < enemies.length; i++) { var enemy = enemies[i]; if (self.hitTargets.indexOf(enemy) === -1 && enemy.health > 0) { var dx2 = enemy.x - self.target.x; var dy2 = enemy.y - self.target.y; var chainDist = Math.sqrt(dx2 * dx2 + dy2 * dy2); if (chainDist < closestDist) { nextTarget = enemy; closestDist = chainDist; } } } if (nextTarget) { self.target = nextTarget; return; // Continue to next target } } } else if (self.towerType === 'violin') { // Damage with slow chance died = self.target.takeDamage(self.damage); if (!died && Math.random() < (self.specialData.slowChance || 0.25)) { self.target.slowedUntil = LK.ticks + (self.specialData.slowDuration || 120); } } else if (self.towerType === 'dj') { // Area damage with blind effect died = self.target.takeDamage(self.damage); // Damage and blind other enemies in large area for (var i = 0; i < enemies.length; i++) { var enemy = enemies[i]; var dx2 = enemy.x - self.target.x; var dy2 = enemy.y - self.target.y; var areaDist = Math.sqrt(dx2 * dx2 + dy2 * dy2); if (areaDist <= (self.specialData.areaRadius || 120)) { if (enemy !== self.target) { enemy.takeDamage(self.damage * 0.8); // Reduced area damage } // Apply blind effect (reduce speed) enemy.blindedUntil = LK.ticks + 60; // 1 second blind } } } else { // Default damage died = self.target.takeDamage(self.damage); } if (died) { gold += self.target.goldValue; updateUI(); LK.getSound('enemyDeath').play(); } self.destroy(); } else { self.x += dx / distance * self.speed; self.y += dy / distance * self.speed; } }; return self; }); var Enemy = Container.expand(function () { var self = Container.call(this); var enemyGraphics = self.attachAsset('enemy', { anchorX: 0.5, anchorY: 0.5 }); self.health = 100; self.maxHealth = 100; self.speed = 2; self.pathIndex = 0; self.goldValue = 25; self.walkAnimationTimer = 0; self.originalScale = 1.0; self.takeDamage = function (damage) { self.health -= damage; if (self.health <= 0) { self.health = 0; return true; // Enemy died } // Flash red when hit tween(enemyGraphics, { tint: 0xff0000 }, { duration: 100, onFinish: function onFinish() { tween(enemyGraphics, { tint: 0xffffff }, { duration: 100 }); } }); return false; }; self.update = function () { // Walking animation - bobbing effect self.walkAnimationTimer += 0.2; var walkBob = Math.sin(self.walkAnimationTimer) * 0.1; enemyGraphics.scaleY = self.originalScale + walkBob; enemyGraphics.scaleX = self.originalScale + walkBob * 0.5; enemyGraphics.rotation = Math.sin(self.walkAnimationTimer * 1.5) * 0.05; if (self.pathIndex < pathPoints.length - 1) { var targetPoint = pathPoints[self.pathIndex + 1]; var dx = targetPoint.x - self.x; var dy = targetPoint.y - self.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance < 10) { self.pathIndex++; if (self.pathIndex >= pathPoints.length - 1) { // Reached goal lives--; updateUI(); if (lives <= 0) { LK.showGameOver(); } } } else { // Calculate current speed with effects var currentSpeed = self.speed; // Apply slow effect from violin if (self.slowedUntil && LK.ticks < self.slowedUntil) { currentSpeed *= 0.5; // 50% speed when slowed } // Apply blind effect from DJ (further speed reduction) if (self.blindedUntil && LK.ticks < self.blindedUntil) { currentSpeed *= 0.3; // 30% speed when blinded } self.x += dx / distance * currentSpeed; self.y += dy / distance * currentSpeed; } } }; return self; }); var Tower = Container.expand(function (towerType) { var self = Container.call(this); self.towerType = towerType || 'drum'; var assetName = self.towerType + 'Tower'; var towerGraphics = self.attachAsset(assetName, { anchorX: 0.5, anchorY: 0.5 }); // Tower properties based on type if (self.towerType === 'drum') { self.damage = 15; self.range = 120; // Short range self.fireRate = 30; // Fast (0.5s at 60fps) self.cost = 50; self.areaRadius = 60; // Small area for drum } else if (self.towerType === 'trumpet') { self.damage = 35; self.range = 180; // Medium range self.fireRate = 60; // Medium (1s at 60fps) self.cost = 80; self.pushback = true; } else if (self.towerType === 'guitar') { self.damage = 20; self.range = 220; // Long range self.fireRate = 90; // Slow (1.5s at 60fps) self.cost = 120; self.chainCount = 3; } else if (self.towerType === 'violin') { self.damage = 10; self.range = 220; // Long range self.fireRate = 60; // Medium (1s at 60fps) self.cost = 100; self.slowChance = 0.25; // 25% chance self.slowDuration = 120; // 2s at 60fps } else if (self.towerType === 'dj') { self.damage = 50; self.range = 200; // Large area self.fireRate = 150; // Very slow (2.5s at 60fps) self.cost = 200; self.areaRadius = 120; // Large area self.blindEffect = true; } self.lastFire = self.fireRate; // Initialize to fireRate to allow immediate first shot after properties are set self.findTarget = function () { var closestEnemy = null; var closestDistance = self.range; for (var i = 0; i < enemies.length; i++) { var enemy = enemies[i]; var dx = enemy.x - self.x; var dy = enemy.y - self.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance <= self.range && distance < closestDistance) { closestEnemy = enemy; closestDistance = distance; } } return closestEnemy; }; self.fire = function (target) { var specialData = { areaRadius: self.areaRadius, chainCount: self.chainCount, slowChance: self.slowChance, slowDuration: self.slowDuration }; var bullet = new Bullet(self.x, self.y, target, self.damage, self.towerType, specialData); bullets.push(bullet); game.addChild(bullet); // Play specific sound for trumpet towers if (self.towerType === 'trumpet') { LK.getSound('sonidotrompeta').play(); } else { LK.getSound('hit').play(); } }; self.update = function () { self.lastFire++; if (self.lastFire >= self.fireRate) { var target = self.findTarget(); if (target && target.health > 0) { self.fire(target); self.lastFire = 0; // Add visual firing effect tween(towerGraphics, { scaleX: 1.2, scaleY: 1.2 }, { duration: 100, onFinish: function onFinish() { tween(towerGraphics, { scaleX: 1.0, scaleY: 1.0 }, { duration: 100 }); } }); } } }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x8B4513 }); /**** * Game Code ****/ // Game variables var gameState = 'menu'; // 'menu', 'tutorial', 'playing' var tutorialStep = 0; var menuContainer; var tutorialContainer; // Game Elements var enemies = []; var towers = []; var bullets = []; var buildSpots = []; var gold = 500; var lives = 20; var wave = 1; var enemiesSpawned = 0; var enemiesPerWave = 10; var spawnTimer = 0; var waveStarted = false; var showingBuildMenu = false; var selectedBuildSpot = null; var backgroundElements = []; var floatingNotes = []; // === GIANT WOODEN TABLE BACKGROUND === // Create a large wooden table that covers the entire game area as the base var giantTable = game.addChild(LK.getAsset('woodPanel', { anchorX: 0.5, anchorY: 0.5 })); giantTable.x = 1024; giantTable.y = 1366; giantTable.scaleX = 5.0; // Scale to cover full width giantTable.scaleY = 6.0; // Scale to cover full height giantTable.tint = 0x8B4513; // Rich wooden brown color giantTable.alpha = 0.3; // Semi-transparent so other elements are visible backgroundElements.push(giantTable); // === STAGE AREA (Top section of concert hall) === // Main stage backdrop var stage = game.addChild(LK.getAsset('stage', { anchorX: 0.5, anchorY: 1 })); stage.x = 1024; stage.y = 350; stage.scaleX = 0.9; stage.scaleY = 0.8; backgroundElements.push(stage); // Stage curtain backdrop var stageBackdrop = game.addChild(LK.getAsset('curtain', { anchorX: 0.5, anchorY: 0 })); stageBackdrop.x = 1024; stageBackdrop.y = 30; stageBackdrop.scaleX = 1.2; stageBackdrop.scaleY = 0.7; backgroundElements.push(stageBackdrop); // Orchestra pit and performance area var orchestraPit = game.addChild(LK.getAsset('orchestraPit', { anchorX: 0.5, anchorY: 1 })); orchestraPit.x = 1024; orchestraPit.y = 450; orchestraPit.scaleX = 0.8; orchestraPit.scaleY = 0.6; backgroundElements.push(orchestraPit); // Grand piano in orchestra pit var grandPiano = game.addChild(LK.getAsset('grandPiano', { anchorX: 0.5, anchorY: 0.5 })); grandPiano.x = 900; grandPiano.y = 400; grandPiano.scaleX = 0.8; grandPiano.scaleY = 0.8; backgroundElements.push(grandPiano); // Conductor podium var conductor = game.addChild(LK.getAsset('conductor', { anchorX: 0.5, anchorY: 1 })); conductor.x = 1024; conductor.y = 420; conductor.scaleX = 0.8; conductor.scaleY = 0.8; backgroundElements.push(conductor); // Music stands arranged in orchestra pit for (var i = 0; i < 6; i++) { var musicStand = game.addChild(LK.getAsset('musicStand', { anchorX: 0.5, anchorY: 1 })); musicStand.x = 750 + i * 90; musicStand.y = 440; musicStand.scaleX = 0.6; musicStand.scaleY = 0.8; backgroundElements.push(musicStand); } // === UPPER BALCONIES AND VIP AREAS === // Main balconies positioned logically for (var i = 0; i < 2; i++) { var balcony = game.addChild(LK.getAsset('balcony', { anchorX: 0.5, anchorY: 0.5 })); balcony.x = 400 + i * 1200; balcony.y = 600; balcony.scaleX = 0.7; balcony.scaleY = 0.6; backgroundElements.push(balcony); // Royal crests for main balconies var crest = game.addChild(LK.getAsset('royalCrest', { anchorX: 0.5, anchorY: 0.5 })); crest.x = balcony.x; crest.y = balcony.y - 60; crest.scaleX = 0.5; crest.scaleY = 0.5; backgroundElements.push(crest); } // VIP boxes on middle level for (var i = 0; i < 3; i++) { var vipBox = game.addChild(LK.getAsset('vipBox', { anchorX: 0.5, anchorY: 0.5 })); vipBox.x = 300 + i * 700; vipBox.y = 800; vipBox.scaleX = 0.6; vipBox.scaleY = 0.5; backgroundElements.push(vipBox); } // === LIGHTING AND ATMOSPHERE === // Chandeliers positioned strategically for (var i = 0; i < 4; i++) { var chandelier = game.addChild(LK.getAsset('chandelier', { anchorX: 0.5, anchorY: 0.5 })); chandelier.x = 400 + i * 400; chandelier.y = 120; chandelier.scaleX = 0.8; chandelier.scaleY = 0.8; backgroundElements.push(chandelier); // Chandelier swaying animation tween(chandelier, { rotation: 0.08 }, { duration: 2500, easing: tween.easeInOut, onFinish: function onFinish() { tween(chandelier, { rotation: -0.08 }, { duration: 2500, easing: tween.easeInOut, onFinish: arguments.callee }); } }); } // Spotlights for stage lighting for (var i = 0; i < 5; i++) { var spotlight = game.addChild(LK.getAsset('spotlight', { anchorX: 0.5, anchorY: 0.5 })); spotlight.x = 500 + i * 200; spotlight.y = 280; spotlight.scaleX = 0.7; spotlight.scaleY = 0.7; backgroundElements.push(spotlight); // Spotlight pulsing effect tween(spotlight, { alpha: 0.4 }, { duration: 1800 + Math.random() * 800, easing: tween.easeInOut, onFinish: function onFinish() { tween(spotlight, { alpha: 1.0 }, { duration: 1800 + Math.random() * 800, easing: tween.easeInOut, onFinish: arguments.callee }); } }); } // === STRUCTURAL ELEMENTS === // Supporting pillars var leftPillar = game.addChild(LK.getAsset('pillar', { anchorX: 0.5, anchorY: 1 })); leftPillar.x = 200; leftPillar.y = 1200; leftPillar.scaleX = 0.6; leftPillar.scaleY = 1.0; backgroundElements.push(leftPillar); var rightPillar = game.addChild(LK.getAsset('pillar', { anchorX: 0.5, anchorY: 1 })); rightPillar.x = 1848; rightPillar.y = 1200; rightPillar.scaleX = 0.6; rightPillar.scaleY = 1.0; backgroundElements.push(rightPillar); // Decorative archways for (var i = 0; i < 2; i++) { var leftArch = game.addChild(LK.getAsset('archDetail', { anchorX: 0, anchorY: 0.5 })); leftArch.x = 100; leftArch.y = 1200 + i * 500; leftArch.scaleX = 1.2; leftArch.scaleY = 1.0; leftArch.rotation = Math.PI / 2; backgroundElements.push(leftArch); var rightArch = game.addChild(LK.getAsset('archDetail', { anchorX: 1, anchorY: 0.5 })); rightArch.x = 1948; rightArch.y = 1200 + i * 500; rightArch.scaleX = 1.2; rightArch.scaleY = 1.0; rightArch.rotation = -Math.PI / 2; backgroundElements.push(rightArch); } // === AUDIENCE SEATING AREAS === // Main seating section for (var row = 0; row < 6; row++) { for (var seat = 0; seat < 14; seat++) { var seatObj = game.addChild(LK.getAsset('seat', { anchorX: 0.5, anchorY: 0.5 })); seatObj.x = 350 + seat * 100; seatObj.y = 2000 + row * 60; seatObj.scaleX = 0.8; seatObj.scaleY = 0.8; backgroundElements.push(seatObj); // Subtle audience movement animation var delayTime = Math.random() * 8000 + 3000; LK.setTimeout(function () { function animateSeat() { tween(seatObj, { scaleY: 0.85, y: seatObj.y + 1 }, { duration: 2000 + Math.random() * 1000, easing: tween.easeInOut, onFinish: function onFinish() { tween(seatObj, { scaleY: 0.8, y: seatObj.y - 1 }, { duration: 2000 + Math.random() * 1000, easing: tween.easeInOut, onFinish: function onFinish() { if (Math.random() < 0.2) { LK.setTimeout(animateSeat, Math.random() * 10000 + 5000); } } }); } }); } animateSeat(); }, delayTime); } } // Upper level seating for (var row = 0; row < 3; row++) { for (var seat = 0; seat < 10; seat++) { var upperSeat = game.addChild(LK.getAsset('seat', { anchorX: 0.5, anchorY: 0.5 })); upperSeat.x = 500 + seat * 100; upperSeat.y = 950 + row * 50; upperSeat.scaleX = 0.6; upperSeat.scaleY = 0.6; backgroundElements.push(upperSeat); } } // === DECORATIVE LIGHTING === // Elegant candelabras positioned throughout for (var i = 0; i < 6; i++) { var candelabra = game.addChild(LK.getAsset('candelabra', { anchorX: 0.5, anchorY: 1 })); candelabra.x = 400 + i * 200; candelabra.y = 1600; candelabra.scaleX = 0.9; candelabra.scaleY = 1.1; backgroundElements.push(candelabra); // Flickering flame effect tween(candelabra, { scaleY: 1.15, alpha: 0.85 }, { duration: 1000 + Math.random() * 500, easing: tween.easeInOut, onFinish: function onFinish() { tween(candelabra, { scaleY: 1.1, alpha: 1.0 }, { duration: 1000 + Math.random() * 500, easing: tween.easeInOut, onFinish: arguments.callee }); } }); } // Wall-mounted lighting for (var i = 0; i < 4; i++) { var wallCandelabra = game.addChild(LK.getAsset('candelabra', { anchorX: 0.5, anchorY: 0.5 })); wallCandelabra.x = 150; wallCandelabra.y = 1000 + i * 300; wallCandelabra.scaleX = 0.7; wallCandelabra.scaleY = 0.8; backgroundElements.push(wallCandelabra); var rightWallCandelabra = game.addChild(LK.getAsset('candelabra', { anchorX: 0.5, anchorY: 0.5 })); rightWallCandelabra.x = 1898; rightWallCandelabra.y = 1000 + i * 300; rightWallCandelabra.scaleX = 0.7; rightWallCandelabra.scaleY = 0.8; backgroundElements.push(rightWallCandelabra); // Synchronized flickering for wall candelabras tween(wallCandelabra, { rotation: 0.03, alpha: 0.9 }, { duration: 1500 + Math.random() * 700, easing: tween.easeInOut, onFinish: function onFinish() { tween(wallCandelabra, { rotation: -0.03, alpha: 1.0 }, { duration: 1500 + Math.random() * 700, easing: tween.easeInOut, onFinish: arguments.callee }); } }); tween(rightWallCandelabra, { rotation: -0.03, alpha: 0.9 }, { duration: 1500 + Math.random() * 700, easing: tween.easeInOut, onFinish: function onFinish() { tween(rightWallCandelabra, { rotation: 0.03, alpha: 1.0 }, { duration: 1500 + Math.random() * 700, easing: tween.easeInOut, onFinish: arguments.callee }); } }); } // === ENTRANCE AREA === // Grand entrance architecture var entranceArch = game.addChild(LK.getAsset('archDetail', { anchorX: 0.5, anchorY: 1 })); entranceArch.x = 1750; entranceArch.y = 2732; entranceArch.scaleX = 2.5; entranceArch.scaleY = 1.8; backgroundElements.push(entranceArch); // Entrance pillars var leftEntrancePillar = game.addChild(LK.getAsset('pillar', { anchorX: 0.5, anchorY: 1 })); leftEntrancePillar.x = 1600; leftEntrancePillar.y = 2732; leftEntrancePillar.scaleX = 0.7; leftEntrancePillar.scaleY = 1.0; backgroundElements.push(leftEntrancePillar); var rightEntrancePillar = game.addChild(LK.getAsset('pillar', { anchorX: 0.5, anchorY: 1 })); rightEntrancePillar.x = 1900; rightEntrancePillar.y = 2732; rightEntrancePillar.scaleX = 0.7; rightEntrancePillar.scaleY = 1.0; backgroundElements.push(rightEntrancePillar); // Entrance lighting for (var i = 0; i < 3; i++) { var entranceCandelabra = game.addChild(LK.getAsset('candelabra', { anchorX: 0.5, anchorY: 1 })); entranceCandelabra.x = 1600 + i * 150; entranceCandelabra.y = 2550; entranceCandelabra.scaleX = 1.0; entranceCandelabra.scaleY = 1.3; backgroundElements.push(entranceCandelabra); // Flickering effect for entrance lighting tween(entranceCandelabra, { scaleY: 1.35, alpha: 0.95 }, { duration: 1200 + Math.random() * 600, easing: tween.easeInOut, onFinish: function onFinish() { tween(entranceCandelabra, { scaleY: 1.3, alpha: 1.0 }, { duration: 1200 + Math.random() * 600, easing: tween.easeInOut, onFinish: arguments.callee }); } }); } // === CURTAINS AND DRAPING === // Side curtains for proper hall framing var leftCurtain = game.addChild(LK.getAsset('curtain', { anchorX: 0, anchorY: 0 })); leftCurtain.x = 0; leftCurtain.y = 0; leftCurtain.scaleX = 0.5; leftCurtain.scaleY = 1.2; backgroundElements.push(leftCurtain); var rightCurtain = game.addChild(LK.getAsset('curtain', { anchorX: 1, anchorY: 0 })); rightCurtain.x = 2048; rightCurtain.y = 0; rightCurtain.scaleX = 0.5; rightCurtain.scaleY = 1.2; backgroundElements.push(rightCurtain); // === CONDUCTOR ANIMATION === // Conductor movement for liveliness tween(conductor, { rotation: 0.06 }, { duration: 1800, easing: tween.easeInOut, onFinish: function onFinish() { tween(conductor, { rotation: -0.06 }, { duration: 1800, easing: tween.easeInOut, onFinish: arguments.callee }); } }); // Function to create floating musical notes function createFloatingNote() { var note = game.addChild(LK.getAsset('musicNote', { anchorX: 0.5, anchorY: 0.5 })); note.x = Math.random() * 2048; note.y = 2732 + 100; note.alpha = 0.6; floatingNotes.push(note); // Animate note floating upward tween(note, { y: -100, rotation: Math.PI * 2, alpha: 0 }, { duration: 8000 + Math.random() * 4000, easing: tween.easeOut, onFinish: function onFinish() { if (note.parent) { note.destroy(); } var index = floatingNotes.indexOf(note); if (index > -1) { floatingNotes.splice(index, 1); } } }); } // Create initial floating notes for (var i = 0; i < 5; i++) { LK.setTimeout(function () { createFloatingNote(); }, Math.random() * 3000); } // === MAIN MENU === menuContainer = new Container(); // Add menu container after all background elements to ensure it appears on top game.addChild(menuContainer); var menuBackground = menuContainer.addChild(LK.getAsset('woodPanel', { anchorX: 0.5, anchorY: 0.5 })); menuBackground.x = 1024; menuBackground.y = 1366; menuBackground.scaleX = 4.5; menuBackground.scaleY = 6; menuBackground.alpha = 0.95; menuBackground.tint = 0x3D2914; var titleText = menuContainer.addChild(new Text2('CONCERT HALL DEFENSE', { size: 120, fill: 0xFFD700 })); titleText.anchor.set(0.5, 0.5); titleText.x = 1024; titleText.y = 800; var startButton = menuContainer.addChild(LK.getAsset('djTower', { anchorX: 0.5, anchorY: 0.5 })); startButton.x = 1024; startButton.y = 1200; startButton.scaleX = 1.5; startButton.scaleY = 1.5; var startText = menuContainer.addChild(new Text2('START GAME', { size: 80, fill: 0xFFFFFF })); startText.anchor.set(0.5, 0.5); startText.x = 1024; startText.y = 1320; var tutorialButton = menuContainer.addChild(LK.getAsset('violinTower', { anchorX: 0.5, anchorY: 0.5 })); tutorialButton.x = 1024; tutorialButton.y = 1500; tutorialButton.scaleX = 1.5; tutorialButton.scaleY = 1.5; var tutorialText = menuContainer.addChild(new Text2('TUTORIAL', { size: 80, fill: 0xFFFFFF })); tutorialText.anchor.set(0.5, 0.5); tutorialText.x = 1024; tutorialText.y = 1620; startButton.down = function () { gameState = 'playing'; menuContainer.visible = false; startNextWave(); }; tutorialButton.down = function () { gameState = 'tutorial'; tutorialStep = 0; menuContainer.visible = false; showTutorial(); }; // === TUTORIAL SYSTEM === tutorialContainer = new Container(); tutorialContainer.visible = false; // Add tutorial container after all background elements to ensure it appears on top game.addChild(tutorialContainer); var tutorialBackground = tutorialContainer.addChild(LK.getAsset('woodPanel', { anchorX: 0.5, anchorY: 0.5 })); tutorialBackground.x = 1024; tutorialBackground.y = 1366; tutorialBackground.scaleX = 4.5; tutorialBackground.scaleY = 5.5; tutorialBackground.alpha = 0.95; tutorialBackground.tint = 0x8B4513; var tutorialTitleText = tutorialContainer.addChild(new Text2('TUTORIAL', { size: 100, fill: 0xFFD700 })); tutorialTitleText.anchor.set(0.5, 0.5); tutorialTitleText.x = 1024; tutorialTitleText.y = 400; var tutorialStepText = tutorialContainer.addChild(new Text2('', { size: 60, fill: 0xFFFFFF })); tutorialStepText.anchor.set(0.5, 0.5); tutorialStepText.x = 1024; tutorialStepText.y = 1000; var nextButton = tutorialContainer.addChild(LK.getAsset('guitarTower', { anchorX: 0.5, anchorY: 0.5 })); nextButton.x = 1200; nextButton.y = 1600; var nextButtonText = tutorialContainer.addChild(new Text2('NEXT', { size: 60, fill: 0xFFFFFF })); nextButtonText.anchor.set(0.5, 0.5); nextButtonText.x = 1200; nextButtonText.y = 1680; var backButton = tutorialContainer.addChild(LK.getAsset('drumTower', { anchorX: 0.5, anchorY: 0.5 })); backButton.x = 848; backButton.y = 1600; var backButtonText = tutorialContainer.addChild(new Text2('BACK TO MENU', { size: 60, fill: 0xFFFFFF })); backButtonText.anchor.set(0.5, 0.5); backButtonText.x = 848; backButtonText.y = 1680; var tutorialSteps = ['Welcome to Concert Hall Defense!\nProtect the stage from invading enemies.', 'Enemies follow the wooden path from bottom to top.\nThey want to disrupt the concert!', 'Click on build spots (circular areas) to place towers.\nEach tower has different abilities and costs.', 'DRUM TOWERS ($50): Fast firing with area damage.\nGreat for groups of enemies.', 'TRUMPET TOWERS ($80): Push enemies back down the path.\nUse to buy more time.', 'GUITAR TOWERS ($120): Chain lightning between enemies.\nEffective against clustered foes.', 'VIOLIN TOWERS ($100): Slow enemies with magical music.\nPerfect for crowd control.', 'DJ TOWERS ($200): Massive area damage with blinding effects.\nExpensive but very powerful.', 'Place towers strategically around the path.\nElevated positions like balconies give better coverage.', 'You earn gold by defeating enemies.\nUse it wisely to build your defense!', 'Good luck defending the concert hall!\nThe show must go on!']; function showTutorial() { tutorialContainer.visible = true; // Move tutorial container to front to ensure visibility game.removeChild(tutorialContainer); game.addChild(tutorialContainer); updateTutorialStep(); } function updateTutorialStep() { if (tutorialStep < tutorialSteps.length) { tutorialStepText.setText(tutorialSteps[tutorialStep]); nextButtonText.setText(tutorialStep === tutorialSteps.length - 1 ? 'START GAME' : 'NEXT'); } else { gameState = 'playing'; tutorialContainer.visible = false; startNextWave(); } } nextButton.down = function () { tutorialStep++; if (tutorialStep >= tutorialSteps.length) { gameState = 'playing'; tutorialContainer.visible = false; startNextWave(); } else { updateTutorialStep(); } }; backButton.down = function () { gameState = 'menu'; tutorialContainer.visible = false; menuContainer.visible = true; }; // Path definition - reversed to go from bottom to top var pathPoints = [{ x: 1750, y: 2250 }, { x: 1700, y: 2100 }, { x: 1650, y: 1950 }, { x: 1550, y: 1800 }, { x: 1400, y: 1750 }, { x: 1250, y: 1700 }, { x: 1100, y: 1650 }, { x: 950, y: 1600 }, { x: 800, y: 1550 }, { x: 650, y: 1500 }, { x: 500, y: 1450 }, { x: 350, y: 1400 }, { x: 200, y: 1300 }, { x: 100, y: 1150 }, { x: 200, y: 1000 }, { x: 350, y: 950 }, { x: 500, y: 900 }, { x: 650, y: 800 }, { x: 700, y: 650 }, { x: 650, y: 500 }, { x: 500, y: 400 }, { x: 350, y: 300 }, { x: 200, y: 300 }, { x: 50, y: 300 }]; // Create elegant wooden walkway with proper connectivity for (var i = 0; i < pathPoints.length; i++) { var pathNode = game.addChild(LK.getAsset('woodPanel', { anchorX: 0.5, anchorY: 0.5 })); pathNode.x = pathPoints[i].x; pathNode.y = pathPoints[i].y; pathNode.scaleX = 0.4; pathNode.scaleY = 0.4; pathNode.alpha = 0.95; pathNode.tint = 0xD2691E; // Warm wood color // Calculate rotation based on path direction for better connectivity if (i < pathPoints.length - 1) { var dx = pathPoints[i + 1].x - pathPoints[i].x; var dy = pathPoints[i + 1].y - pathPoints[i].y; pathNode.rotation = Math.atan2(dy, dx); } else if (i > 0) { var dx = pathPoints[i].x - pathPoints[i - 1].x; var dy = pathPoints[i].y - pathPoints[i - 1].y; pathNode.rotation = Math.atan2(dy, dx); } // Add gentle animation to make the wooden path feel alive tween(pathNode, { scaleX: 0.42, alpha: 1.0 }, { duration: 2000 + Math.random() * 1000, easing: tween.easeInOut, onFinish: function onFinish() { tween(pathNode, { scaleX: 0.4, alpha: 0.95 }, { duration: 2000 + Math.random() * 1000, easing: tween.easeInOut, onFinish: arguments.callee }); } }); // Add connecting wooden planks between path points for better continuity if (i < pathPoints.length - 1) { var distance = Math.sqrt(Math.pow(pathPoints[i + 1].x - pathPoints[i].x, 2) + Math.pow(pathPoints[i + 1].y - pathPoints[i].y, 2)); var numConnectors = Math.floor(distance / 80); // Add connectors every 80 pixels for (var j = 1; j <= numConnectors; j++) { var ratio = j / (numConnectors + 1); var connectorX = pathPoints[i].x + (pathPoints[i + 1].x - pathPoints[i].x) * ratio; var connectorY = pathPoints[i].y + (pathPoints[i + 1].y - pathPoints[i].y) * ratio; var connector = game.addChild(LK.getAsset('woodPanel', { anchorX: 0.5, anchorY: 0.5 })); connector.x = connectorX; connector.y = connectorY; connector.scaleX = 0.3; connector.scaleY = 0.3; connector.alpha = 0.8; connector.tint = 0xCD853F; // Slightly different wood tone for variety var dx = pathPoints[i + 1].x - pathPoints[i].x; var dy = pathPoints[i + 1].y - pathPoints[i].y; connector.rotation = Math.atan2(dy, dx) + (Math.random() - 0.5) * 0.2; } } } // Create goal var goal = game.addChild(LK.getAsset('goal', { anchorX: 0.5, anchorY: 0.5 })); goal.x = pathPoints[pathPoints.length - 1].x; goal.y = pathPoints[pathPoints.length - 1].y; // Create strategic build spots positioned for logical tower defense gameplay around the wooden path var buildPositions = [{ // Stage area - premium elevated positions for long-range towers x: 450, y: 280 // Left stage position, overlooks early path }, { x: 550, y: 350 // Behind conductor, central elevated }, { // Path curve coverage near goal area x: 100, y: 450 // Covers final path curve to goal }, { x: 350, y: 550 // Path curve interception point }, { // Mid-path strategic positions x: 800, y: 750 // Covers central path segment }, { x: 500, y: 1050 // Left side path coverage }, { x: 300, y: 1250 // Path bend coverage }, { // Path approach and turn coverage x: 100, y: 1450 // Covers path turns and approach }, { x: 450, y: 1350 // Central defensive position }, { // Lower path defensive line x: 850, y: 1450 // Right side path coverage }, { x: 1200, y: 1550 // Mid-lower path position }, { x: 1450, y: 1650 // Path turn coverage }, { // Final approach defense x: 1350, y: 1850 // Late stage interception }, { x: 1550, y: 2000 // Final bend coverage }, { // Entrance area coverage x: 1600, y: 2150 // Near entrance, early defense }, { x: 1850, y: 2300 // Entrance approach }]; for (var i = 0; i < buildPositions.length; i++) { var buildSpot = new BuildSpot(); buildSpot.x = buildPositions[i].x; buildSpot.y = buildPositions[i].y; buildSpots.push(buildSpot); game.addChild(buildSpot); } // UI Elements // Gold icon and text var goldIcon = LK.getAsset('gold', { anchorX: 0.5, anchorY: 0.5 }); goldIcon.tint = 0xFFD700; goldIcon.scaleX = 0.8; goldIcon.scaleY = 0.8; LK.gui.topRight.addChild(goldIcon); goldIcon.x = -280; goldIcon.y = 50; var goldText = new Text2(gold, { size: 85, fill: 0xFFFF00 }); goldText.anchor.set(0, 0); LK.gui.topRight.addChild(goldText); goldText.x = -240; goldText.y = 20; // Lives icon and text var livesIcon = LK.getAsset('lives', { anchorX: 0.5, anchorY: 0.5 }); livesIcon.tint = 0xFF0000; livesIcon.scaleX = 0.8; livesIcon.scaleY = 0.8; LK.gui.topRight.addChild(livesIcon); livesIcon.x = -280; livesIcon.y = 130; var livesText = new Text2(lives, { size: 85, fill: 0xFF0000 }); livesText.anchor.set(0, 0); LK.gui.topRight.addChild(livesText); livesText.x = -240; livesText.y = 100; var waveText = new Text2('WAVE ' + wave, { size: 80, fill: 0xFFD700 }); waveText.anchor.set(0, 1); LK.gui.bottomLeft.addChild(waveText); waveText.x = 50; waveText.y = -50; // Add wave background for better visibility var waveBackground = LK.getAsset('woodPanel', { anchorX: 0, anchorY: 1 }); waveBackground.scaleX = 0.6; waveBackground.scaleY = 0.3; waveBackground.alpha = 0.7; waveBackground.tint = 0x8B4513; LK.gui.bottomLeft.addChild(waveBackground); waveBackground.x = 40; waveBackground.y = -40; // Move wave text to front LK.gui.bottomLeft.removeChild(waveText); LK.gui.bottomLeft.addChild(waveText); // Build menu elements (initially hidden) var buildMenuContainer = new Container(); game.addChild(buildMenuContainer); buildMenuContainer.visible = false; var drumButton = buildMenuContainer.addChild(LK.getAsset('drumTower', { anchorX: 0.5, anchorY: 0.5 })); var guitarButton = buildMenuContainer.addChild(LK.getAsset('guitarTower', { anchorX: 0.5, anchorY: 0.5 })); var violinButton = buildMenuContainer.addChild(LK.getAsset('violinTower', { anchorX: 0.5, anchorY: 0.5 })); var trumpetButton = buildMenuContainer.addChild(LK.getAsset('trumpetTower', { anchorX: 0.5, anchorY: 0.5 })); var djButton = buildMenuContainer.addChild(LK.getAsset('djTower', { anchorX: 0.5, anchorY: 0.5 })); var drumText = buildMenuContainer.addChild(new Text2('$50', { size: 45, fill: 0xFFFFFF })); drumText.anchor.set(0.5, 0); var trumpetText = buildMenuContainer.addChild(new Text2('$80', { size: 45, fill: 0xFFFFFF })); trumpetText.anchor.set(0.5, 0); var guitarText = buildMenuContainer.addChild(new Text2('$120', { size: 45, fill: 0xFFFFFF })); guitarText.anchor.set(0.5, 0); var violinText = buildMenuContainer.addChild(new Text2('$100', { size: 45, fill: 0xFFFFFF })); violinText.anchor.set(0.5, 0); var djText = buildMenuContainer.addChild(new Text2('$200', { size: 45, fill: 0xFFFFFF })); djText.anchor.set(0.5, 0); function updateUI() { goldText.setText(gold); livesText.setText(lives); waveText.setText('WAVE ' + wave); } function showBuildMenu(buildSpot) { showingBuildMenu = true; selectedBuildSpot = buildSpot; buildMenuContainer.visible = true; // Position menu near build spot buildMenuContainer.x = buildSpot.x; buildMenuContainer.y = buildSpot.y - 200; // Create circular menu layout var radius = 120; var centerX = 0; var centerY = 0; // Position buttons in a circle var angleStep = Math.PI * 2 / 5; // 5 buttons in circle drumButton.x = centerX + Math.cos(0) * radius; drumButton.y = centerY + Math.sin(0) * radius; trumpetButton.x = centerX + Math.cos(angleStep) * radius; trumpetButton.y = centerY + Math.sin(angleStep) * radius; guitarButton.x = centerX + Math.cos(angleStep * 2) * radius; guitarButton.y = centerY + Math.sin(angleStep * 2) * radius; violinButton.x = centerX + Math.cos(angleStep * 3) * radius; violinButton.y = centerY + Math.sin(angleStep * 3) * radius; djButton.x = centerX + Math.cos(angleStep * 4) * radius; djButton.y = centerY + Math.sin(angleStep * 4) * radius; // Position text closer to buttons in circle var textRadius = radius + 30; drumText.x = centerX + Math.cos(0) * textRadius; drumText.y = centerY + Math.sin(0) * textRadius; trumpetText.x = centerX + Math.cos(angleStep) * textRadius; trumpetText.y = centerY + Math.sin(angleStep) * textRadius; guitarText.x = centerX + Math.cos(angleStep * 2) * textRadius; guitarText.y = centerY + Math.sin(angleStep * 2) * textRadius; violinText.x = centerX + Math.cos(angleStep * 3) * textRadius; violinText.y = centerY + Math.sin(angleStep * 3) * textRadius; djText.x = centerX + Math.cos(angleStep * 4) * textRadius; djText.y = centerY + Math.sin(angleStep * 4) * textRadius; // Animate buttons appearing in circle tween(drumButton, { scaleX: 1.2, scaleY: 1.2 }, { duration: 200, easing: tween.easeOut }); tween(trumpetButton, { scaleX: 1.2, scaleY: 1.2 }, { duration: 200, easing: tween.easeOut }); tween(guitarButton, { scaleX: 1.2, scaleY: 1.2 }, { duration: 200, easing: tween.easeOut }); tween(violinButton, { scaleX: 1.2, scaleY: 1.2 }, { duration: 200, easing: tween.easeOut }); tween(djButton, { scaleX: 1.2, scaleY: 1.2 }, { duration: 200, easing: tween.easeOut }); } function hideBuildMenu() { showingBuildMenu = false; selectedBuildSpot = null; buildMenuContainer.visible = false; } function buildTower(towerType, cost) { console.log("buildTower called:", towerType, "cost:", cost, "gold:", gold, "selectedBuildSpot:", selectedBuildSpot); if (!selectedBuildSpot) { console.log("No build spot selected"); return; } if (gold < cost) { console.log("Not enough gold:", gold, "needed:", cost); return; } console.log("Building tower..."); // Deduct gold first gold -= cost; console.log("Gold after purchase:", gold); var tower = new Tower(towerType); tower.x = selectedBuildSpot.x; tower.y = selectedBuildSpot.y; towers.push(tower); game.addChild(tower); selectedBuildSpot.occupied = true; console.log("Tower built successfully at:", tower.x, tower.y); updateUI(); hideBuildMenu(); // Play specific sound for trumpet towers if (towerType === 'trumpet') { LK.getSound('sonido trompeta').play(); } else { LK.getSound('build').play(); } } // Button handlers with proper event handling drumButton.down = function (x, y, obj) { console.log("Drum button clicked, gold:", gold); if (gold >= 50) { buildTower('drum', 50); } else { console.log("Not enough gold for drum tower"); } }; guitarButton.down = function (x, y, obj) { console.log("Guitar button clicked, gold:", gold); if (gold >= 120) { buildTower('guitar', 120); } else { console.log("Not enough gold for guitar tower"); } }; violinButton.down = function (x, y, obj) { console.log("Violin button clicked, gold:", gold); if (gold >= 100) { buildTower('violin', 100); } else { console.log("Not enough gold for violin tower"); } }; trumpetButton.down = function (x, y, obj) { console.log("Trumpet button clicked, gold:", gold); if (gold >= 80) { buildTower('trumpet', 80); } else { console.log("Not enough gold for trumpet tower"); } }; djButton.down = function (x, y, obj) { console.log("DJ button clicked, gold:", gold); if (gold >= 200) { buildTower('dj', 200); } else { console.log("Not enough gold for DJ tower"); } }; // Game click handler to hide menu - only if not clicking on buttons or build spots game.down = function (x, y, obj) { // Don't interfere if clicking on build menu buttons if (showingBuildMenu) { // Check if clicked within circular menu area var relativeX = x - buildMenuContainer.x; var relativeY = y - buildMenuContainer.y; var distanceFromCenter = Math.sqrt(relativeX * relativeX + relativeY * relativeY); var clickedOnButton = distanceFromCenter <= 180; // Circular area radius + buffer if (!clickedOnButton) { hideBuildMenu(); } } }; function spawnEnemy() { var enemy = new Enemy(); enemy.x = pathPoints[0].x; enemy.y = pathPoints[0].y; enemy.health = 100 + (wave - 1) * 20; // Increase health each wave enemy.maxHealth = enemy.health; enemies.push(enemy); game.addChild(enemy); } function startNextWave() { if (gameState === 'playing') { // Start background music on first wave if (wave === 1) { LK.playMusic('1'); } // Show "Level X, Go!" message var levelMessage = game.addChild(new Text2('LEVEL ' + wave + ', GO!', { size: 150, fill: 0xFFD700 })); levelMessage.anchor.set(0.5, 0.5); levelMessage.x = 1024; levelMessage.y = 1366; levelMessage.alpha = 0; // Animate the message tween(levelMessage, { alpha: 1, scaleX: 1.2, scaleY: 1.2 }, { duration: 500, easing: tween.easeOut, onFinish: function onFinish() { tween(levelMessage, { alpha: 0, scaleX: 0.8, scaleY: 0.8 }, { duration: 1000, easing: tween.easeIn, onFinish: function onFinish() { levelMessage.destroy(); } }); } }); // Show wave display message after Level X, Go! LK.setTimeout(function () { var waveMessage = game.addChild(new Text2('WAVE ' + wave, { size: 120, fill: 0xFFD700 })); waveMessage.anchor.set(0.5, 0.5); waveMessage.x = 1024; waveMessage.y = 1200; waveMessage.alpha = 0; // Animate wave message tween(waveMessage, { alpha: 1, scaleX: 1.1, scaleY: 1.1 }, { duration: 600, easing: tween.easeOut, onFinish: function onFinish() { tween(waveMessage, { alpha: 0, scaleX: 0.9, scaleY: 0.9 }, { duration: 800, easing: tween.easeIn, onFinish: function onFinish() { waveMessage.destroy(); } }); } }); }, 1200); waveStarted = true; enemiesSpawned = 0; enemiesPerWave = 10 + wave * 2; // More enemies each wave } } // Hide game elements initially for (var i = 0; i < buildSpots.length; i++) { buildSpots[i].visible = false; } goal.visible = false; buildMenuContainer.visible = false; // Show main menu first gameState = 'menu'; game.update = function () { // Concert hall ambiance - create floating musical notes periodically if (LK.ticks % 180 === 0) { // Every 3 seconds createFloatingNote(); } if (gameState === 'playing') { // Show game elements when playing for (var i = 0; i < buildSpots.length; i++) { buildSpots[i].visible = true; } goal.visible = true; // Spawn enemies if (waveStarted && enemiesSpawned < enemiesPerWave) { spawnTimer++; if (spawnTimer >= 60) { // Spawn every second spawnEnemy(); enemiesSpawned++; spawnTimer = 0; } } // Check if wave is complete if (waveStarted && enemiesSpawned >= enemiesPerWave && enemies.length === 0) { wave++; waveStarted = false; gold += 100; // Bonus gold for completing wave updateUI(); // Start next wave after delay LK.setTimeout(function () { startNextWave(); }, 3000); } } // Clean up destroyed bullets for (var i = bullets.length - 1; i >= 0; i--) { if (bullets[i].destroyed) { bullets.splice(i, 1); } } // Clean up dead enemies for (var i = enemies.length - 1; i >= 0; i--) { if (enemies[i].health <= 0) { enemies[i].destroy(); enemies.splice(i, 1); } } };
===================================================================
--- original.js
+++ change.js
@@ -1410,9 +1410,9 @@
updateUI();
hideBuildMenu();
// Play specific sound for trumpet towers
if (towerType === 'trumpet') {
- LK.getSound('sonidotrompeta').play();
+ LK.getSound('sonido trompeta').play();
} else {
LK.getSound('build').play();
}
}
Bloque de piedra que ocupe todo el sprite. In-Game asset. 2d. High contrast. No shadows
El pilar de una Sala de Conciertos Viviente. In-Game asset. 2d. High contrast. No shadows
Silla de un Sala de Conciertos Viviente vista desde arriba. In-Game asset. 2d. High contrast. No shadows
Candelabro de una Sala de Conciertos Viviente. In-Game asset. 2d. High contrast. No shadows
Orquesta de una Sala de Conciertos Viviente. In-Game asset. 2d. High contrast. No shadows
escenario de una Sala de Conciertos Viviente. In-Game asset. 2d. High contrast. No shadows
Cortina de una Sala de Conciertos Viviente. In-Game asset. 2d. High contrast. No shadows
Vip box de una Sala de Conciertos Viviente. In-Game asset. 2d. High contrast. No shadows
RoyalCrest de una Sala de Conciertos Viviente. In-Game asset. 2d. High contrast. No shadows
Nota musical de una Sala de Conciertos Viviente. In-Game asset. 2d. High contrast. No shadows
Una nota negrita endiablada. In-Game asset. 2d. High contrast. No shadows
WoodPanel en una sala de conciertos viviente. In-Game asset. 2d. High contrast. No shadows
Tarimas con cuerdas tensadas flotando debajo.. In-Game asset. 2d. High contrast. No shadows
tambor basico. In-Game asset. 2d. High contrast. No shadows
Trompeta de choque. In-Game asset. 2d. High contrast. No shadows
Un bailarin del caos. In-Game asset. 2d. High contrast. No shadows
Guitarra electrica. In-Game asset. 2d. High contrast. No shadows
Violin congelante. In-Game asset. 2d. High contrast. No shadows
DJ ritmico. In-Game asset. 2d. High contrast. No shadows
Oro. In-Game asset. 2d. High contrast. No shadows
Nota musical semifusa. In-Game asset. 2d. High contrast. No shadows
Clave de sol. In-Game asset. 2d. High contrast. No shadows
Portal siniestro. In-Game asset. 2d. High contrast. No shadows
Clave de fa. In-Game asset. 2d. High contrast. No shadows
nota musical. In-Game asset. 2d. High contrast. No shadows
Upgrade. In-Game asset. 2d. High contrast. No shadows
Remove. In-Game asset. 2d. High contrast. No shadows
Ruido blanco personificado como un enemigo. In-Game asset. 2d. High contrast. No shadows
Una nota desafinada personificada como enemigo. In-Game asset. 2d. High contrast. No shadows
Autotune malicioso personificado como enemigo. In-Game asset. 2d. High contrast. No shadows
Glitch audio personificado como un enemigo. In-Game asset. 2d. High contrast. No shadows
Eco oscuro personificado como un enemigo. In-Game asset. 2d. High contrast. No shadows
Un enemigo del infierno de elite, tiene armas y tambien armadura. In-Game asset. 2d. High contrast. No shadows
Crea un botón visual para la pantalla de inicio de un videojuego llamado Symphony Siege. El botón debe decir "Start" y estar inspirado en una sala de conciertos clásica y elementos musicales. El diseño debe tener un estilo elegante, ligeramente barroco o sinfónico, con detalles dorados y formas suaves. El texto "Start" debe estar centrado y ser legible, con una tipografía estilizada tipo partitura o manuscrito musical. El fondo del botón debe parecer una tecla de piano brillante o una placa de madera de violín. El contorno puede tener detalles dorados o bronces ornamentales. El botón debe emitir una sensación de majestuosidad y armonía, no modernidad ni minimalismo. In-Game asset. 2d. High contrast. No shadows
Diseña un botón visual para un videojuego llamado Symphony Siege, destinado a la opción "Tutorial". El estilo debe ser coherente con una interfaz inspirada en una sala de conciertos clásica: elegante, musical y refinada. El botón debe incluir la palabra "Tutorial" centrada, usando una tipografía manuscrita o de partitura antigua, legible y estilizada. El fondo puede simular una partitura enrollada, una tablilla de madera pulida o una tecla de piano estirada horizontalmente. El contorno del botón debe tener detalles ornamentales dorados o cobrizos, evocando la estética barroca o sinfónica. El tono general debe ser acogedor y educativo, sin perder la elegancia musical. In-Game asset. 2d. High contrast. No shadows
Fondo azul con un marco de hierro. In-Game asset. 2d. High contrast. No shadows
Tambor evolucionado. In-Game asset. 2d. High contrast. No shadows
guitarra evolucionada. In-Game asset. 2d. High contrast. No shadows
Trompeta evolucionada. In-Game asset. 2d. High contrast. No shadows
Violin de hielo futurista evolucionado. In-Game asset. 2d. High contrast. No shadows
DJ evolucionado. In-Game asset. 2d. High contrast. No shadows
estrellitas luminosas. In-Game asset. 2d. High contrast. No shadows
Piano enorme. In-Game asset. 2d. High contrast. No shadows
piano de cola cayendo. In-Game asset. 2d. High contrast. No shadows
musicChest. In-Game asset. 2d. High contrast. No shadows
Design a stylish "Restart" button for a fantasy-themed tower defense game called Symphony Siege. The button should look like a polished UI element with a musical theme, fitting the visual style of a haunted concert hall. Shape: rounded rectangle or ornate frame, with golden or bronze edges and a subtle wood or velvet texture background. Icon: a circular restart arrow symbol (⟳ or similar), stylized like a treble clef or musical motif, glowing softly in white, gold, or blue. Optional details: faint floating music notes, light reflections, or sparkles around the icon to suggest magical energy. Text (optional): include the word "Restart" in elegant serif font, or leave it icon-only. Make sure the design is readable at small sizes and fits with the existing UI style (clean, magical, classical). No clutter, no background image — just the button asset.. In-Game asset. 2d. High contrast. No shadows
Design an icon for a button labeled "Towers" in a fantasy tower defense game set in a haunted concert hall. The icon should clearly represent access to a selection of instrument-based defense towers. Use a stylized rack or display of musical instruments arranged like tower miniatures: a drum, violin, trumpet, electric guitar, and DJ deck. They should look magical and glowing slightly, as if floating or placed on a scroll or magical stand. The icon should be square (256×256 px), clean and readable at small sizes. Background should be subtle—wood, velvet, or magical mist—but not distracting. The icon must not include text, only imagery. Style: digital painted or semi-flat fantasy UI, fitting with a classical, magical orchestral theme.. In-Game asset. 2d. High contrast. No shadows
Design an icon for a button labeled "Enemies" in a fantasy tower defense game set in a haunted concert hall. The icon should represent the chaotic and musical nature of the enemies. Show a cluster of stylized enemy silhouettes made of shadow, glitchy waveforms, or cracked musical notes. They should look menacing but stylized, like abstract creatures of sound and dissonance. Use a dark, slightly glowing background (deep purple, blue, or smoky black) with subtle magical accents—floating broken clefs, static, or distortion. Icon must be square (256×256 px), clean, and readable at small sizes. Avoid text—use only imagery. Style: semi-flat or digitally painted fantasy UI, consistent with an elegant but eerie orchestral theme.. In-Game asset. 2d. High contrast. No shadows
Design a button icon for "Back to Menu" in a fantasy tower defense game set in a haunted, musical concert hall. The button should feature a stylized arrow pointing left, wrapped in or formed by musical elements such as a ribbon of notes, a bass clef, or a scroll with a staff line. The background should be elegant and soft: deep velvet red or dark wood with subtle glow. Optional: add a small menu symbol (like sliders or a parchment icon) subtly integrated behind or beneath the arrow. Keep the icon square (256×256 px), readable at small sizes, and without text. Style should match the UI of the game—refined, fantasy-themed, and orchestral in tone.. In-Game asset. 2d. High contrast. No shadows
Design an icon for the Settings menu in a fantasy tower defense game set in a haunted concert hall. The icon should be a stylized gear or cogwheel, but with a musical twist: integrate treble clefs, tuning pegs, or parts of old instruments (like violin scrolls or piano strings) into the gear design. Use metallic textures (bronze, dark gold, or polished silver), with soft magical glow or engraved music notes along the edges. Background should be subtle—deep velvet or dark wood, with ambient lighting to highlight the gear. Icon must be square (256×256 px), readable at small sizes, and include no text. Style: elegant, orchestral fantasy UI—matching the tone of a classical concert hall with magical elements.. In-Game asset. 2d. High contrast. No shadows
Simbolo de mas de color verde. In-Game asset. 2d. High contrast. No shadows
Simbolo de menos de color rojo. In-Game asset. 2d. High contrast. No shadows
Design an icon for an Auto Start Wave toggle in a fantasy tower defense game set in a haunted concert hall. The icon should represent automatic wave progression using a musical or magical theme. Main element: a stylized fast-forward symbol (⏩) or two angled arrows, designed from musical elements like overlapping notes, metronome arms, or flowing sheet music. Optional overlay: a glowing circle, enchanted loop, or small play symbol to suggest automation. Use glowing magical accents (blue, gold, or purple) and keep the shape elegant, readable, and consistent with the orchestral UI. Icon must be square (256×256 px), readable at small sizes, and include no text. Provide two visual states: Enabled: glowing softly with animated sparkles or highlights. Disabled: desaturated or dimmed, with no glow. Style: clean fantasy UI, matching a mystical and musical battlefield interface.. In-Game asset. 2d. High contrast. No shadows
Design an icon for a toggle button labeled "Show Damage Numbers" in a fantasy tower defense game set in a magical concert hall. The icon should represent visible damage output using a musical and magical theme. Main elements: show floating numbers (like “+35”, “-120”) rising or popping out from stylized musical symbols—such as a treble clef or burst of notes. Optionally, display a glowing impact spark or small explosion with numbers around it to represent hit feedback. Use gold, red, or white tones for the numbers and magical trails for emphasis. Background should be neutral or dark, subtly textured (like velvet or wood), to enhance readability. The icon must be square (256×256 px), readable at small sizes, and include no text. Provide two visual states: Enabled: numbers glowing, slightly animated or rising. Disabled: numbers greyed out or crossed subtly with a muted tone. Style: fantasy UI, clean and elegant, consistent with the musical combat theme of the game.. In-Game asset. 2d. High contrast. No shadows
Design an icon for a Language selection button in a fantasy tower defense game set in a magical concert hall. The icon should combine a classic globe symbol with musical or magical elements to reflect the game's unique theme. Main symbol: a stylized globe with subtle music note engravings on the surface or longitude/latitude lines formed from staff lines (like a musical sheet). Optional elements: a floating treble clef, sparkles, or an open scroll representing language or translation. Use elegant gold, bronze, or blue tones, with a soft magical glow. The background should be subtle—velvet, dark wood, or parchment-like texture. Icon must be square (256×256 px), readable at small sizes, and must not include text. Optional: provide a state where a small flag symbol or dropdown arrow appears to suggest language selection. Style: refined, orchestral fantasy UI—fitting the atmosphere of a haunted concert hall with magical elegance.. In-Game asset. 2d. High contrast. No shadows
destello. In-Game asset. 2d. High contrast. No shadows
Create a detailed fantasy icon of a War Horn designed for a musical-themed tower defense game set in a haunted concert hall. The horn should be ornate and elegant, resembling a mix between a classical brass instrument (like a French horn or trumpet) and a battle horn. Crafted from polished brass or gold, with engraved musical symbols (clefs, notes, or swirling staff lines) along its surface. The mouthpiece and flared bell should look slightly exaggerated, magical, or ceremonial. Add glowing accents (blue, violet, or gold) or floating music notes around it to suggest it's enchanted. The horn may rest on a pedestal, float slightly, or face outward ready to be sounded. Background should be minimal or transparent. Icon must be square (256×256 or 512×512), clean and readable at small sizes. Style: elegant fantasy UI, semi-realistic digital painting, matching the orchestral theme of the game.. In-Game asset. 2d. High contrast. No shadows
Torre de guitarra moderna, futurista con amplificacion.. In-Game asset. 2d. High contrast. No shadows
Una estructura imponente, como una batería gigante, con tambores hechos de cristales vibrantes o rocas volcánicas incandescentes. Podría tener vetas de energía luminosa (magma, hielo o electricidad) recorriendo su superficie, y un aura de pulsaciones rítmicas visibles. La base podría estar agrietada por la energía que emana.. In-Game asset. 2d. High contrast. No shadows
Una trompeta de proporciones colosales, con una campana que se abre como un altavoz parabólico gigante. Su superficie podría ser de un metal brillante y pulido, con intrincados grabados o incrustaciones de cristales resonantes que brillan intensamente. Podría tener un sistema de lentes o emisores de energía en su boca.. In-Game asset. 2d. High contrast. No shadows
Un violín que parece estar esculpido en nubes etéreas o cristal de éter, con un brillo suave. El arco es un haz de luz pura que deja un rastro luminoso al moverse. Las cuerdas son finos hilos de energía que brillan con diferentes colores, y el cuerpo del violín podría tener constelaciones o nebulosas incrustadas.. In-Game asset. 2d. High contrast. No shadows
Una torre que es una mesa de DJ futurista y auto-programable, flotando sobre el suelo. Tendría múltiples pantallas holográficas que muestran complejos patrones de ondas sonoras y datos. Los platos serían discos de energía giratorios que emiten luz y chispas, y la torre en sí podría estar rodeada por un campo de fuerza o una rejilla de luz.. In-Game asset. 2d. High contrast. No shadows
Aura de luz. In-Game asset. 2d. High contrast. No shadows
enemyDeath
Sound effect
hit
Sound effect
build
Sound effect
sonidotrompeta
Sound effect
proyectilT
Sound effect
ProyectilTA
Sound effect
SonidoGuitarra
Sound effect
ProyectilG
Sound effect
portal
Sound effect
titleSound
Sound effect
SonidoViolin
Sound effect
ProyectilV
Sound effect
SonidoV
Sound effect
Cuerno
Sound effect
SonidoDJ
Sound effect
ProyectilDJ
Sound effect
MusicaInicio
Music
Risa
Sound effect
Voz
Sound effect
Melodia
Music
Destruir
Sound effect
eror
Sound effect
grandPianoChord
Sound effect
grandPianoImpact
Sound effect
chestOpen
Sound effect
powerUnlock
Sound effect
fanfare
Music
orito
Sound effect