User prompt
Pon el apartado skins al lado del apartado shop de forma simétrica
User prompt
Mueve en apartado de skins para que no se fusione con otros apartados
User prompt
Haz un apartado llamado skins en el menú principal donde salgan las skins compradas y que esas skins cuando las compres en la shop se quiten de ella ↪💡 Consider importing and using the following plugins: @upit/storage.v1
User prompt
Elimina la skin naranja de la tienda
User prompt
Please fix the bug: 'Script error.' in or related to this line: 'shopContainer.addChild(aircraftTitleText);' Line Number: 2374
User prompt
Elimina la skin naranja de la tienda
User prompt
Cambia el nombre shop por skins
User prompt
Haz que la skin naranja solo se pueda conseguir con el código, y una vez ya introducido el código aparezca en la tienda ↪💡 Consider importing and using the following plugins: @upit/storage.v1
User prompt
Cambia el código orangefrreskin por orangefreeskin
User prompt
Haz que la línea de meta aparezca en el punto donde el progreso termina
User prompt
Haz que la línea de meta aparezca justo cuando el progreso termina
User prompt
En la tienda, baja el botón de atras
User prompt
En el menú principal, donde pone BETA, cámbialo por 0.00.02
User prompt
Pon una separación un poco mayor entre torres
User prompt
Pero haz que el hueco entre torres conecte con las siguientes torres para que no sea imposible pasarse el nivel
User prompt
Haz una dos líneas imaginarias en el centro del mapa, delimitando la zona en la que las torres se puedan generar, para que no sea imposible
User prompt
Vuelve a mejorar la generación de las torres, en algunos niveles es imposible pasarlas
User prompt
Haz que en la generación de las torres, no sea imposible de pasarlas, ya que algunos niveles no se pueden superar
User prompt
Aumenta la velocidad del avión, de forma en la que por cada nivel que pase, la velocidad sea mayor, pero que deje de aumentar en un nivel determinado para que no sea incontrolable
User prompt
Crea un código llamado ORANGEFRRESKIN que al reclamarlo te de un color de avión naranja y se te añada gratis a la tienda ↪💡 Consider importing and using the following plugins: @upit/storage.v1
User prompt
En el menú principal, en la parte de abajo, pon versión: (la versión que es, en este caso la BETA)
User prompt
Haz un apartado en el menu principal que ponga el score total que has conseguido ↪💡 Consider importing and using the following plugins: @upit/storage.v1
User prompt
Soluciona el bug del progreso y la linea de meta, la linea de meta debe estar justo en los numeros propuestos del progreso
User prompt
Mejora la skin del avion
User prompt
Mejora todo lo que puedas el juego ↪💡 Consider importing and using the following plugins: @upit/tween.v1, @upit/storage.v1
/**** * Plugins ****/ var storage = LK.import("@upit/storage.v1"); var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ var Aircraft = Container.expand(function () { var self = Container.call(this); // Main aircraft fuselage (body) - enhanced proportions var aircraftGraphics = self.attachAsset('aircraft', { anchorX: 0.5, anchorY: 0.5 }); // Enhanced main wings with better positioning and scale var mainWing = self.attachAsset('aircraftWing', { anchorX: 0.5, anchorY: 0.5 }); mainWing.x = -5; // Move forward for better balance mainWing.y = 5; // Slightly lower on fuselage mainWing.scaleX = 1.3; // Make wings larger mainWing.scaleY = 1.5; // Wing struts for realism var leftWingStrut = self.attachAsset('aircraftEngine', { anchorX: 0.5, anchorY: 0.5 }); leftWingStrut.x = -10; leftWingStrut.y = 18; leftWingStrut.scaleX = 0.3; leftWingStrut.scaleY = 2; leftWingStrut.rotation = Math.PI / 4; var rightWingStrut = self.attachAsset('aircraftEngine', { anchorX: 0.5, anchorY: 0.5 }); rightWingStrut.x = -10; rightWingStrut.y = -8; rightWingStrut.scaleX = 0.3; rightWingStrut.scaleY = 2; rightWingStrut.rotation = -Math.PI / 4; // Enhanced aircraft tail with better proportions var tail = self.attachAsset('aircraftTail', { anchorX: 0.5, anchorY: 0.5 }); tail.x = -65; tail.y = 0; tail.rotation = Math.PI / 2; tail.scaleX = 1.2; // Make tail more prominent tail.scaleY = 0.8; // Horizontal stabilizer with improved positioning var horizontalStab = self.attachAsset('aircraftWing', { anchorX: 0.5, anchorY: 0.5 }); horizontalStab.x = -58; horizontalStab.y = 0; horizontalStab.scaleX = 0.5; horizontalStab.scaleY = 0.7; // Enhanced cockpit with better visibility var cockpit = self.attachAsset('aircraftCockpit', { anchorX: 0.5, anchorY: 0.5 }); cockpit.x = 40; cockpit.y = -3; cockpit.scaleX = 1.4; // Larger, more visible cockpit cockpit.scaleY = 1.2; // Wing tip fuel tanks for modern look var leftWingTip = self.attachAsset('aircraftEngine', { anchorX: 0.5, anchorY: 0.5 }); leftWingTip.x = -5; leftWingTip.y = 25; leftWingTip.scaleX = 0.6; leftWingTip.scaleY = 0.8; var rightWingTip = self.attachAsset('aircraftEngine', { anchorX: 0.5, anchorY: 0.5 }); rightWingTip.x = -5; rightWingTip.y = -15; rightWingTip.scaleX = 0.6; rightWingTip.scaleY = 0.8; // Enhanced engine nacelles with better positioning var leftEngine = self.attachAsset('aircraftEngine', { anchorX: 0.5, anchorY: 0.5 }); leftEngine.x = -15; leftEngine.y = 15; leftEngine.scaleX = 1.2; leftEngine.scaleY = 1.3; var rightEngine = self.attachAsset('aircraftEngine', { anchorX: 0.5, anchorY: 0.5 }); rightEngine.x = -15; rightEngine.y = -5; rightEngine.scaleX = 1.2; rightEngine.scaleY = 1.3; // Landing gear indicators (small details) var leftGear = self.attachAsset('aircraftEngine', { anchorX: 0.5, anchorY: 0.5 }); leftGear.x = 15; leftGear.y = 8; leftGear.scaleX = 0.4; leftGear.scaleY = 0.3; var rightGear = self.attachAsset('aircraftEngine', { anchorX: 0.5, anchorY: 0.5 }); rightGear.x = 15; rightGear.y = -8; rightGear.scaleX = 0.4; rightGear.scaleY = 0.3; // Enhanced propeller with better positioning var propeller = self.attachAsset('aircraftPropeller', { anchorX: 0.5, anchorY: 0.5 }); propeller.x = 75; propeller.y = 0; propeller.scaleX = 1.2; // Larger propeller propeller.scaleY = 1.4; // Secondary propeller blade for depth var propellerBlade2 = self.attachAsset('aircraftPropeller', { anchorX: 0.5, anchorY: 0.5 }); propellerBlade2.x = 75; propellerBlade2.y = 0; propellerBlade2.scaleX = 1.2; propellerBlade2.scaleY = 1.4; propellerBlade2.rotation = Math.PI / 2; // 90 degrees offset // Navigation lights var leftNavLight = self.attachAsset('aircraftCockpit', { anchorX: 0.5, anchorY: 0.5 }); leftNavLight.x = -5; leftNavLight.y = 30; leftNavLight.scaleX = 0.3; leftNavLight.scaleY = 0.3; leftNavLight.tint = 0xFF0000; // Red navigation light var rightNavLight = self.attachAsset('aircraftCockpit', { anchorX: 0.5, anchorY: 0.5 }); rightNavLight.x = -5; rightNavLight.y = -20; rightNavLight.scaleX = 0.3; rightNavLight.scaleY = 0.3; rightNavLight.tint = 0x00FF00; // Green navigation light // Animate propeller rotation with both blades propeller.rotationSpeed = 0.3; propellerBlade2.rotationSpeed = 0.3; // Progressive aircraft speed: starts at 3, increases by 0.1 per level, caps at level 20 (speed 5) self.speed = Math.min(5, 3 + (currentLevel - 1) * 0.1); self.lastY = 0; self.update = function () { // Update last position for collision detection self.lastY = self.y; // Animate both propeller blades spinning with variable speed var propellerSpeed = propeller.rotationSpeed * (1 + self.speed * 0.1); propeller.rotation += propellerSpeed; propellerBlade2.rotation += propellerSpeed; // Animate navigation lights blinking if (LK.ticks % 120 < 60) { // Blink every 2 seconds leftNavLight.alpha = 1; rightNavLight.alpha = 1; } else { leftNavLight.alpha = 0.3; rightNavLight.alpha = 0.3; } // Create enhanced engine trail particles if (LK.ticks % 3 === 0 && gameStarted) { createEngineParticle(self.x - 50, self.y + 10); // Left engine trail createEngineParticle(self.x - 50, self.y - 5); // Right engine trail // Add occasional spark effects from both engines if (Math.random() < 0.3) { createSparkParticle(self.x - 40, self.y + (Math.random() - 0.5) * 20); } } // Add subtle banking animation during movement var bankingAngle = Math.sin(LK.ticks * 0.05) * 0.1; self.rotation = bankingAngle; // Add subtle floating animation for more dynamic feel if (!self.floatingTween) { self.floatingTween = true; var originalY = self.y; tween(self, { y: originalY + 8 }, { duration: 2000, easing: tween.easeInOut, onFinish: function onFinish() { tween(self, { y: originalY - 8 }, { duration: 2000, easing: tween.easeInOut, onFinish: function onFinish() { self.floatingTween = false; } }); } }); } }; return self; }); var Cloud = Container.expand(function () { var self = Container.call(this); // Choose random cloud type var cloudTypes = ['cloud1', 'cloud2', 'cloud3']; var cloudType = cloudTypes[Math.floor(Math.random() * cloudTypes.length)]; // Main cloud body var mainCloud = self.attachAsset(cloudType, { anchorX: 0.5, anchorY: 0.5 }); // Add smaller cloud parts for more realistic shape var cloud2 = self.attachAsset(cloudType, { anchorX: 0.5, anchorY: 0.5 }); cloud2.x = -30 + Math.random() * 60; cloud2.y = -15 + Math.random() * 30; cloud2.scaleX = 0.6 + Math.random() * 0.4; cloud2.scaleY = 0.6 + Math.random() * 0.4; cloud2.alpha = 0.8; var cloud3 = self.attachAsset(cloudType, { anchorX: 0.5, anchorY: 0.5 }); cloud3.x = -20 + Math.random() * 40; cloud3.y = -10 + Math.random() * 20; cloud3.scaleX = 0.4 + Math.random() * 0.3; cloud3.scaleY = 0.4 + Math.random() * 0.3; cloud3.alpha = 0.6; // Set random speed and scale self.speed = 0.5 + Math.random() * 1.5; self.scaleX = 0.8 + Math.random() * 0.6; self.scaleY = 0.8 + Math.random() * 0.6; self.alpha = 0.7 + Math.random() * 0.3; self.update = function () { // Move cloud from right to left self.x -= self.speed; }; return self; }); var Coin = Container.expand(function () { var self = Container.call(this); // Coin visual var coinGraphics = self.attachAsset('coin', { anchorX: 0.5, anchorY: 0.5, scaleX: 1.2, scaleY: 1.2 }); // Floating and spinning animation self.floatOffset = Math.random() * Math.PI * 2; self.collected = false; self.update = function () { // Floating animation self.y += Math.sin(LK.ticks * 0.15 + self.floatOffset) * 0.8; // Spinning animation coinGraphics.rotation += 0.1; // Pulsing scale effect var scale = 1.2 + Math.sin(LK.ticks * 0.08) * 0.2; coinGraphics.scaleX = scale; coinGraphics.scaleY = scale; // Move from right to left var speed = Math.max(1.5, Math.min(6, 1.5 + currentLevel * 0.05)); self.x -= speed; }; return self; }); var FinishLine = Container.expand(function () { var self = Container.call(this); // Main finish line var lineGraphics = self.attachAsset('finishLine', { anchorX: 0.5, anchorY: 0.5 }); // Add flags at top and bottom for visibility var topFlag = self.attachAsset('finishFlag', { anchorX: 0.5, anchorY: 0.5 }); topFlag.y = -1300; var bottomFlag = self.attachAsset('finishFlag', { anchorX: 0.5, anchorY: 0.5 }); bottomFlag.y = 1300; self.lastX = 0; self.crossed = false; self.update = function () { // Update last position before moving self.lastX = self.x; // Move finish line from right to left (match tower speed for levels 1-100) var speed = Math.max(1.5, Math.min(6, 1.5 + currentLevel * 0.05)); // Match tower speed progression self.x -= speed; }; return self; }); var Particle = Container.expand(function () { var self = Container.call(this); // Small particle visual var particleGraphics = self.attachAsset('cloud1', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.1, scaleY: 0.1 }); particleGraphics.alpha = 0.7; particleGraphics.tint = 0xFF6600; // Orange-ish color self.velocityX = -2 - Math.random() * 3; self.velocityY = (Math.random() - 0.5) * 2; self.life = 60; // 1 second at 60fps self.update = function () { self.x += self.velocityX; self.y += self.velocityY; self.life--; particleGraphics.alpha *= 0.98; // Fade out particleGraphics.scaleX *= 0.99; // Shrink particleGraphics.scaleY *= 0.99; if (self.life <= 0) { self.destroy(); var index = particles.indexOf(self); if (index > -1) particles.splice(index, 1); } }; return self; }); var PowerUp = Container.expand(function () { var self = Container.call(this); // Power-up visual var powerUpGraphics = self.attachAsset('finishFlag', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.8, scaleY: 0.8 }); powerUpGraphics.tint = 0x00FFFF; // Cyan color for power-ups // Floating animation self.floatOffset = Math.random() * Math.PI * 2; self.collected = false; self.update = function () { // Floating animation self.y += Math.sin(LK.ticks * 0.1 + self.floatOffset) * 0.5; // Rotation animation powerUpGraphics.rotation += 0.05; // Move from right to left var speed = Math.max(1.5, Math.min(6, 1.5 + currentLevel * 0.05)); self.x -= speed; }; return self; }); var SparkParticle = Container.expand(function () { var self = Container.call(this); // Small spark visual var sparkGraphics = self.attachAsset('coin', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.05, scaleY: 0.05 }); sparkGraphics.alpha = 1; sparkGraphics.tint = 0xFFAA00; // Orange spark color self.velocityX = -1 - Math.random() * 2; self.velocityY = (Math.random() - 0.5) * 3; self.life = 30; // Half second at 60fps self.update = function () { self.x += self.velocityX; self.y += self.velocityY; self.velocityY += 0.1; // Gravity effect self.life--; sparkGraphics.alpha *= 0.95; // Faster fade than regular particles sparkGraphics.scaleX *= 0.98; sparkGraphics.scaleY *= 0.98; sparkGraphics.rotation += 0.2; // Spinning effect if (self.life <= 0) { self.destroy(); var index = sparkParticles.indexOf(self); if (index > -1) sparkParticles.splice(index, 1); } }; return self; }); var Tower = Container.expand(function () { var self = Container.call(this); // Tower base var towerBase = self.attachAsset('towerBase', { anchorX: 0.5, anchorY: 0.5 }); // Tower top var towerTop = self.attachAsset('towerTop', { anchorX: 0.5, anchorY: 0.5 }); towerTop.y = -420; // Position at top of tower // Add windows to make it look more realistic for (var w = 0; w < 3; w++) { var window1 = self.attachAsset('towerWindow', { anchorX: 0.5, anchorY: 0.5 }); window1.x = -30; window1.y = -300 + w * 150; var window2 = self.attachAsset('towerWindow', { anchorX: 0.5, anchorY: 0.5 }); window2.x = 30; window2.y = -300 + w * 150; } self.lastX = 0; self.passed = false; self.update = function () { // Update last position before moving self.lastX = self.x; // Move tower from right to left (progressive speed increase for levels 1-100) var speed = Math.max(1.5, Math.min(6, 1.5 + currentLevel * 0.05)); // Gradual speed increase, capped at 6 self.x -= speed; }; return self; }); /**** * Initialize Game ****/ // Game variables var game = new LK.Game({ backgroundColor: 0x87CEFA // More realistic sky blue background }); /**** * Game Code ****/ //Storage plugin for persistent game data // Game variables // Initialize assets for the tower dodge flight game var aircraft; var towers = []; var clouds = []; var finishLine = null; var showingMenu = false; var currentLevel = storage.currentLevel || 1; var levelScore = 0; var towersToComplete = 5 * currentLevel; // Level 1: 5, Level 2: 10, Level 3: 15, etc. var towerSpawnTimer = 0; var gameStarted = false; var menuContainer = null; var mainMenuContainer = null; var showingMainMenu = true; var showingCodesMenu = false; var codesMenuContainer = null; var adminMode = false; var adminModeEndTime = 0; // Enhanced settings storage var gameSettings = storage.gameSettings || { soundEnabled: true, musicEnabled: true, difficulty: 'normal', highestLevelReached: 1, particlesEnabled: true, screenshakeEnabled: true }; // Additional game variables var powerUps = []; var particles = []; var sparkParticles = []; var powerUpSpawnTimer = 0; var invulnerabilityTime = 0; var comboMultiplier = 1; var lastPowerUpTime = 0; var musicPlaying = false; var coins = []; var coinSpawnTimer = 0; var showingSkins = false; var skinsContainer = null; // Initialize player coins and shop items var playerCoins = storage.playerCoins || 0; var totalScore = storage.totalScore || 0; var ownedAircraftStyles = storage.ownedAircraftStyles || ['default']; var ownedTowerStyles = storage.ownedTowerStyles || ['default']; var currentAircraftStyle = storage.currentAircraftStyle || 'default'; var currentTowerStyle = storage.currentTowerStyle || 'default'; // Shop items with prices var aircraftStyles = [{ id: 'default', name: 'Classic', price: 0, color: 0xf0f0f0 }, { id: 'red', name: 'Fire Bird', price: 100, color: 0xff4444 }, { id: 'blue', name: 'Sky Runner', price: 150, color: 0x4444ff }, { id: 'green', name: 'Forest Wing', price: 200, color: 0x44ff44 }, { id: 'purple', name: 'Royal Jet', price: 300, color: 0x8844ff }, { id: 'gold', name: 'Golden Eagle', price: 500, color: 0xffd700 }]; // Orange aircraft style - only available through code var orangeAircraftStyle = { id: 'orange', name: 'Orange Flyer', price: 0, color: 0xff8000 }; var towerStyles = [{ id: 'default', name: 'Stone Tower', price: 0, color: 0x8b4513 }, { id: 'metal', name: 'Metal Tower', price: 120, color: 0x778899 }, { id: 'crystal', name: 'Crystal Tower', price: 180, color: 0x99ddff }, { id: 'dark', name: 'Dark Tower', price: 250, color: 0x444444 }, { id: 'rainbow', name: 'Rainbow Tower', price: 400, color: 0xff6699 }]; // Update settings when needed if (currentLevel > gameSettings.highestLevelReached) { gameSettings.highestLevelReached = currentLevel; storage.gameSettings = gameSettings; } // Check if admin mode is still active from previous session var storedAdminEndTime = storage.adminModeEndTime || 0; if (storedAdminEndTime > Date.now()) { adminMode = true; adminModeEndTime = storedAdminEndTime; } // UI Elements var levelText = new Text2('Level: 1', { size: 60, fill: 0xFFFFFF }); levelText.anchor.set(0, 0); LK.gui.topLeft.addChild(levelText); levelText.x = 120; // Avoid top-left menu area levelText.y = 20; var scoreText = new Text2('Score: 0', { size: 60, fill: 0xFFFFFF }); scoreText.anchor.set(1, 0); LK.gui.topRight.addChild(scoreText); var progressText = new Text2('Progress: 0/10', { size: 50, fill: 0xFFFFFF }); progressText.anchor.set(0.5, 0); LK.gui.top.addChild(progressText); progressText.y = 100; var coinsText = new Text2('Coins: ' + playerCoins, { size: 50, fill: 0xFFD700 }); coinsText.anchor.set(0, 0); LK.gui.topLeft.addChild(coinsText); coinsText.x = 120; coinsText.y = 80; // Initialize aircraft aircraft = game.addChild(new Aircraft()); aircraft.x = 300; aircraft.y = 1366; // Center vertically aircraft.lastIntersecting = false; // Show main menu at start createMainMenu(); // Touch controls for aircraft movement var dragActive = false; game.down = function (x, y, obj) { if (showingMainMenu || showingMenu) return; dragActive = true; }; game.up = function (x, y, obj) { if (showingMainMenu || showingMenu) return; dragActive = false; }; game.move = function (x, y, obj) { if (showingMainMenu || showingMenu) return; var targetY = y; if (dragActive) { targetY = y; } // Keep aircraft within screen bounds if (targetY < 50) targetY = 50; if (targetY > 2680) targetY = 2680; // Smooth tween animation for aircraft movement tween.stop(aircraft, { y: true }); tween(aircraft, { y: targetY }, { duration: 200, easing: tween.easeOut }); }; // Function to spawn tower function spawnTower() { // Define imaginary boundary lines to delimit tower generation zone var screenTop = 0; var screenBottom = 2732; var centerY = 1366; // Center of the screen var safeZoneHeight = 1800; // Height of the safe generation zone (smaller than full screen) var upperBoundary = centerY - safeZoneHeight / 2; // Top imaginary line var lowerBoundary = centerY + safeZoneHeight / 2; // Bottom imaginary line // Ensure boundaries are within screen limits with additional margin upperBoundary = Math.max(200, upperBoundary); // Minimum 200px from top lowerBoundary = Math.min(2532, lowerBoundary); // Maximum 200px from bottom // Enhanced gap sizing with more generous minimum and smoother progression var baseGapSize = 450; // Increased base gap size for better playability var levelReduction = Math.min(currentLevel - 1, 30) * 8; // Slower reduction, cap at level 30 var gapSize = Math.max(380, baseGapSize - levelReduction); // Higher minimum gap (380px vs 350px) // Aircraft dimensions for precise gap calculation var aircraftHeight = 140; // Based on aircraft asset height var safetyMargin = 50; // Extra margin for comfortable passage var minRequiredGap = aircraftHeight + safetyMargin * 2; // Minimum theoretical gap needed gapSize = Math.max(gapSize, minRequiredGap); // Ensure gap is never smaller than aircraft needs // Tower generation zone constraints using imaginary boundary lines var towerHeight = 800; // Tower base height from asset var zoneMargin = 100; // Additional margin within the safe zone var minGapCenter = upperBoundary + zoneMargin + gapSize / 2; // Use upper boundary line var maxGapCenter = lowerBoundary - zoneMargin - gapSize / 2; // Use lower boundary line // Ensure we have enough space for gap generation if (maxGapCenter <= minGapCenter) { // Fallback to center area if boundaries are too restrictive minGapCenter = centerY - gapSize / 2; maxGapCenter = centerY + gapSize / 2; } // Enhanced gap connection system to ensure continuity between tower pairs var gapCenter; if (towers.length === 0) { // First tower pair - start in center area for safety gapCenter = centerY; } else { // Find the most recent tower pair to connect with var lastTopTower = null; var lastBottomTower = null; var lastGapCenter = centerY; // Find the last tower pair by looking for the rightmost towers for (var t = towers.length - 1; t >= 0; t--) { var tower = towers[t]; if (!lastTopTower && tower.y < centerY) { lastTopTower = tower; } else if (!lastBottomTower && tower.y > centerY) { lastBottomTower = tower; } if (lastTopTower && lastBottomTower) break; } // Calculate last gap center if we found both towers if (lastTopTower && lastBottomTower) { var lastGapTop = lastTopTower.y + towerHeight / 2; var lastGapBottom = lastBottomTower.y - towerHeight / 2; lastGapCenter = (lastGapTop + lastGapBottom) / 2; } // Create connecting gap within reasonable range of last gap var connectionRange = gapSize * 0.8; // Allow gap to move within 80% of gap size var minConnectionCenter = Math.max(minGapCenter, lastGapCenter - connectionRange); var maxConnectionCenter = Math.min(maxGapCenter, lastGapCenter + connectionRange); // Ensure we still have valid range if (minConnectionCenter > maxConnectionCenter) { minConnectionCenter = minGapCenter; maxConnectionCenter = maxGapCenter; } gapCenter = minConnectionCenter + Math.random() * (maxConnectionCenter - minConnectionCenter); } var gapTop = gapCenter - gapSize / 2; var gapBottom = gapCenter + gapSize / 2; // Final boundary checks to ensure towers stay within imaginary lines gapTop = Math.max(upperBoundary + zoneMargin, gapTop); gapBottom = Math.min(lowerBoundary - zoneMargin, gapBottom); gapSize = gapBottom - gapTop; // Recalculate actual gap size after boundary adjustments // Ensure minimum gap size is maintained if (gapSize < minRequiredGap) { var adjustment = (minRequiredGap - gapSize) / 2; gapTop -= adjustment; gapBottom += adjustment; // Re-check boundaries after adjustment gapTop = Math.max(upperBoundary + zoneMargin, gapTop); gapBottom = Math.min(lowerBoundary - zoneMargin, gapBottom); } // Create top tower with precise positioning var topTower = game.addChild(new Tower()); topTower.x = 2200; // Start from right edge // Position tower so its bottom edge aligns with gap top topTower.y = gapTop - towerHeight / 2; // Center tower above gap topTower.lastIntersecting = false; towers.push(topTower); // Apply current tower style var currentTowerStyleData = towerStyles.find(function (style) { return style.id === currentTowerStyle; }); if (currentTowerStyleData) { topTower.children[0].tint = currentTowerStyleData.color; // Tower base topTower.children[1].tint = currentTowerStyleData.color; // Tower top } // Create bottom tower with precise positioning var bottomTower = game.addChild(new Tower()); bottomTower.x = 2200; // Start from right edge // Position tower so its top edge aligns with gap bottom bottomTower.y = gapBottom + towerHeight / 2; // Center tower below gap bottomTower.lastIntersecting = false; towers.push(bottomTower); // Apply current tower style if (currentTowerStyleData) { bottomTower.children[0].tint = currentTowerStyleData.color; // Tower base bottomTower.children[1].tint = currentTowerStyleData.color; // Tower top } // Debug verification to ensure proper gap and boundary compliance var actualGap = bottomTower.y - towerHeight / 2 - (topTower.y + towerHeight / 2); if (actualGap < minRequiredGap) { console.warn('Gap too small detected:', actualGap, 'Required:', minRequiredGap); } // Verify towers are within boundary lines if (topTower.y + towerHeight / 2 < upperBoundary || bottomTower.y - towerHeight / 2 > lowerBoundary) { console.warn('Tower positioned outside boundary lines'); } } // Function to spawn clouds function spawnCloud() { var cloud = new Cloud(); cloud.x = 2200 + Math.random() * 400; // Start from right edge with some variation cloud.y = 200 + Math.random() * 2300; // Random height across screen clouds.push(cloud); game.addChild(cloud); } // Function to spawn finish line function spawnFinishLine() { if (finishLine) return; // Don't spawn if already exists finishLine = game.addChild(new FinishLine()); finishLine.x = aircraft.x + 400; // Position finish line ahead of aircraft when progress completes finishLine.y = 1366; // Center vertically finishLine.lastIntersecting = false; } // Function to create engine particles function createEngineParticle(x, y) { if (!gameSettings.particlesEnabled || particles.length > 20) return; var particle = new Particle(); particle.x = x + (Math.random() - 0.5) * 20; particle.y = y + (Math.random() - 0.5) * 10; particles.push(particle); game.addChild(particle); } // Function to create spark particles function createSparkParticle(x, y) { if (!gameSettings.particlesEnabled || sparkParticles.length > 15) return; var spark = new SparkParticle(); spark.x = x; spark.y = y; sparkParticles.push(spark); game.addChild(spark); } // Function to create tower destruction effect function createTowerDestructionEffect(x, y) { if (!gameSettings.particlesEnabled) return; // Create multiple debris particles for (var i = 0; i < 8; i++) { var debris = new Particle(); debris.x = x + (Math.random() - 0.5) * 100; debris.y = y + (Math.random() - 0.5) * 200; debris.children[0].tint = 0x8B4513; // Brown debris color debris.velocityX = (Math.random() - 0.5) * 8; debris.velocityY = -Math.random() * 5; debris.life = 120; // Longer life for debris particles.push(debris); game.addChild(debris); } // Create sparks for (var j = 0; j < 5; j++) { createSparkParticle(x + (Math.random() - 0.5) * 80, y + (Math.random() - 0.5) * 150); } } // Function to spawn coin function spawnCoin() { var coin = new Coin(); coin.x = 2200; coin.y = 200 + Math.random() * 2300; coin.lastIntersecting = false; coins.push(coin); game.addChild(coin); } // Function to spawn power-up function spawnPowerUp() { var powerUp = new PowerUp(); powerUp.x = 2200; powerUp.y = 200 + Math.random() * 2300; powerUp.lastIntersecting = false; powerUps.push(powerUp); game.addChild(powerUp); } // Function to apply power-up effect function applyPowerUpEffect() { invulnerabilityTime = 300; // 5 seconds at 60fps comboMultiplier = Math.min(comboMultiplier + 0.5, 3); // Max 3x multiplier lastPowerUpTime = LK.ticks; // Visual feedback LK.effects.flashObject(aircraft, 0x00FFFF, 500); LK.getSound('powerup').play(); // Update aircraft appearance during invulnerability tween(aircraft, { alpha: 0.7 }, { duration: 100, onFinish: function onFinish() { tween(aircraft, { alpha: 1 }, { duration: 100 }); } }); } // Function to create level completion menu function createLevelMenu() { showingMenu = true; menuContainer = new Container(); game.addChild(menuContainer); // Semi-transparent background var menuBg = LK.getAsset('towerBase', { anchorX: 0.5, anchorY: 0.5, scaleX: 8, scaleY: 2, alpha: 0.8 }); menuBg.x = 1024; menuBg.y = 1366; menuContainer.addChild(menuBg); // Title text var titleText = new Text2('Level ' + currentLevel + ' Complete!', { size: 80, fill: 0xFFFFFF }); titleText.anchor.set(0.5, 0.5); titleText.x = 1024; titleText.y = 1200; menuContainer.addChild(titleText); // Retry button var retryText = new Text2('Retry Level', { size: 60, fill: 0x00FF00 }); retryText.anchor.set(0.5, 0.5); retryText.x = 1024; retryText.y = 1300; retryText.interactive = true; retryText.down = function () { restartCurrentLevel(); }; menuContainer.addChild(retryText); // Next level button var nextText = new Text2('Next Level', { size: 60, fill: 0x0080FF }); nextText.anchor.set(0.5, 0.5); nextText.x = 1024; nextText.y = 1400; nextText.interactive = true; nextText.down = function () { goToNextLevel(); }; menuContainer.addChild(nextText); // Return to level 1 button var returnText = new Text2('Return to Level 1', { size: 60, fill: 0xFF8000 }); returnText.anchor.set(0.5, 0.5); returnText.x = 1024; returnText.y = 1500; returnText.interactive = true; returnText.down = function () { returnToLevel1(); }; menuContainer.addChild(returnText); } // Function to restart current level function restartCurrentLevel() { hideMenu(); levelScore = 0; // Clear existing towers and finish line clearLevel(); // Reset aircraft position aircraft.x = 300; aircraft.y = 1366; // Update aircraft speed for current level aircraft.speed = Math.min(5, 3 + (currentLevel - 1) * 0.1); // Update UI progressText.setText('Progress: 0/' + towersToComplete); } // Function to go to next level function goToNextLevel() { hideMenu(); completeLevel(); } // Function to return to level 1 function returnToLevel1() { hideMenu(); currentLevel = 1; storage.currentLevel = 1; levelScore = 0; towersToComplete = 5 * currentLevel; // Clear existing towers and finish line clearLevel(); // Reset aircraft position aircraft.x = 300; aircraft.y = 1366; // Update aircraft speed for level 1 aircraft.speed = Math.min(5, 3 + (currentLevel - 1) * 0.1); // Update UI levelText.setText('Level: ' + currentLevel); progressText.setText('Progress: 0/' + towersToComplete); } // Function to create main menu function createMainMenu() { showingMainMenu = true; mainMenuContainer = new Container(); game.addChild(mainMenuContainer); // Start menu music if (gameSettings.musicEnabled) { LK.stopMusic(); LK.playMusic('menuMusic', { loop: true }); musicPlaying = false; // Reset flag so game music can start } // Semi-transparent background var menuBg = LK.getAsset('towerBase', { anchorX: 0.5, anchorY: 0.5, scaleX: 10, scaleY: 4, alpha: 0.9 }); menuBg.x = 1024; menuBg.y = 1366; mainMenuContainer.addChild(menuBg); // Game title var titleText = new Text2('TOWER DODGE', { size: 120, fill: 0xFFD700 }); titleText.anchor.set(0.5, 0.5); titleText.x = 1024; titleText.y = 600; titleText.alpha = 0; mainMenuContainer.addChild(titleText); // Animate title entrance tween(titleText, { y: 750, alpha: 1 }, { duration: 1000, easing: tween.bounceOut }); // Subtitle var subtitleText = new Text2('Navigate through the towers!', { size: 60, fill: 0xFFFFFF }); subtitleText.anchor.set(0.5, 0.5); subtitleText.x = 1024; subtitleText.y = 850; mainMenuContainer.addChild(subtitleText); // Play button var playText = new Text2('PLAY', { size: 80, fill: 0x00FF00 }); playText.anchor.set(0.5, 0.5); playText.x = 1024; playText.y = 1000; playText.alpha = 0; playText.scaleX = 0.5; playText.scaleY = 0.5; playText.interactive = true; playText.down = function () { // Add button press animation tween(playText, { scaleX: 1.2, scaleY: 1.2 }, { duration: 100, onFinish: function onFinish() { tween(playText, { scaleX: 1, scaleY: 1 }, { duration: 100 }); } }); hideMainMenu(); startGame(); }; mainMenuContainer.addChild(playText); // Animate play button entrance with delay tween(playText, { y: 1050, alpha: 1, scaleX: 1, scaleY: 1 }, { duration: 800, easing: tween.elasticOut }); // Skins button var skinsText = new Text2('SKINS', { size: 80, fill: 0x00FFFF }); skinsText.anchor.set(0.5, 0.5); skinsText.x = 1024; skinsText.y = 1150; skinsText.interactive = true; skinsText.down = function () { hideMainMenu(); showSkins(); }; mainMenuContainer.addChild(skinsText); // Codes button var codesText = new Text2('CODES', { size: 80, fill: 0xFF8000 }); codesText.anchor.set(0.5, 0.5); codesText.x = 1024; codesText.y = 1250; codesText.interactive = true; codesText.down = function () { hideMainMenu(); showCodesMenu(); }; mainMenuContainer.addChild(codesText); // Current level indicator var levelIndicatorText = new Text2('Continue from Level ' + currentLevel, { size: 50, fill: 0xFFFF00 }); levelIndicatorText.anchor.set(0.5, 0.5); levelIndicatorText.x = 1024; levelIndicatorText.y = 1350; mainMenuContainer.addChild(levelIndicatorText); // Enhanced coins display section with background var coinsDisplayBg = LK.getAsset('towerTop', { anchorX: 0.5, anchorY: 0.5, scaleX: 3.5, scaleY: 0.7, alpha: 0.4 }); coinsDisplayBg.x = 1024; coinsDisplayBg.y = 1450; mainMenuContainer.addChild(coinsDisplayBg); // Coins icon simulation using coin asset var coinsIcon = LK.getAsset('coin', { anchorX: 0.5, anchorY: 0.5, scaleX: 1.5, scaleY: 1.5 }); coinsIcon.x = 850; coinsIcon.y = 1450; mainMenuContainer.addChild(coinsIcon); // Enhanced coins indicator with larger, more prominent text var coinsIndicatorText = new Text2('Your Coins: ' + playerCoins, { size: 55, fill: 0xFFD700 }); coinsIndicatorText.anchor.set(0.5, 0.5); coinsIndicatorText.x = 1100; coinsIndicatorText.y = 1450; mainMenuContainer.addChild(coinsIndicatorText); // Add subtle animation to coins display coinsIcon.rotationSpeed = 0.02; tween(coinsIcon, { rotation: Math.PI * 2 }, { duration: 3000, loop: true, easing: tween.linear }); // Add pulsing effect to coins text tween(coinsIndicatorText, { scaleX: 1.1, scaleY: 1.1 }, { duration: 1500, loop: true, yoyo: true, easing: tween.easeInOut }); // Enhanced total score display section with background var totalScoreDisplayBg = LK.getAsset('towerTop', { anchorX: 0.5, anchorY: 0.5, scaleX: 3.5, scaleY: 0.7, alpha: 0.4 }); totalScoreDisplayBg.x = 1024; totalScoreDisplayBg.y = 1520; mainMenuContainer.addChild(totalScoreDisplayBg); // Total score icon simulation using finish flag asset var scoreIcon = LK.getAsset('finishFlag', { anchorX: 0.5, anchorY: 0.5, scaleX: 1.2, scaleY: 1.2 }); scoreIcon.x = 850; scoreIcon.y = 1520; scoreIcon.tint = 0x00FF00; mainMenuContainer.addChild(scoreIcon); // Enhanced total score indicator with larger, more prominent text var totalScoreIndicatorText = new Text2('Total Score: ' + totalScore, { size: 55, fill: 0x00FF00 }); totalScoreIndicatorText.anchor.set(0.5, 0.5); totalScoreIndicatorText.x = 1100; totalScoreIndicatorText.y = 1520; mainMenuContainer.addChild(totalScoreIndicatorText); // Add subtle animation to score display scoreIcon.rotationSpeed = 0.015; tween(scoreIcon, { rotation: Math.PI * 2 }, { duration: 4000, loop: true, easing: tween.linear }); // Add pulsing effect to total score text tween(totalScoreIndicatorText, { scaleX: 1.1, scaleY: 1.1 }, { duration: 1800, loop: true, yoyo: true, easing: tween.easeInOut }); // Version display at bottom of menu var versionText = new Text2('Version: 0.00.02', { size: 45, fill: 0x888888 }); versionText.anchor.set(0.5, 0.5); versionText.x = 1024; versionText.y = 1620; mainMenuContainer.addChild(versionText); // Add subtle fade animation to version text versionText.alpha = 0.7; tween(versionText, { alpha: 1 }, { duration: 2000, loop: true, yoyo: true, easing: tween.easeInOut }); } // Function to show codes menu function showCodesMenu() { showingCodesMenu = true; codesMenuContainer = new Container(); game.addChild(codesMenuContainer); // Create layered background for depth effect var outerBorder = LK.getAsset('towerBase', { anchorX: 0.5, anchorY: 0.5, scaleX: 11, scaleY: 4.5, alpha: 0.2 }); outerBorder.x = 1024; outerBorder.y = 1366; codesMenuContainer.addChild(outerBorder); // Main background with gradient effect var codesBg = LK.getAsset('towerBase', { anchorX: 0.5, anchorY: 0.5, scaleX: 10.5, scaleY: 4.2, alpha: 0.95 }); codesBg.x = 1024; codesBg.y = 1366; codesMenuContainer.addChild(codesBg); // Inner frame for modern look var innerFrame = LK.getAsset('towerBase', { anchorX: 0.5, anchorY: 0.5, scaleX: 10, scaleY: 4, alpha: 0.15 }); innerFrame.x = 1024; innerFrame.y = 1366; codesMenuContainer.addChild(innerFrame); // Title with enhanced styling and glow effect var titleBg = LK.getAsset('towerTop', { anchorX: 0.5, anchorY: 0.5, scaleX: 4, scaleY: 1, alpha: 0.4 }); titleBg.x = 1024; titleBg.y = 750; codesMenuContainer.addChild(titleBg); var titleText = new Text2('ENTER CODE', { size: 95, fill: 0xFFD700 }); titleText.anchor.set(0.5, 0.5); titleText.x = 1024; titleText.y = 750; codesMenuContainer.addChild(titleText); // Add animated title underline var titleUnderline = LK.getAsset('finishLine', { anchorX: 0.5, anchorY: 0.5, scaleX: 0, scaleY: 0.15 }); titleUnderline.x = 1024; titleUnderline.y = 815; codesMenuContainer.addChild(titleUnderline); // Animate underline appearance tween(titleUnderline, { scaleX: 5 }, { duration: 800, easing: tween.easeOut }); // Enhanced code input display with multiple layers var inputOuterBorder = LK.getAsset('towerBase', { anchorX: 0.5, anchorY: 0.5, scaleX: 6.5, scaleY: 0.65, alpha: 0.2 }); inputOuterBorder.x = 1024; inputOuterBorder.y = 950; codesMenuContainer.addChild(inputOuterBorder); var inputBg = LK.getAsset('towerBase', { anchorX: 0.5, anchorY: 0.5, scaleX: 6, scaleY: 0.55, alpha: 0.4 }); inputBg.x = 1024; inputBg.y = 950; codesMenuContainer.addChild(inputBg); var inputInner = LK.getAsset('towerTop', { anchorX: 0.5, anchorY: 0.5, scaleX: 5.5, scaleY: 0.45, alpha: 0.8 }); inputInner.x = 1024; inputInner.y = 950; codesMenuContainer.addChild(inputInner); var codeInputText = new Text2('', { size: 70, fill: 0x000000 }); codeInputText.anchor.set(0.5, 0.5); codeInputText.x = 1024; codeInputText.y = 950; codesMenuContainer.addChild(codeInputText); // Enhanced instructions with icon-like styling var instructionBg = LK.getAsset('towerTop', { anchorX: 0.5, anchorY: 0.5, scaleX: 4.5, scaleY: 0.4, alpha: 0.3 }); instructionBg.x = 1024; instructionBg.y = 1050; codesMenuContainer.addChild(instructionBg); var instructionText = new Text2('Tap keys below to enter your code', { size: 48, fill: 0xF0F0F0 }); instructionText.anchor.set(0.5, 0.5); instructionText.x = 1024; instructionText.y = 1050; codesMenuContainer.addChild(instructionText); // Create enhanced virtual keyboard with modern styling var currentCode = ''; var keyboardRows = ['QWERTYUIOP', 'ASDFGHJKL', 'ZXCVBNM']; var keySize = 70; var keySpacing = 130; var rowSpacing = 140; // Calculate starting positions for each row to center them perfectly with improved spacing var rowStartPositions = [1024 - (keyboardRows[0].length - 1) * keySpacing / 2, // QWERTY row 1024 - (keyboardRows[1].length - 1) * keySpacing / 2, // ASDF row 1024 - (keyboardRows[2].length - 1) * keySpacing / 2 // ZXCV row ]; for (var row = 0; row < keyboardRows.length; row++) { var letters = keyboardRows[row]; for (var col = 0; col < letters.length; col++) { var letter = letters[col]; // Create layered key design for modern look var keyShadow = LK.getAsset('towerBase', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.45, scaleY: 0.65, alpha: 0.3 }); keyShadow.x = rowStartPositions[row] + col * keySpacing + 2; keyShadow.y = 1320 + row * rowSpacing + 2; codesMenuContainer.addChild(keyShadow); var keyBg = LK.getAsset('towerTop', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.48, scaleY: 0.65, alpha: 0.9 }); keyBg.x = rowStartPositions[row] + col * keySpacing; keyBg.y = 1320 + row * rowSpacing; codesMenuContainer.addChild(keyBg); var keyHighlight = LK.getAsset('towerTop', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.44, scaleY: 0.61, alpha: 0.6 }); keyHighlight.x = rowStartPositions[row] + col * keySpacing; keyHighlight.y = 1315 + row * rowSpacing; codesMenuContainer.addChild(keyHighlight); var keyText = new Text2(letter, { size: 140, fill: 0x000000 }); keyText.anchor.set(0.5, 0.5); keyText.x = rowStartPositions[row] + col * keySpacing; keyText.y = 1320 + row * rowSpacing; keyText.interactive = true; keyText.letter = letter; keyText.keyBg = keyBg; keyText.keyHighlight = keyHighlight; keyText.keyShadow = keyShadow; keyText.down = function () { // Enhanced button press animation with multiple elements tween(this, { scaleX: 1.15, scaleY: 1.15, y: this.y + 3 }, { duration: 80, onFinish: function () { tween(this, { scaleX: 1, scaleY: 1, y: this.y - 3 }, { duration: 120, easing: tween.easeOut }); }.bind(this) }); // Animate key background tween(this.keyBg, { scaleX: 0.48, scaleY: 0.68, alpha: 1 }, { duration: 80, onFinish: function () { tween(this.keyBg, { scaleX: 0.42, scaleY: 0.62, alpha: 0.9 }, { duration: 120 }); }.bind(this) }); // Animate highlight tween(this.keyHighlight, { scaleX: 0.44, scaleY: 0.64, alpha: 0.8 }, { duration: 80, onFinish: function () { tween(this.keyHighlight, { scaleX: 0.38, scaleY: 0.58, alpha: 0.6 }, { duration: 120 }); }.bind(this) }); if (currentCode.length < 25) { currentCode += this.letter; codeInputText.setText(currentCode); // Animate input text when adding character tween(codeInputText, { scaleX: 1.1, scaleY: 1.1 }, { duration: 100, onFinish: function onFinish() { tween(codeInputText, { scaleX: 1, scaleY: 1 }, { duration: 100 }); } }); } }; codesMenuContainer.addChild(keyText); } } // Add numbers row (0-9) above the letters var numbersRow = '0123456789'; var numberRowY = 1120; var numberRowStartX = 1024 - (numbersRow.length - 1) * keySpacing / 2; for (var numCol = 0; numCol < numbersRow.length; numCol++) { var number = numbersRow[numCol]; // Add number key shadow for depth var numKeyShadow = LK.getAsset('towerBase', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.51, scaleY: 0.68, alpha: 0.3 }); numKeyShadow.x = numberRowStartX + numCol * keySpacing + 2; numKeyShadow.y = numberRowY + 2; codesMenuContainer.addChild(numKeyShadow); // Add number key background var numKeyBg = LK.getAsset('towerTop', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.48, scaleY: 0.65, alpha: 0.9 }); numKeyBg.x = numberRowStartX + numCol * keySpacing; numKeyBg.y = numberRowY; codesMenuContainer.addChild(numKeyBg); // Add number key highlight var numKeyHighlight = LK.getAsset('towerTop', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.44, scaleY: 0.61, alpha: 0.6 }); numKeyHighlight.x = numberRowStartX + numCol * keySpacing; numKeyHighlight.y = numberRowY - 2; codesMenuContainer.addChild(numKeyHighlight); var numKeyText = new Text2(number, { size: 135, fill: 0x0080FF }); numKeyText.anchor.set(0.5, 0.5); numKeyText.x = numberRowStartX + numCol * keySpacing; numKeyText.y = numberRowY; numKeyText.interactive = true; numKeyText.letter = number; numKeyText.keyBg = numKeyBg; numKeyText.keyHighlight = numKeyHighlight; numKeyText.keyShadow = numKeyShadow; numKeyText.down = function () { // Enhanced button press animation matching letter keys tween(this, { scaleX: 1.15, scaleY: 1.15, y: this.y + 3 }, { duration: 80, onFinish: function () { tween(this, { scaleX: 1, scaleY: 1, y: this.y - 3 }, { duration: 120, easing: tween.easeOut }); }.bind(this) }); // Animate key background tween(this.keyBg, { scaleX: 0.54, scaleY: 0.71, alpha: 1 }, { duration: 80, onFinish: function () { tween(this.keyBg, { scaleX: 0.48, scaleY: 0.65, alpha: 0.9 }, { duration: 120 }); }.bind(this) }); // Animate highlight tween(this.keyHighlight, { scaleX: 0.50, scaleY: 0.67, alpha: 0.8 }, { duration: 80, onFinish: function () { tween(this.keyHighlight, { scaleX: 0.44, scaleY: 0.61, alpha: 0.6 }, { duration: 120 }); }.bind(this) }); if (currentCode.length < 25) { currentCode += this.letter; codeInputText.setText(currentCode); // Animate input text when adding character tween(codeInputText, { scaleX: 1.1, scaleY: 1.1 }, { duration: 100, onFinish: function onFinish() { tween(codeInputText, { scaleX: 1, scaleY: 1 }, { duration: 100 }); } }); } }; codesMenuContainer.addChild(numKeyText); } // Create enhanced control button layout with improved design var buttonY = 1720; var buttonSpacing = 280; // Clear button with layered design (left) var clearShadow = LK.getAsset('towerBase', { anchorX: 0.5, anchorY: 0.5, scaleX: 1.3, scaleY: 0.85, alpha: 0.3 }); clearShadow.x = 1024 - buttonSpacing + 3; clearShadow.y = buttonY + 3; codesMenuContainer.addChild(clearShadow); var clearBg = LK.getAsset('towerTop', { anchorX: 0.5, anchorY: 0.5, scaleX: 1.25, scaleY: 0.82, alpha: 0.9 }); clearBg.x = 1024 - buttonSpacing; clearBg.y = buttonY; codesMenuContainer.addChild(clearBg); var clearHighlight = LK.getAsset('towerTop', { anchorX: 0.5, anchorY: 0.5, scaleX: 1.1, scaleY: 0.68, alpha: 0.4 }); clearHighlight.x = 1024 - buttonSpacing; clearHighlight.y = buttonY - 5; codesMenuContainer.addChild(clearHighlight); var clearText = new Text2('CLEAR', { size: 58, fill: 0x000000 }); clearText.anchor.set(0.5, 0.5); clearText.x = 1024 - buttonSpacing; clearText.y = buttonY; clearText.interactive = true; clearText.clearBg = clearBg; clearText.clearHighlight = clearHighlight; clearText.down = function () { // Enhanced button animation with 3D effect tween(this, { scaleX: 1.05, scaleY: 1.05, y: this.y + 2 }, { duration: 80, onFinish: function () { tween(this, { scaleX: 1, scaleY: 1, y: this.y - 2 }, { duration: 120, easing: tween.easeOut }); }.bind(this) }); // Animate background elements tween(this.clearBg, { scaleX: 1.35, scaleY: 0.9, alpha: 1 }, { duration: 80, onFinish: function () { tween(this.clearBg, { scaleX: 1.25, scaleY: 0.82, alpha: 0.9 }, { duration: 120 }); }.bind(this) }); currentCode = ''; codeInputText.setText(''); // Animate input clearing tween(codeInputText, { alpha: 0.3 }, { duration: 200, onFinish: function onFinish() { tween(codeInputText, { alpha: 1 }, { duration: 200 }); } }); }; codesMenuContainer.addChild(clearText); // Submit button with layered design (right) var submitShadow = LK.getAsset('towerBase', { anchorX: 0.5, anchorY: 0.5, scaleX: 1.3, scaleY: 0.85, alpha: 0.3 }); submitShadow.x = 1024 + buttonSpacing + 3; submitShadow.y = buttonY + 3; codesMenuContainer.addChild(submitShadow); var submitBg = LK.getAsset('towerTop', { anchorX: 0.5, anchorY: 0.5, scaleX: 1.25, scaleY: 0.82, alpha: 0.9 }); submitBg.x = 1024 + buttonSpacing; submitBg.y = buttonY; codesMenuContainer.addChild(submitBg); var submitHighlight = LK.getAsset('towerTop', { anchorX: 0.5, anchorY: 0.5, scaleX: 1.1, scaleY: 0.68, alpha: 0.4 }); submitHighlight.x = 1024 + buttonSpacing; submitHighlight.y = buttonY - 5; codesMenuContainer.addChild(submitHighlight); var submitText = new Text2('SUBMIT', { size: 58, fill: 0x000000 }); submitText.anchor.set(0.5, 0.5); submitText.x = 1024 + buttonSpacing; submitText.y = buttonY; submitText.interactive = true; submitText.submitBg = submitBg; submitText.down = function () { // Enhanced button animation tween(this, { scaleX: 1.05, scaleY: 1.05, y: this.y + 2 }, { duration: 80, onFinish: function () { tween(this, { scaleX: 1, scaleY: 1, y: this.y - 2 }, { duration: 120, easing: tween.easeOut }); }.bind(this) }); tween(this.submitBg, { scaleX: 1.35, scaleY: 0.9, alpha: 1 }, { duration: 80, onFinish: function () { tween(this.submitBg, { scaleX: 1.25, scaleY: 0.82, alpha: 0.9 }, { duration: 120 }); }.bind(this) }); if (currentCode === 'ZKUIT1GAMESSTAFFMODE') { // Success animation before activating admin mode tween(codeInputText, { fill: 0x00FF00, scaleX: 1.2, scaleY: 1.2 }, { duration: 300, onFinish: function onFinish() { // Activate admin mode for 15 minutes adminMode = true; adminModeEndTime = Date.now() + 15 * 60 * 1000; // 15 minutes in milliseconds storage.adminModeEndTime = adminModeEndTime; hideCodesMenu(); showAdminMenu(); } }); } else if (currentCode === 'LEVELS') { // Success animation before showing levels menu tween(codeInputText, { fill: 0x00FF00, scaleX: 1.2, scaleY: 1.2 }, { duration: 300, onFinish: function onFinish() { hideCodesMenu(); showLevelsMenu(); } }); } else if (currentCode === 'RESETALL') { // Success animation before resetting to level 1 tween(codeInputText, { fill: 0x00FF00, scaleX: 1.2, scaleY: 1.2 }, { duration: 300, onFinish: function onFinish() { // Reset player progress to level 1 currentLevel = 1; storage.currentLevel = 1; levelScore = 0; towersToComplete = 5 * currentLevel; // Update game settings gameSettings.highestLevelReached = 1; storage.gameSettings = gameSettings; // Clear level and reset aircraft clearLevel(); aircraft.x = 300; aircraft.y = 1366; hideCodesMenu(); createMainMenu(); } }); } else if (currentCode === 'FREEMONEYBETA2025') { // Check if this code has already been used var usedCodes = storage.usedCodes || []; if (usedCodes.indexOf('FREEMONEYBETA2025') >= 0) { // Code already used - show error tween(codeInputText, { scaleX: 1.3, scaleY: 0.8, fill: 0xFF0000 }, { duration: 150, easing: tween.easeOut, onFinish: function onFinish() { tween(codeInputText, { scaleX: 1, scaleY: 1, fill: 0x000000 }, { duration: 300, easing: tween.easeInOut }); } }); currentCode = ''; codeInputText.setText('CODE ALREADY USED'); LK.setTimeout(function () { codeInputText.setText(''); }, 2000); } else { // Success animation before awarding coins tween(codeInputText, { fill: 0x00FF00, scaleX: 1.2, scaleY: 1.2 }, { duration: 300, onFinish: function onFinish() { // Award 200 coins playerCoins += 200; storage.playerCoins = playerCoins; // Mark code as used usedCodes.push('FREEMONEYBETA2025'); storage.usedCodes = usedCodes; // Flash screen gold for success LK.effects.flashScreen(0xFFD700, 500); // Play coin sound if available if (LK.getSound('coinCollect')) { LK.getSound('coinCollect').play(); } hideCodesMenu(); createMainMenu(); } }); } } else if (currentCode === 'ORANGEFREESKIN') { // Check if this code has already been used var usedCodes = storage.usedCodes || []; if (usedCodes.indexOf('ORANGEFREESKIN') >= 0) { // Code already used - show error tween(codeInputText, { scaleX: 1.3, scaleY: 0.8, fill: 0xFF0000 }, { duration: 150, easing: tween.easeOut, onFinish: function onFinish() { tween(codeInputText, { scaleX: 1, scaleY: 1, fill: 0x000000 }, { duration: 300, easing: tween.easeInOut }); } }); currentCode = ''; codeInputText.setText('CODE ALREADY USED'); LK.setTimeout(function () { codeInputText.setText(''); }, 2000); } else { // Success animation before awarding orange skin tween(codeInputText, { fill: 0xFF8000, scaleX: 1.2, scaleY: 1.2 }, { duration: 300, onFinish: function onFinish() { // Add orange aircraft to owned styles if not already owned if (ownedAircraftStyles.indexOf('orange') < 0) { ownedAircraftStyles.push('orange'); storage.ownedAircraftStyles = ownedAircraftStyles; } // Equip the orange skin immediately currentAircraftStyle = 'orange'; storage.currentAircraftStyle = currentAircraftStyle; updateAircraftStyle(); // Mark code as used usedCodes.push('ORANGEFREESKIN'); storage.usedCodes = usedCodes; // Flash screen orange for success LK.effects.flashScreen(0xFF8000, 500); // Play coin sound if available if (LK.getSound('coinCollect')) { LK.getSound('coinCollect').play(); } hideCodesMenu(); createMainMenu(); } }); } } else if (currentCode.indexOf('TPLEVELSTAFFLV') === 0) { // Extract level number from code (format: TPLEVELSTAFFLVnumero) var levelNumberStr = currentCode.substring(14); // Remove 'TPLEVELSTAFFLV' prefix var targetLevel = parseInt(levelNumberStr, 10); // Validate level number (must be between 1 and 100) if (!isNaN(targetLevel) && targetLevel >= 1 && targetLevel <= 100) { // Success animation before teleporting to level tween(codeInputText, { fill: 0x00FF00, scaleX: 1.2, scaleY: 1.2 }, { duration: 300, onFinish: function onFinish() { // Transport player to specified level currentLevel = targetLevel; storage.currentLevel = currentLevel; levelScore = 0; towersToComplete = 5 * currentLevel; // Update game settings if new level is higher than previous highest if (currentLevel > gameSettings.highestLevelReached) { gameSettings.highestLevelReached = currentLevel; storage.gameSettings = gameSettings; } // Clear level and reset aircraft clearLevel(); aircraft.x = 300; aircraft.y = 1366; hideCodesMenu(); createMainMenu(); } }); } else { // Invalid level number - treat as wrong code tween(codeInputText, { scaleX: 1.3, scaleY: 0.8, fill: 0xFF0000 }, { duration: 150, easing: tween.easeOut, onFinish: function onFinish() { tween(codeInputText, { scaleX: 1, scaleY: 1, fill: 0x000000 }, { duration: 300, easing: tween.easeInOut }); } }); currentCode = ''; codeInputText.setText('INVALID LEVEL'); LK.setTimeout(function () { codeInputText.setText(''); }, 2000); } } else { // Enhanced wrong code animation tween(codeInputText, { scaleX: 1.3, scaleY: 0.8, fill: 0xFF0000 }, { duration: 150, easing: tween.easeOut, onFinish: function onFinish() { tween(codeInputText, { scaleX: 1, scaleY: 1, fill: 0x000000 }, { duration: 300, easing: tween.easeInOut }); } }); currentCode = ''; codeInputText.setText('INVALID CODE'); LK.setTimeout(function () { codeInputText.setText(''); }, 2000); } }; codesMenuContainer.addChild(submitText); // Back button with enhanced design (centered at bottom) var backShadow = LK.getAsset('towerBase', { anchorX: 0.5, anchorY: 0.5, scaleX: 1.1, scaleY: 0.75, alpha: 0.3 }); backShadow.x = 1024 + 2; backShadow.y = 1870 + 2; codesMenuContainer.addChild(backShadow); var backBg = LK.getAsset('towerTop', { anchorX: 0.5, anchorY: 0.5, scaleX: 1.05, scaleY: 0.72, alpha: 0.9 }); backBg.x = 1024; backBg.y = 1870; codesMenuContainer.addChild(backBg); var backText = new Text2('BACK', { size: 58, fill: 0x000000 }); backText.anchor.set(0.5, 0.5); backText.x = 1024; backText.y = 1870; backText.interactive = true; backText.backBg = backBg; backText.down = function () { // Enhanced back button animation tween(this, { scaleX: 1.05, scaleY: 1.05, y: this.y + 2 }, { duration: 80, onFinish: function () { tween(this, { scaleX: 1, scaleY: 1, y: this.y - 2 }, { duration: 120, easing: tween.easeOut }); }.bind(this) }); tween(this.backBg, { scaleX: 1.15, scaleY: 0.8, alpha: 1 }, { duration: 80, onFinish: function () { tween(this.backBg, { scaleX: 1.05, scaleY: 0.72, alpha: 0.9 }, { duration: 120 }); }.bind(this) }); hideCodesMenu(); createMainMenu(); }; codesMenuContainer.addChild(backText); // Add sophisticated entrance animations with staggered timing // Animate title with bounce effect titleText.alpha = 0; titleText.scaleX = 0.3; titleText.scaleY = 0.3; titleText.y = titleText.y - 50; tween(titleText, { alpha: 1, scaleX: 1, scaleY: 1, y: titleText.y + 50 }, { duration: 800, easing: tween.bounceOut }); // Animate input area with cascading effect inputOuterBorder.alpha = 0; inputBg.alpha = 0; inputInner.alpha = 0; codeInputText.alpha = 0; instructionText.alpha = 0; instructionBg.alpha = 0; // Staggered input area animations tween(inputOuterBorder, { alpha: 0.2 }, { duration: 300 }); LK.setTimeout(function () { tween(inputBg, { alpha: 0.4 }, { duration: 300 }); }, 100); LK.setTimeout(function () { tween(inputInner, { alpha: 0.8 }, { duration: 300 }); }, 200); LK.setTimeout(function () { tween(codeInputText, { alpha: 1 }, { duration: 400 }); }, 300); LK.setTimeout(function () { tween(instructionBg, { alpha: 0.3 }, { duration: 300 }); }, 400); LK.setTimeout(function () { tween(instructionText, { alpha: 1 }, { duration: 400 }); }, 500); // Animate keyboard keys with wave effect for (var animRow = 0; animRow < keyboardRows.length; animRow++) { for (var animCol = 0; animCol < keyboardRows[animRow].length; animCol++) { (function (row, col) { LK.setTimeout(function () { var keyIndex = row * 10 + col; // Approximate index for timing var targetKey = codesMenuContainer.children.filter(function (child) { return child.letter && child.x === rowStartPositions[row] + col * keySpacing && child.y === 1320 + row * rowSpacing; })[0]; if (targetKey) { targetKey.alpha = 0; targetKey.scaleX = 0.5; targetKey.scaleY = 0.5; tween(targetKey, { alpha: 1, scaleX: 1, scaleY: 1 }, { duration: 300, easing: tween.easeOut }); } }, 600 + row * 50 + col * 20); })(animRow, animCol); } } // Animate number keys for (var numAnimCol = 0; numAnimCol < numbersRow.length; numAnimCol++) { (function (col) { LK.setTimeout(function () { var targetNumKey = codesMenuContainer.children.filter(function (child) { return child.letter && child.x === numberRowStartX + col * keySpacing && child.y === numberRowY; })[0]; if (targetNumKey) { targetNumKey.alpha = 0; targetNumKey.scaleX = 0.5; targetNumKey.scaleY = 0.5; tween(targetNumKey, { alpha: 1, scaleX: 1, scaleY: 1 }, { duration: 300, easing: tween.easeOut }); } }, 550 + col * 25); })(numAnimCol); } // Animate control buttons with final cascade LK.setTimeout(function () { clearText.alpha = 0; clearText.scaleX = 0.8; clearText.scaleY = 0.8; tween(clearText, { alpha: 1, scaleX: 1, scaleY: 1 }, { duration: 400, easing: tween.easeOut }); }, 1200); LK.setTimeout(function () { submitText.alpha = 0; submitText.scaleX = 0.8; submitText.scaleY = 0.8; tween(submitText, { alpha: 1, scaleX: 1, scaleY: 1 }, { duration: 400, easing: tween.easeOut }); }, 1300); LK.setTimeout(function () { backText.alpha = 0; backText.scaleX = 0.8; backText.scaleY = 0.8; tween(backText, { alpha: 1, scaleX: 1, scaleY: 1 }, { duration: 400, easing: tween.easeOut }); }, 1400); } // Function to show skins function showSkins() { showingSkins = true; skinsContainer = new Container(); game.addChild(skinsContainer); // Simple main background var skinsBg = LK.getAsset('towerBase', { anchorX: 0.5, anchorY: 0.5, scaleX: 10, scaleY: 4.5, alpha: 0.9 }); skinsBg.x = 1024; skinsBg.y = 1366; skinsContainer.addChild(skinsBg); // Clean title var titleText = new Text2('SKINS', { size: 80, fill: 0xFFD700 }); titleText.anchor.set(0.5, 0.5); titleText.x = 1024; titleText.y = 400; skinsContainer.addChild(titleText); // Simple coins display var coinsDisplayText = new Text2('Coins: ' + playerCoins, { size: 50, fill: 0xFFD700 }); coinsDisplayText.anchor.set(0.5, 0.5); coinsDisplayText.x = 1024; coinsDisplayText.y = 480; skinsContainer.addChild(coinsDisplayText); // Store reference to update coins display throughout skins skinsContainer.coinsDisplayText = coinsDisplayText; // Add function to update coins display with animation skinsContainer.updateCoinsDisplay = function (newAmount) { // Flash effect on coins change tween(this.coinsDisplayText, { scaleX: 1.2, scaleY: 1.2, fill: 0x00FF00 }, { duration: 200, onFinish: function () { this.coinsDisplayText.setText('Coins: ' + newAmount); tween(this.coinsDisplayText, { scaleX: 1, scaleY: 1, fill: 0xFFD700 }, { duration: 300, easing: tween.bounceOut }); }.bind(this) }); }; // Simple centered layout with increased spacing var centerX = 1024; var itemStartY = 600; var itemSpacing = 120; // Aircraft styles section title var aircraftTitleText = new Text2('AIRCRAFT STYLES', { size: 55, fill: 0xFFFFFF }); aircraftTitleText.anchor.set(0.5, 0.5); aircraftTitleText.x = centerX; aircraftTitleText.y = 560; shopContainer.addChild(aircraftTitleText); // Create display array that includes orange skin if unlocked var displayAircraftStyles = aircraftStyles.slice(); // Copy base array var usedCodes = storage.usedCodes || []; if (usedCodes.indexOf('ORANGEFREESKIN') >= 0) { displayAircraftStyles.push(orangeAircraftStyle); } // Aircraft items with clean design for (var a = 0; a < displayAircraftStyles.length; a++) { var aircraftItem = displayAircraftStyles[a]; var isOwned = ownedAircraftStyles.indexOf(aircraftItem.id) >= 0; var isEquipped = currentAircraftStyle === aircraftItem.id; // Simple item card var itemBg = LK.getAsset('towerTop', { anchorX: 0.5, anchorY: 0.5, scaleX: 6, scaleY: 1.2, alpha: isEquipped ? 0.9 : 0.7 }); itemBg.x = centerX; itemBg.y = itemStartY + a * itemSpacing; if (isEquipped) itemBg.tint = 0x00AA66; skinsContainer.addChild(itemBg); // Aircraft preview var previewAircraft = LK.getAsset('aircraft', { anchorX: 0.5, anchorY: 0.5, scaleX: 1.2, scaleY: 1.2 }); previewAircraft.x = centerX - 250; previewAircraft.y = itemStartY + a * itemSpacing; previewAircraft.tint = aircraftItem.color; skinsContainer.addChild(previewAircraft); // Item name var itemNameText = new Text2(aircraftItem.name, { size: 44, fill: 0x000000 }); itemNameText.anchor.set(0, 0.5); itemNameText.x = centerX - 120; itemNameText.y = itemStartY + a * itemSpacing; skinsContainer.addChild(itemNameText); // Purchase button var buttonText = isOwned ? isEquipped ? 'EQUIPPED' : 'EQUIP' : 'BUY ' + aircraftItem.price; var buttonColor = isOwned ? isEquipped ? 0x888888 : 0x00AA00 : playerCoins >= aircraftItem.price ? 0x0066CC : 0xCC0000; var itemButton = new Text2(buttonText, { size: 38, fill: buttonColor }); itemButton.anchor.set(0.5, 0.5); itemButton.x = centerX + 200; itemButton.y = itemStartY + a * itemSpacing; itemButton.aircraftItem = aircraftItem; itemButton.isOwned = isOwned; itemButton.isEquipped = isEquipped; if (!isEquipped) { itemButton.interactive = true; itemButton.down = function () { // Simple button animation tween(this, { scaleX: 1.1, scaleY: 1.1 }, { duration: 100, easing: tween.easeOut, onFinish: function () { tween(this, { scaleX: 1, scaleY: 1 }, { duration: 100 }); }.bind(this) }); if (this.isOwned) { // Equip item currentAircraftStyle = this.aircraftItem.id; storage.currentAircraftStyle = currentAircraftStyle; updateAircraftStyle(); LK.effects.flashScreen(0x00FF00, 300); hideSkins(); showSkins(); } else if (playerCoins >= this.aircraftItem.price) { // Purchase item playerCoins -= this.aircraftItem.price; storage.playerCoins = playerCoins; ownedAircraftStyles.push(this.aircraftItem.id); storage.ownedAircraftStyles = ownedAircraftStyles; currentAircraftStyle = this.aircraftItem.id; storage.currentAircraftStyle = currentAircraftStyle; updateAircraftStyle(); LK.effects.flashScreen(0xFFD700, 500); if (LK.getSound('coinCollect')) { LK.getSound('coinCollect').play(); } hideSkins(); showSkins(); } else { // Insufficient funds LK.effects.flashObject(this, 0xFF0000, 300); } }; } skinsContainer.addChild(itemButton); } // Simple back button var backText = new Text2('BACK', { size: 50, fill: 0xFFFFFF }); backText.anchor.set(0.5, 0.5); backText.x = 1024; backText.y = 1800; backText.interactive = true; backText.down = function () { // Simple button animation tween(this, { scaleX: 1.1, scaleY: 1.1 }, { duration: 100, onFinish: function () { tween(this, { scaleX: 1, scaleY: 1 }, { duration: 100 }); }.bind(this) }); hideSkins(); createMainMenu(); }; skinsContainer.addChild(backText); // Simple fade-in animation skinsContainer.alpha = 0; tween(skinsContainer, { alpha: 1 }, { duration: 300 }); } // Function to hide skins function hideSkins() { if (skinsContainer) { skinsContainer.destroy(); skinsContainer = null; } showingSkins = false; } // Function to update aircraft style function updateAircraftStyle() { // Create search array that includes orange skin if unlocked var searchAircraftStyles = aircraftStyles.slice(); var usedCodes = storage.usedCodes || []; if (usedCodes.indexOf('ORANGEFREESKIN') >= 0) { searchAircraftStyles.push(orangeAircraftStyle); } var styleData = searchAircraftStyles.find(function (style) { return style.id === currentAircraftStyle; }); if (styleData && aircraft) { // Apply color to main aircraft components aircraft.children[0].tint = styleData.color; // Main aircraft body aircraft.children[1].tint = styleData.color; // Main wing aircraft.children[4].tint = styleData.color; // Tail aircraft.children[5].tint = styleData.color; // Horizontal stabilizer // Apply slightly darker tint to engines and details var darkerTint = styleData.color * 0.8; if (aircraft.children[8]) aircraft.children[8].tint = darkerTint; // Left engine if (aircraft.children[9]) aircraft.children[9].tint = darkerTint; // Right engine if (aircraft.children[10]) aircraft.children[10].tint = darkerTint; // Left gear if (aircraft.children[11]) aircraft.children[11].tint = darkerTint; // Right gear } } // Function to hide codes menu function hideCodesMenu() { if (codesMenuContainer) { codesMenuContainer.destroy(); codesMenuContainer = null; } showingCodesMenu = false; } // Function to show levels menu function showLevelsMenu() { var levelsMenuContainer = new Container(); game.addChild(levelsMenuContainer); // Semi-transparent background var levelsBg = LK.getAsset('towerBase', { anchorX: 0.5, anchorY: 0.5, scaleX: 10, scaleY: 4.5, alpha: 0.95 }); levelsBg.x = 1024; levelsBg.y = 1366; levelsMenuContainer.addChild(levelsBg); // Title var titleText = new Text2('ALL LEVELS', { size: 90, fill: 0xFFD700 }); titleText.anchor.set(0.5, 0.5); titleText.x = 1024; titleText.y = 400; levelsMenuContainer.addChild(titleText); // Subtitle with completion info var completedLevels = gameSettings.highestLevelReached; var subtitleText = new Text2('Completed: ' + completedLevels + '/100', { size: 60, fill: 0x00FF00 }); subtitleText.anchor.set(0.5, 0.5); subtitleText.x = 1024; subtitleText.y = 500; levelsMenuContainer.addChild(subtitleText); // Add coins balance display in levels menu var levelCoinsDisplayBg = LK.getAsset('towerTop', { anchorX: 0.5, anchorY: 0.5, scaleX: 2.5, scaleY: 0.5, alpha: 0.4 }); levelCoinsDisplayBg.x = 1024; levelCoinsDisplayBg.y = 550; levelsMenuContainer.addChild(levelCoinsDisplayBg); var levelCoinsText = new Text2('Your Coins: ' + playerCoins, { size: 45, fill: 0xFFD700 }); levelCoinsText.anchor.set(0.5, 0.5); levelCoinsText.x = 1024; levelCoinsText.y = 550; levelsMenuContainer.addChild(levelCoinsText); // Create scrollable container for levels var scrollContainer = new Container(); levelsMenuContainer.addChild(scrollContainer); // Create level display in grid format (10 columns, 10 rows for 100 levels) for (var level = 1; level <= 100; level++) { var isCompleted = level <= completedLevels; var levelButton = new Text2(level.toString(), { size: 35, fill: isCompleted ? 0x00FF00 : 0x888888 // Green if completed, gray if not }); levelButton.anchor.set(0.5, 0.5); // Position in 10x10 grid levelButton.x = 300 + (level - 1) % 10 * 145; levelButton.y = 650 + Math.floor((level - 1) / 10) * 60; // Add background for better visibility var levelBg = LK.getAsset('towerTop', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.7, scaleY: 0.7, alpha: isCompleted ? 0.8 : 0.3 }); levelBg.x = levelButton.x; levelBg.y = levelButton.y; scrollContainer.addChild(levelBg); scrollContainer.addChild(levelButton); // Add completion checkmark for completed levels if (isCompleted) { var checkmark = new Text2('✓', { size: 25, fill: 0xFFD700 }); checkmark.anchor.set(0.5, 0.5); checkmark.x = levelButton.x + 25; checkmark.y = levelButton.y - 25; scrollContainer.addChild(checkmark); } } // Add scroll instruction var scrollText = new Text2('Scroll to see all levels', { size: 45, fill: 0xFFFF00 }); scrollText.anchor.set(0.5, 0.5); scrollText.x = 1024; scrollText.y = 600; levelsMenuContainer.addChild(scrollText); // Add scroll functionality var scrollY = 0; var maxScroll = Math.max(0, Math.ceil(100 / 10) * 60 - 500); levelsMenuContainer.interactive = true; levelsMenuContainer.move = function (x, y, obj) { if (obj.deltaY) { scrollY -= obj.deltaY * 2; scrollY = Math.max(-maxScroll, Math.min(0, scrollY)); scrollContainer.y = scrollY; } }; // Back button var backText = new Text2('BACK', { size: 60, fill: 0xFF8000 }); backText.anchor.set(0.5, 0.5); backText.x = 1024; backText.y = 1600; backText.interactive = true; backText.down = function () { levelsMenuContainer.destroy(); createMainMenu(); }; levelsMenuContainer.addChild(backText); // Add entrance animation levelsMenuContainer.alpha = 0; tween(levelsMenuContainer, { alpha: 1 }, { duration: 500, easing: tween.easeOut }); } // Function to show admin menu function showAdminMenu() { var adminMenuContainer = new Container(); game.addChild(adminMenuContainer); // Semi-transparent background var adminBg = LK.getAsset('towerBase', { anchorX: 0.5, anchorY: 0.5, scaleX: 8, scaleY: 4, alpha: 0.9 }); adminBg.x = 1024; adminBg.y = 1366; adminMenuContainer.addChild(adminBg); // Title var titleText = new Text2('ADMIN MODE ACTIVATED', { size: 70, fill: 0xFF0000 }); titleText.anchor.set(0.5, 0.5); titleText.x = 1024; titleText.y = 600; adminMenuContainer.addChild(titleText); // Level selection title var levelSelectText = new Text2('SELECT LEVEL:', { size: 60, fill: 0xFFFFFF }); levelSelectText.anchor.set(0.5, 0.5); levelSelectText.x = 1024; levelSelectText.y = 800; adminMenuContainer.addChild(levelSelectText); // Create scrollable level buttons (1-100) var scrollContainer = new Container(); adminMenuContainer.addChild(scrollContainer); // Create level buttons in a grid layout for (var level = 1; level <= 100; level++) { var levelButton = new Text2(level.toString(), { size: 35, fill: 0x00FF00 }); levelButton.anchor.set(0.5, 0.5); // 10 columns, 10 rows for 100 levels levelButton.x = 300 + (level - 1) % 10 * 145; levelButton.y = 900 + Math.floor((level - 1) / 10) * 60; levelButton.interactive = true; levelButton.targetLevel = level; levelButton.down = function () { currentLevel = this.targetLevel; storage.currentLevel = currentLevel; adminMenuContainer.destroy(); createMainMenu(); }; scrollContainer.addChild(levelButton); } // Add scroll instruction text var scrollText = new Text2('Scroll to see all 100 levels', { size: 40, fill: 0xFFFF00 }); scrollText.anchor.set(0.5, 0.5); scrollText.x = 1024; scrollText.y = 850; adminMenuContainer.addChild(scrollText); // Add scroll functionality var scrollY = 0; var maxScroll = Math.max(0, Math.ceil(100 / 10) * 60 - 400); // Adjust based on visible area adminMenuContainer.interactive = true; adminMenuContainer.move = function (x, y, obj) { if (obj.deltaY) { scrollY -= obj.deltaY * 2; scrollY = Math.max(-maxScroll, Math.min(0, scrollY)); scrollContainer.y = scrollY; } }; // Back button var backText = new Text2('BACK TO MENU', { size: 50, fill: 0xFF8000 }); backText.anchor.set(0.5, 0.5); backText.x = 1024; backText.y = 1500; backText.interactive = true; backText.down = function () { adminMenuContainer.destroy(); createMainMenu(); }; adminMenuContainer.addChild(backText); } // Function to hide main menu function hideMainMenu() { if (mainMenuContainer) { mainMenuContainer.destroy(); mainMenuContainer = null; } showingMainMenu = false; } // Function to start game function startGame() { gameStarted = true; // Reset game state levelScore = 0; towersToComplete = 5 * currentLevel; invulnerabilityTime = 0; comboMultiplier = 1; powerUpSpawnTimer = 0; // Clear any existing game objects clearLevel(); // Reset aircraft position aircraft.x = 300; aircraft.y = 1366; // Update UI levelText.setText('Level: ' + currentLevel); progressText.setText('Progress: 0/' + towersToComplete); scoreText.setText('Score: ' + LK.getScore()); coinsText.setText('Coins: ' + playerCoins); // Apply current aircraft style updateAircraftStyle(); // Update aircraft speed for current level aircraft.speed = Math.min(5, 3 + (currentLevel - 1) * 0.1); // Start background music if (gameSettings.musicEnabled && !musicPlaying) { LK.stopMusic(); // Stop any menu music LK.playMusic('backgroundMusic', { loop: true }); musicPlaying = true; } } // Function to hide menu function hideMenu() { if (menuContainer) { menuContainer.destroy(); menuContainer = null; } showingMenu = false; gameStarted = true; } // Function to clear level objects function clearLevel() { // Clear existing towers for (var i = towers.length - 1; i >= 0; i--) { towers[i].destroy(); towers.splice(i, 1); } // Clear finish line if (finishLine) { finishLine.destroy(); finishLine = null; } // Clear existing clouds for (var c = clouds.length - 1; c >= 0; c--) { clouds[c].destroy(); clouds.splice(c, 1); } // Clear power-ups for (var p = powerUps.length - 1; p >= 0; p--) { powerUps[p].destroy(); powerUps.splice(p, 1); } // Clear particles for (var pt = particles.length - 1; pt >= 0; pt--) { particles[pt].destroy(); particles.splice(pt, 1); } // Clear spark particles for (var sp = sparkParticles.length - 1; sp >= 0; sp--) { sparkParticles[sp].destroy(); sparkParticles.splice(sp, 1); } // Clear coins for (var co = coins.length - 1; co >= 0; co--) { coins[co].destroy(); coins.splice(co, 1); } } // Function to complete level function completeLevel() { currentLevel++; // Save progress to storage storage.currentLevel = currentLevel; levelScore = 0; towersToComplete = 5 * currentLevel; // Level 1: 5, Level 2: 10, Level 3: 15, etc. // Reset power-up system invulnerabilityTime = 0; comboMultiplier = 1; powerUpSpawnTimer = 0; // Clear existing towers and finish line clearLevel(); // Reset aircraft position aircraft.x = 300; aircraft.y = 1366; // Update aircraft speed for new level aircraft.speed = Math.min(5, 3 + (currentLevel - 1) * 0.1); // Update UI levelText.setText('Level: ' + currentLevel); progressText.setText('Progress: 0/' + towersToComplete); // Enhanced level completion effects with camera shake startCameraShake(10, 60); // Gentle celebration shake LK.effects.flashScreen(0x00ff00, 1000); LK.getSound('levelComplete').play(); // Bonus score for completing level with progressive rewards var bonusScore = 100 * currentLevel * comboMultiplier; var milestoneBonus = 0; // Milestone bonuses for every 10 levels if (currentLevel % 10 === 0) { milestoneBonus = 1000 * (currentLevel / 10); playerCoins += 50; // Bonus coins for milestone storage.playerCoins = playerCoins; coinsText.setText('Coins: ' + playerCoins); } LK.setScore(LK.getScore() + bonusScore + milestoneBonus); scoreText.setText('Score: ' + LK.getScore()); // Update total score with session progress totalScore += bonusScore + milestoneBonus; storage.totalScore = totalScore; // Create celebration particles for (var i = 0; i < 10; i++) { LK.setTimeout(function () { createSparkParticle(aircraft.x + (Math.random() - 0.5) * 200, aircraft.y + (Math.random() - 0.5) * 100); }, i * 50); } } // Enhanced camera shake system var cameraShake = { active: false, intensity: 0, duration: 0, originalX: 0, originalY: 0 }; function startCameraShake(intensity, duration) { if (!gameSettings.screenshakeEnabled) return; cameraShake.active = true; cameraShake.intensity = intensity; cameraShake.duration = duration; cameraShake.originalX = game.x; cameraShake.originalY = game.y; } function updateCameraShake() { if (!cameraShake.active) return; cameraShake.duration--; if (cameraShake.duration <= 0) { cameraShake.active = false; game.x = cameraShake.originalX; game.y = cameraShake.originalY; return; } var shakeX = (Math.random() - 0.5) * cameraShake.intensity; var shakeY = (Math.random() - 0.5) * cameraShake.intensity; game.x = cameraShake.originalX + shakeX; game.y = cameraShake.originalY + shakeY; } // Function to handle game over function gameOver() { // Add current session score to total score totalScore += LK.getScore(); storage.totalScore = totalScore; // Save current level to storage so player can restart from this level storage.currentLevel = currentLevel; // Enhanced screen shake for dramatic effect startCameraShake(25, 120); LK.effects.flashScreen(0xff0000, 1000); LK.getSound('crash').play(); LK.showGameOver(); } // Main game update loop game.update = function () { // Update camera shake system updateCameraShake(); // Check if admin mode has expired if (adminMode && Date.now() > adminModeEndTime) { adminMode = false; adminModeEndTime = 0; storage.adminModeEndTime = 0; } if (!gameStarted || showingMenu || showingMainMenu || showingCodesMenu || showingSkins) return; // Update invulnerability if (invulnerabilityTime > 0) { invulnerabilityTime--; if (invulnerabilityTime === 0) { aircraft.alpha = 1; // Restore normal appearance } } // Update combo multiplier decay if (LK.ticks - lastPowerUpTime > 1800) { // 30 seconds comboMultiplier = Math.max(1, comboMultiplier - 0.01); } // Spawn clouds for background atmosphere if (LK.ticks % 180 === 0) { // Spawn cloud every 3 seconds at 60fps spawnCloud(); } // Spawn coins coinSpawnTimer++; if (coinSpawnTimer > 180 + Math.random() * 120) { // Every 3-5 seconds spawnCoin(); coinSpawnTimer = 0; } // Spawn power-ups powerUpSpawnTimer++; if (powerUpSpawnTimer > 600 + Math.random() * 300) { // Every 10-15 seconds spawnPowerUp(); powerUpSpawnTimer = 0; } // Update clouds for (var c = clouds.length - 1; c >= 0; c--) { var cloud = clouds[c]; // Remove clouds that have moved off screen if (cloud.x < -200) { cloud.destroy(); clouds.splice(c, 1); } } // Update coins for (var co = coins.length - 1; co >= 0; co--) { var coin = coins[co]; // Remove if off screen if (coin.x < -100) { coin.destroy(); coins.splice(co, 1); continue; } // Check collection var coinIntersecting = aircraft.intersects(coin); if (!coin.lastIntersecting && coinIntersecting && !coin.collected) { coin.collected = true; playerCoins += 5; // Award 5 coins per collection storage.playerCoins = playerCoins; coinsText.setText('Coins: ' + playerCoins); // Coin collection effect LK.effects.flashObject(coin, 0xFFD700, 300); LK.getSound('coinCollect').play(); // Create coin text popup var coinPopup = new Text2('+5', { size: 40, fill: 0xFFD700 }); coinPopup.anchor.set(0.5, 0.5); coinPopup.x = coin.x; coinPopup.y = coin.y; game.addChild(coinPopup); tween(coinPopup, { y: coinPopup.y - 80, alpha: 0 }, { duration: 1000, easing: tween.easeOut, onFinish: function onFinish() { coinPopup.destroy(); } }); coin.destroy(); coins.splice(co, 1); continue; } coin.lastIntersecting = coinIntersecting; } // Update spark particles for (var sp = sparkParticles.length - 1; sp >= 0; sp--) { var spark = sparkParticles[sp]; // Particles are automatically removed in their update method } // Update power-ups for (var p = powerUps.length - 1; p >= 0; p--) { var powerUp = powerUps[p]; // Remove if off screen if (powerUp.x < -100) { powerUp.destroy(); powerUps.splice(p, 1); continue; } // Check collection var currentIntersecting = aircraft.intersects(powerUp); if (!powerUp.lastIntersecting && currentIntersecting && !powerUp.collected) { powerUp.collected = true; applyPowerUpEffect(); powerUp.destroy(); powerUps.splice(p, 1); continue; } powerUp.lastIntersecting = currentIntersecting; } // Spawn towers based on level difficulty (adjusted for levels 1-100) with increased separation var spawnRate = Math.max(90, 420 - Math.min(currentLevel, 15) * 20); // Increased base separation between tower pairs if (LK.ticks % spawnRate === 0) { spawnTower(); } // Check if we should spawn finish line - spawn exactly when progress reaches target var progress = Math.floor(levelScore / 2); if (progress === towersToComplete && !finishLine) { spawnFinishLine(); } // Update finish line if (finishLine) { // Check if finish line went off screen if (finishLine.lastX >= -200 && finishLine.x < -200) { finishLine.destroy(); finishLine = null; } // Check if aircraft crossed finish line if (!finishLine.crossed && finishLine.x < aircraft.x) { finishLine.crossed = true; createLevelMenu(); return; } } // Update towers for (var i = towers.length - 1; i >= 0; i--) { var tower = towers[i]; // Check if tower went off screen if (tower.lastX >= -200 && tower.x < -200) { towers.splice(i, 1); tower.destroy(); continue; } // Check collision with aircraft (skip if invulnerable) var currentIntersecting = aircraft.intersects(tower); if (!tower.lastIntersecting && currentIntersecting && invulnerabilityTime <= 0) { // Create dramatic collision effect createTowerDestructionEffect(tower.x, tower.y); startCameraShake(30, 100); LK.getSound('crash').play(); gameOver(); return; } tower.lastIntersecting = currentIntersecting; // Check if aircraft passed tower (score point) if (!tower.passed && tower.x < aircraft.x - 100) { tower.passed = true; levelScore++; var basePoints = 10 * currentLevel; var bonusPoints = Math.floor(basePoints * comboMultiplier); LK.setScore(LK.getScore() + bonusPoints); LK.getSound('dodge').play(); LK.getSound('whoosh').play(); // Update progress - count obstacles (pairs of towers) correctly var progress = Math.floor(levelScore / 2); // Two towers per obstacle pair progressText.setText('Progress: ' + progress + '/' + towersToComplete); scoreText.setText('Score: ' + LK.getScore()); // Create score popup for bonus points if (comboMultiplier > 1) { var bonusText = new Text2('+' + bonusPoints + ' (x' + comboMultiplier.toFixed(1) + ')', { size: 40, fill: 0xFFD700 }); bonusText.anchor.set(0.5, 0.5); bonusText.x = aircraft.x; bonusText.y = aircraft.y - 50; game.addChild(bonusText); // Animate bonus text tween(bonusText, { y: bonusText.y - 100, alpha: 0 }, { duration: 1000, easing: tween.easeOut, onFinish: function onFinish() { bonusText.destroy(); } }); } // Animate score text to highlight points earned tween.stop(scoreText, { scaleX: true, scaleY: true }); tween(scoreText, { scaleX: 1.3, scaleY: 1.3 }, { duration: 200, easing: tween.easeOut, onFinish: function onFinish() { tween(scoreText, { scaleX: 1, scaleY: 1 }, { duration: 200, easing: tween.easeIn }); } }); } } // Dynamic background color system based on level var targetBackgroundColor = 0x87CEFA; // Default sky blue if (currentLevel >= 80) { targetBackgroundColor = 0x2F1B69; // Deep purple for high levels } else if (currentLevel >= 60) { targetBackgroundColor = 0x1a1a2e; // Dark blue } else if (currentLevel >= 40) { targetBackgroundColor = 0x16213e; // Navy blue } else if (currentLevel >= 20) { targetBackgroundColor = 0x0f3460; // Medium blue } // Gradually transition background color every few seconds if (LK.ticks % 300 === 0) { // Every 5 seconds var currentBg = game.backgroundColor || 0x87CEFA; if (currentBg !== targetBackgroundColor) { // Simple color transition by setting it directly game.setBackgroundColor(targetBackgroundColor); } } // Aircraft stays stationary while towers move to create forward movement illusion };
===================================================================
--- original.js
+++ change.js
@@ -488,10 +488,10 @@
var lastPowerUpTime = 0;
var musicPlaying = false;
var coins = [];
var coinSpawnTimer = 0;
-var showingShop = false;
-var shopContainer = null;
+var showingSkins = false;
+var skinsContainer = null;
// Initialize player coins and shop items
var playerCoins = storage.playerCoins || 0;
var totalScore = storage.totalScore || 0;
var ownedAircraftStyles = storage.ownedAircraftStyles || ['default'];
@@ -1050,22 +1050,22 @@
}, {
duration: 800,
easing: tween.elasticOut
});
- // Shop button
- var shopText = new Text2('SHOP', {
+ // Skins button
+ var skinsText = new Text2('SKINS', {
size: 80,
fill: 0x00FFFF
});
- shopText.anchor.set(0.5, 0.5);
- shopText.x = 1024;
- shopText.y = 1150;
- shopText.interactive = true;
- shopText.down = function () {
+ skinsText.anchor.set(0.5, 0.5);
+ skinsText.x = 1024;
+ skinsText.y = 1150;
+ skinsText.interactive = true;
+ skinsText.down = function () {
hideMainMenu();
- showShop();
+ showSkins();
};
- mainMenuContainer.addChild(shopText);
+ mainMenuContainer.addChild(skinsText);
// Codes button
var codesText = new Text2('CODES', {
size: 80,
fill: 0xFF8000
@@ -2249,46 +2249,46 @@
easing: tween.easeOut
});
}, 1400);
}
-// Function to show shop
-function showShop() {
- showingShop = true;
- shopContainer = new Container();
- game.addChild(shopContainer);
+// Function to show skins
+function showSkins() {
+ showingSkins = true;
+ skinsContainer = new Container();
+ game.addChild(skinsContainer);
// Simple main background
- var shopBg = LK.getAsset('towerBase', {
+ var skinsBg = LK.getAsset('towerBase', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 10,
scaleY: 4.5,
alpha: 0.9
});
- shopBg.x = 1024;
- shopBg.y = 1366;
- shopContainer.addChild(shopBg);
+ skinsBg.x = 1024;
+ skinsBg.y = 1366;
+ skinsContainer.addChild(skinsBg);
// Clean title
- var titleText = new Text2('SHOP', {
+ var titleText = new Text2('SKINS', {
size: 80,
fill: 0xFFD700
});
titleText.anchor.set(0.5, 0.5);
titleText.x = 1024;
titleText.y = 400;
- shopContainer.addChild(titleText);
+ skinsContainer.addChild(titleText);
// Simple coins display
var coinsDisplayText = new Text2('Coins: ' + playerCoins, {
size: 50,
fill: 0xFFD700
});
coinsDisplayText.anchor.set(0.5, 0.5);
coinsDisplayText.x = 1024;
coinsDisplayText.y = 480;
- shopContainer.addChild(coinsDisplayText);
- // Store reference to update coins display throughout shop
- shopContainer.coinsDisplayText = coinsDisplayText;
+ skinsContainer.addChild(coinsDisplayText);
+ // Store reference to update coins display throughout skins
+ skinsContainer.coinsDisplayText = coinsDisplayText;
// Add function to update coins display with animation
- shopContainer.updateCoinsDisplay = function (newAmount) {
+ skinsContainer.updateCoinsDisplay = function (newAmount) {
// Flash effect on coins change
tween(this.coinsDisplayText, {
scaleX: 1.2,
scaleY: 1.2,
@@ -2342,9 +2342,9 @@
});
itemBg.x = centerX;
itemBg.y = itemStartY + a * itemSpacing;
if (isEquipped) itemBg.tint = 0x00AA66;
- shopContainer.addChild(itemBg);
+ skinsContainer.addChild(itemBg);
// Aircraft preview
var previewAircraft = LK.getAsset('aircraft', {
anchorX: 0.5,
anchorY: 0.5,
@@ -2353,18 +2353,18 @@
});
previewAircraft.x = centerX - 250;
previewAircraft.y = itemStartY + a * itemSpacing;
previewAircraft.tint = aircraftItem.color;
- shopContainer.addChild(previewAircraft);
+ skinsContainer.addChild(previewAircraft);
// Item name
var itemNameText = new Text2(aircraftItem.name, {
size: 44,
fill: 0x000000
});
itemNameText.anchor.set(0, 0.5);
itemNameText.x = centerX - 120;
itemNameText.y = itemStartY + a * itemSpacing;
- shopContainer.addChild(itemNameText);
+ skinsContainer.addChild(itemNameText);
// Purchase button
var buttonText = isOwned ? isEquipped ? 'EQUIPPED' : 'EQUIP' : 'BUY ' + aircraftItem.price;
var buttonColor = isOwned ? isEquipped ? 0x888888 : 0x00AA00 : playerCoins >= aircraftItem.price ? 0x0066CC : 0xCC0000;
var itemButton = new Text2(buttonText, {
@@ -2401,10 +2401,10 @@
currentAircraftStyle = this.aircraftItem.id;
storage.currentAircraftStyle = currentAircraftStyle;
updateAircraftStyle();
LK.effects.flashScreen(0x00FF00, 300);
- hideShop();
- showShop();
+ hideSkins();
+ showSkins();
} else if (playerCoins >= this.aircraftItem.price) {
// Purchase item
playerCoins -= this.aircraftItem.price;
storage.playerCoins = playerCoins;
@@ -2416,17 +2416,17 @@
LK.effects.flashScreen(0xFFD700, 500);
if (LK.getSound('coinCollect')) {
LK.getSound('coinCollect').play();
}
- hideShop();
- showShop();
+ hideSkins();
+ showSkins();
} else {
// Insufficient funds
LK.effects.flashObject(this, 0xFF0000, 300);
}
};
}
- shopContainer.addChild(itemButton);
+ skinsContainer.addChild(itemButton);
}
// Simple back button
var backText = new Text2('BACK', {
size: 50,
@@ -2451,27 +2451,27 @@
duration: 100
});
}.bind(this)
});
- hideShop();
+ hideSkins();
createMainMenu();
};
- shopContainer.addChild(backText);
+ skinsContainer.addChild(backText);
// Simple fade-in animation
- shopContainer.alpha = 0;
- tween(shopContainer, {
+ skinsContainer.alpha = 0;
+ tween(skinsContainer, {
alpha: 1
}, {
duration: 300
});
}
-// Function to hide shop
-function hideShop() {
- if (shopContainer) {
- shopContainer.destroy();
- shopContainer = null;
+// Function to hide skins
+function hideSkins() {
+ if (skinsContainer) {
+ skinsContainer.destroy();
+ skinsContainer = null;
}
- showingShop = false;
+ showingSkins = false;
}
// Function to update aircraft style
function updateAircraftStyle() {
// Create search array that includes orange skin if unlocked
@@ -2916,9 +2916,9 @@
adminMode = false;
adminModeEndTime = 0;
storage.adminModeEndTime = 0;
}
- if (!gameStarted || showingMenu || showingMainMenu || showingCodesMenu || showingShop) return;
+ if (!gameStarted || showingMenu || showingMainMenu || showingCodesMenu || showingSkins) return;
// Update invulnerability
if (invulnerabilityTime > 0) {
invulnerabilityTime--;
if (invulnerabilityTime === 0) {