User prompt
Please fix the bug: 'Script error.' in or related to this line: 'var lengthValue = new Text2(storage.editorState.currentLevel.length.toString(), {' Line Number: 5039 βͺπ‘ Consider importing and using the following plugins: @upit/storage.v1
User prompt
Please fix the bug: 'Script error.' in or related to this line: 'storage.editorState.currentLevel = {};' Line Number: 4764 βͺπ‘ Consider importing and using the following plugins: @upit/storage.v1
User prompt
Please fix the bug: 'Script error.' in or related to this line: 'storage.editorState = {' Line Number: 4758 βͺπ‘ Consider importing and using the following plugins: @upit/storage.v1
User prompt
Add more level editor elements
User prompt
Add a update
User prompt
Add more level editor elements
User prompt
Add a map packs button and a level editor button
User prompt
Update get all shop items βͺπ‘ Consider importing and using the following plugins: @upit/storage.v1
User prompt
Add 4 more shops βͺπ‘ Consider importing and using the following plugins: @upit/storage.v1
User prompt
Add 4 more shops βͺπ‘ Consider importing and using the following plugins: @upit/storage.v1
User prompt
Add get all shop items βͺπ‘ Consider importing and using the following plugins: @upit/storage.v1
User prompt
Add add 6 more commands βͺπ‘ Consider importing and using the following plugins: @upit/storage.v1
User prompt
Add 3 more shops βͺπ‘ Consider importing and using the following plugins: @upit/storage.v1
User prompt
Add a add 10000 gems and coins to owner commands βͺπ‘ Consider importing and using the following plugins: @upit/storage.v1
User prompt
Please fix the bug: 'Script error.' in or related to this line: 'storage.dailyShopItems.push({' Line Number: 2408 βͺπ‘ Consider importing and using the following plugins: @upit/storage.v1
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var storage = LK.import("@upit/storage.v1"); /**** * Classes ****/ var Checkpoint = Container.expand(function (x, y) { var self = Container.call(this); var checkpointGraphics = self.attachAsset('checkpoint', { anchorX: 0.5, anchorY: 1.0 }); self.x = x; self.y = y; self.activated = false; return self; }); var Coin = Container.expand(function (x, y) { var self = Container.call(this); var coinGraphics = self.attachAsset('coin', { anchorX: 0.5, anchorY: 0.5 }); self.x = x; self.y = y; self.collected = false; self.rotationSpeed = 0.05; self.update = function () { if (!self.collected) { coinGraphics.rotation += self.rotationSpeed; } }; return self; }); var Ground = Container.expand(function (x, y, width) { var self = Container.call(this); var groundGraphics = self.attachAsset('ground', { anchorX: 0, anchorY: 0 }); groundGraphics.width = width || 200; self.x = x; self.y = y; return self; }); var LevelButton = Container.expand(function (levelNum, x, y) { var self = Container.call(this); var buttonGraphics = self.attachAsset('levelButton', { anchorX: 0.5, anchorY: 0.5 }); self.levelNum = levelNum; self.x = x; self.y = y; self.locked = levelNum > 1 && !storage.completedLevels[levelNum - 1]; // Set button color based on status if (self.locked) { buttonGraphics.tint = 0x666666; } else if (storage.completedLevels[levelNum]) { buttonGraphics.tint = 0x00ff00; } // Level number text self.levelText = new Text2(levelNum.toString(), { size: 40, fill: 0xFFFFFF }); self.levelText.anchor.set(0.5, 0.3); self.addChild(self.levelText); // Coin count text var coinCount = storage.levelCoins[levelNum] || 0; var maxCoins = levelData[levelNum] ? levelData[levelNum].coins.length : 0; self.coinText = new Text2(coinCount + '/' + maxCoins, { size: 25, fill: 0xFFD700 }); self.coinText.anchor.set(0.5, 0.7); self.addChild(self.coinText); self.down = function (x, y, obj) { if (!self.locked) { currentLevel = self.levelNum; showGameplay(); } }; return self; }); var Platform = Container.expand(function (x, y, width) { var self = Container.call(this); var platformGraphics = self.attachAsset('platform', { anchorX: 0, anchorY: 0 }); platformGraphics.width = width || 200; self.x = x; self.y = y; return self; }); var Player = Container.expand(function () { var self = Container.call(this); self.isShipMode = false; self.playerGraphics = null; self.shipGraphics = null; self.setMode = function (isShip) { if (self.playerGraphics) { self.removeChild(self.playerGraphics); self.playerGraphics = null; } if (self.shipGraphics) { self.removeChild(self.shipGraphics); self.shipGraphics = null; } self.isShipMode = isShip; if (isShip) { self.shipGraphics = self.attachAsset('ship', { anchorX: 0.5, anchorY: 0.5 }); // Apply purchased ship color if (storage.shipColor) { self.shipGraphics.tint = storage.shipColor; } // Apply size reduction if (storage.smallSize) { self.shipGraphics.scaleX = 0.75; self.shipGraphics.scaleY = 0.75; } } else { self.playerGraphics = self.attachAsset('player', { anchorX: 0.5, anchorY: 1.0 }); // Apply purchased player color if (storage.playerColor) { self.playerGraphics.tint = storage.playerColor; } // Apply size reduction if (storage.smallSize) { self.playerGraphics.scaleX = 0.75; self.playerGraphics.scaleY = 0.75; } } }; // Initialize with player mode self.setMode(false); self.velocityY = 0; self.isGrounded = false; self.isDead = false; self.isFlying = false; self.isSwinging = false; self.swingAnchor = null; self.swingAngle = 0; self.swingLength = 0; self.swingSpeed = 0; self.jump = function () { if (self.isShipMode) { if (!self.isDead) { self.isFlying = true; self.velocityY = -12; LK.getSound('jump').play(); } } else { if (self.isGrounded && !self.isDead) { var jumpPower = storage.jumpBoost ? -30 : -24; self.velocityY = jumpPower; self.isGrounded = false; LK.getSound('jump').play(); } } }; self.stopJump = function () { if (self.isShipMode) { self.isFlying = false; } else if (self.isSwinging) { // Release from swing var releaseVelX = Math.cos(self.swingAngle + Math.PI / 2) * self.swingSpeed * 0.8; var releaseVelY = Math.sin(self.swingAngle + Math.PI / 2) * self.swingSpeed * 0.8; self.velocityY = releaseVelY; self.releaseVelX = releaseVelX; self.isSwinging = false; if (self.swingAnchor) { self.swingAnchor.deactivateSwing(); self.swingAnchor = null; } } }; self.update = function () { if (self.isDead) return; // Trail effect if (storage.trail) { var trailParticle = LK.getAsset('coin', { anchorX: 0.5, anchorY: 0.5 }); trailParticle.x = self.x; trailParticle.y = self.y; trailParticle.scaleX = 0.3; trailParticle.scaleY = 0.3; trailParticle.alpha = 0.6; trailParticle.tint = storage.playerColor || 0x00ff00; game.addChild(trailParticle); // Fade out trail particle tween(trailParticle, { alpha: 0, scaleX: 0, scaleY: 0 }, { duration: 500, onComplete: function onComplete() { game.removeChild(trailParticle); } }); } if (self.isSwinging) { // Swing physics var gravity = 0.8; var dampening = 0.995; // Apply gravity to swing speed var gravityForce = gravity * Math.cos(self.swingAngle); self.swingSpeed += gravityForce; self.swingSpeed *= dampening; // Update swing angle self.swingAngle += self.swingSpeed / self.swingLength; // Update player position based on swing self.x = self.swingAnchor.x + Math.cos(self.swingAngle) * self.swingLength; self.y = self.swingAnchor.y + Math.sin(self.swingAngle) * self.swingLength; // Update rope visual if exists if (self.swingAnchor.rope) { self.swingAnchor.rope.rotation = self.swingAngle; } } else if (self.isShipMode) { // Ship mode physics if (self.isFlying) { self.velocityY -= 2.5; } else { self.velocityY += 2.0; } // Limit ship velocity if (self.velocityY > 18) self.velocityY = 18; if (self.velocityY < -18) self.velocityY = -18; self.y += self.velocityY; // Ship ground collision if (self.y >= groundLevel - 20) { self.y = groundLevel - 20; self.velocityY = 0; } // Ship ceiling collision if (self.y <= 100) { self.y = 100; self.velocityY = 0; } } else { // Regular cube mode physics if (self.releaseVelX) { // Apply horizontal velocity from swing release self.x += self.releaseVelX; self.releaseVelX *= 0.95; // Decay horizontal velocity if (Math.abs(self.releaseVelX) < 0.5) { self.releaseVelX = 0; } } self.velocityY += 2.0; self.y += self.velocityY; // Ground collision if (self.y >= groundLevel) { self.y = groundLevel; self.velocityY = 0; self.isGrounded = true; self.releaseVelX = 0; // Stop horizontal movement on ground } } }; return self; }); var Spike = Container.expand(function (x, y) { var self = Container.call(this); var spikeGraphics = self.attachAsset('spike', { anchorX: 0.5, anchorY: 1.0 }); self.x = x; self.y = y; return self; }); var SwingAnchor = Container.expand(function (x, y) { var self = Container.call(this); var anchorGraphics = self.attachAsset('swingAnchor', { anchorX: 0.5, anchorY: 0.5 }); self.x = x; self.y = y; self.isActive = false; self.rope = null; self.activateSwing = function (player) { if (!self.isActive && !player.isSwinging) { self.isActive = true; player.isSwinging = true; player.swingAnchor = self; player.swingAngle = Math.atan2(player.y - self.y, player.x - self.x); player.swingLength = Math.sqrt(Math.pow(player.x - self.x, 2) + Math.pow(player.y - self.y, 2)); player.swingSpeed = 0; // Create visual rope self.rope = LK.getAsset('ground', { anchorX: 0, anchorY: 0.5 }); self.rope.width = player.swingLength; self.rope.height = 4; self.rope.tint = 0x8B4513; self.rope.x = self.x; self.rope.y = self.y; self.rope.rotation = self.swingAngle; game.addChild(self.rope); // Animate anchor activation tween(anchorGraphics, { scaleX: 1.5, scaleY: 1.5 }, { duration: 200, easing: tween.bounceOut }); } }; self.deactivateSwing = function () { self.isActive = false; if (self.rope) { game.removeChild(self.rope); self.rope = null; } tween(anchorGraphics, { scaleX: 1, scaleY: 1 }, { duration: 150 }); }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x222222 }); /**** * Game Code ****/ // Game states var gameState = 'menu'; // 'menu' or 'playing' var currentLevel = 1; var maxLevels = 68; var groundLevel = 2400; var cameraX = 0; var scrollSpeed = 12; // Player variables var player; var playerStartX = 300; var playerStartY = groundLevel; // Level data var obstacles = []; var platforms = []; var grounds = []; var checkpoints = []; var swingAnchors = []; var coins = []; var currentCheckpoint = 0; var levelData = {}; // UI elements var levelButtons = []; var backButton; var levelCompleteText; var deathCount = 0; var godModeEnabled = false; var speedBoostEnabled = false; var debugInfoVisible = false; var debugText = null; // Storage initialization if (!storage.completedLevels) { storage.completedLevels = {}; } if (!storage.currentLevel) { storage.currentLevel = 1; } if (!storage.totalCoins) { storage.totalCoins = 0; } if (!storage.levelCoins) { storage.levelCoins = {}; } if (!storage.dailyLevelDate) { storage.dailyLevelDate = ''; } if (!storage.dailyLevelCompleted) { storage.dailyLevelCompleted = false; } if (!storage.dailyLevelCoins) { storage.dailyLevelCoins = 0; } // Shop storage initialization if (!storage.shopPurchases) { storage.shopPurchases = {}; } if (!storage.playerColor) { storage.playerColor = 0x00ff00; // Default green } if (!storage.shipColor) { storage.shipColor = 0x0088ff; // Default blue } if (!storage.speedMultiplier) { storage.speedMultiplier = 1.0; } if (!storage.coinMagnet) { storage.coinMagnet = false; } if (!storage.checkpoint) { storage.checkpoint = false; } if (!storage.jumpBoost) { storage.jumpBoost = false; } if (!storage.shield) { storage.shield = false; } if (!storage.smallSize) { storage.smallSize = false; } if (!storage.trail) { storage.trail = false; } if (!storage.shieldUsed) { storage.shieldUsed = false; } // Daily shop storage initialization if (!storage.dailyShopDate) { storage.dailyShopDate = ''; } if (!storage.dailyShopItems) { storage.dailyShopItems = []; } if (!storage.dailyShopPurchases) { storage.dailyShopPurchases = {}; } // Gem shop storage initialization if (!storage.totalGems) { storage.totalGems = 10; // Start with 10 gems } if (!storage.gemShopPurchases) { storage.gemShopPurchases = {}; } // Generate daily level based on current date function generateDailyLevel() { var today = new Date(); var dateString = today.getFullYear() + '-' + (today.getMonth() + 1) + '-' + today.getDate(); // Check if daily level needs to be regenerated if (storage.dailyLevelDate !== dateString) { storage.dailyLevelDate = dateString; storage.dailyLevelCompleted = false; storage.dailyLevelCoins = 0; } // Generate daily level using date as seed for consistency var dayOfYear = Math.floor((today - new Date(today.getFullYear(), 0, 0)) / (1000 * 60 * 60 * 24)); var seed = dayOfYear + today.getFullYear() * 365; levelData['daily'] = { spikes: [], platforms: [], checkpoints: [], swingAnchors: [], coins: [], length: 3000, shipMode: seed % 3 === 0 // Ship mode every 3rd type of pattern }; // Generate pattern based on seed var patternType = seed % 5; if (patternType === 0) { // Spike gauntlet for (var i = 0; i < 8; i++) { levelData['daily'].spikes.push({ x: 800 + i * 300, y: groundLevel }); if (i % 2 === 1) { levelData['daily'].spikes.push({ x: 840 + i * 300, y: groundLevel }); } } } else if (patternType === 1) { // Platform jumps with swings for (var i = 0; i < 6; i++) { levelData['daily'].platforms.push({ x: 700 + i * 400, y: groundLevel - 120, width: 120 }); levelData['daily'].spikes.push({ x: 820 + i * 400, y: groundLevel - 120 }); if (i < 5) { levelData['daily'].swingAnchors.push({ x: 1000 + i * 400, y: groundLevel - 250 }); } } } else if (patternType === 2) { // Mixed chaos for (var i = 0; i < 10; i++) { if (i % 3 === 0) { levelData['daily'].platforms.push({ x: 700 + i * 250, y: groundLevel - 100, width: 100 }); } else { levelData['daily'].spikes.push({ x: 700 + i * 250, y: groundLevel }); } } } else if (patternType === 3) { // Staircase challenge for (var i = 0; i < 7; i++) { levelData['daily'].platforms.push({ x: 700 + i * 300, y: groundLevel - i * 50, width: 150 }); levelData['daily'].spikes.push({ x: 850 + i * 300, y: groundLevel - i * 50 }); } } else { // Speed run for (var i = 0; i < 12; i++) { levelData['daily'].spikes.push({ x: 700 + i * 200, y: groundLevel }); if (i % 4 === 3) { levelData['daily'].spikes.push({ x: 720 + i * 200, y: groundLevel }); } } } // Add daily coins (always 5 coins for daily level) for (var i = 0; i < 5; i++) { levelData['daily'].coins.push({ x: 600 + (i + 1) * (levelData['daily'].length / 6), y: groundLevel - 100 - i % 3 * 40 }); } // Add checkpoints levelData['daily'].checkpoints.push({ x: 1500, y: groundLevel }); levelData['daily'].checkpoints.push({ x: 2250, y: groundLevel }); } // Initialize level data with unique patterns for each level function initializeLevelData() { for (var i = 1; i <= 68; i++) { levelData[i] = { spikes: [], platforms: [], checkpoints: [], swingAnchors: [], coins: [], length: 2500 + i * 150, shipMode: false }; // Define unique patterns for each level if (i === 1) { // Level 1: Ship mode tutorial - simple gaps levelData[i].shipMode = true; levelData[i].length = 2000; for (var s = 0; s < 3; s++) { levelData[i].spikes.push({ x: 1000 + s * 600, y: groundLevel }); levelData[i].spikes.push({ x: 1000 + s * 600, y: groundLevel - 300 }); // Add coins between spikes if (s < 2) { levelData[i].coins.push({ x: 1300 + s * 600, y: groundLevel - 150 }); } } } else if (i === 2) { // Level 2: Single spike jumps for (var s = 0; s < 4; s++) { levelData[i].spikes.push({ x: 800 + s * 400, y: groundLevel }); // Add coin above each spike levelData[i].coins.push({ x: 800 + s * 400, y: groundLevel - 100 }); } } else if (i === 3) { // Level 3: Double spike jumps for (var s = 0; s < 3; s++) { levelData[i].spikes.push({ x: 800 + s * 500, y: groundLevel }); levelData[i].spikes.push({ x: 840 + s * 500, y: groundLevel }); } } else if (i === 4) { // Level 4: Platform jumps with swing anchors for (var p = 0; p < 4; p++) { levelData[i].platforms.push({ x: 800 + p * 400, y: groundLevel - 120, width: 150 }); levelData[i].spikes.push({ x: 975 + p * 400, y: groundLevel - 120 }); // Add swing anchor between platforms if (p < 3) { levelData[i].swingAnchors.push({ x: 1075 + p * 400, y: groundLevel - 200 }); } } } else if (i === 5) { // Level 5: Spike clusters for (var c = 0; c < 3; c++) { for (var s = 0; s < 3; s++) { levelData[i].spikes.push({ x: 800 + c * 600 + s * 50, y: groundLevel }); } // Add coin above each cluster levelData[i].coins.push({ x: 850 + c * 600, y: groundLevel - 120 }); } } else if (i >= 6 && i <= 10) { // Levels 6-10: Mixed patterns with increasing difficulty var patternType = (i - 6) % 3; if (patternType === 0) { // Alternating single and double spikes for (var s = 0; s < 5; s++) { levelData[i].spikes.push({ x: 700 + s * 350, y: groundLevel }); if (s % 2 === 1) { levelData[i].spikes.push({ x: 740 + s * 350, y: groundLevel }); } // Add coins between spikes if (s < 4) { levelData[i].coins.push({ x: 875 + s * 350, y: groundLevel - 80 }); } } } else if (patternType === 1) { // Platform hopping for (var p = 0; p < 4; p++) { var height = groundLevel - 100 - p % 2 * 80; levelData[i].platforms.push({ x: 800 + p * 350, y: height, width: 120 }); levelData[i].spikes.push({ x: 920 + p * 350, y: height }); } } else { // Triple spike jumps for (var t = 0; t < 3; t++) { for (var s = 0; s < 3; s++) { levelData[i].spikes.push({ x: 800 + t * 500 + s * 45, y: groundLevel }); } } } } else if (i >= 11 && i <= 20) { // Levels 11-20: Advanced patterns var complexity = i - 10; if (i % 4 === 1) { // Staircase platforms with spikes for (var st = 0; st < 5; st++) { var stairY = groundLevel - st * 60; levelData[i].platforms.push({ x: 700 + st * 300, y: stairY, width: 150 }); levelData[i].spikes.push({ x: 850 + st * 300, y: stairY }); } } else if (i % 4 === 2) { // Ship mode level levelData[i].shipMode = true; for (var s = 0; s < 6; s++) { levelData[i].spikes.push({ x: 800 + s * 300, y: groundLevel }); levelData[i].spikes.push({ x: 800 + s * 300, y: groundLevel - 250 }); } } else if (i % 4 === 3) { // Maze-like platforms with swing challenges for (var m = 0; m < 4; m++) { var upper = m % 2 === 0; var platY = upper ? groundLevel - 200 : groundLevel - 100; levelData[i].platforms.push({ x: 700 + m * 400, y: platY, width: 200 }); levelData[i].spikes.push({ x: 800 + m * 400, y: platY }); // Add swing anchors for advanced navigation if (m < 3) { levelData[i].swingAnchors.push({ x: 900 + m * 400, y: groundLevel - 300 }); } } } else { // Rapid fire spikes for (var r = 0; r < 8; r++) { levelData[i].spikes.push({ x: 700 + r * 200, y: groundLevel }); } } } else if (i >= 21 && i <= 35) { // Levels 21-35: Expert patterns if (i % 5 === 1) { // Multi-level platforms for (var ml = 0; ml < 3; ml++) { for (var level = 0; level < 3; level++) { var platY = groundLevel - 80 - level * 70; levelData[i].platforms.push({ x: 700 + ml * 500 + level * 100, y: platY, width: 100 }); if (level < 2) { levelData[i].spikes.push({ x: 750 + ml * 500 + level * 100, y: platY }); } } // Add challenging coin placement levelData[i].coins.push({ x: 850 + ml * 500, y: groundLevel - 250 }); } } else if (i % 5 === 2) { // Ship maze levelData[i].shipMode = true; for (var sm = 0; sm < 5; sm++) { levelData[i].spikes.push({ x: 800 + sm * 250, y: groundLevel }); levelData[i].spikes.push({ x: 825 + sm * 250, y: groundLevel - 150 }); levelData[i].spikes.push({ x: 850 + sm * 250, y: groundLevel - 300 }); } } else if (i % 5 === 3) { // Wave pattern spikes for (var w = 0; w < 8; w++) { var wave = Math.sin(w * 0.8) * 100; levelData[i].spikes.push({ x: 700 + w * 150, y: groundLevel + wave }); } } else if (i % 5 === 4) { // Tight platform sequences for (var tp = 0; tp < 6; tp++) { levelData[i].platforms.push({ x: 700 + tp * 250, y: groundLevel - 120, width: 80 }); levelData[i].spikes.push({ x: 780 + tp * 250, y: groundLevel - 120 }); levelData[i].spikes.push({ x: 950 + tp * 250, y: groundLevel }); } } else { // Spike walls for (var sw = 0; sw < 4; sw++) { for (var wall = 0; wall < 4; wall++) { levelData[i].spikes.push({ x: 800 + sw * 400, y: groundLevel - wall * 50 }); } } } } else { // Levels 36-50: Master difficulty var masterPattern = (i - 35) % 8; if (masterPattern === 0) { // Ultimate ship challenge levelData[i].shipMode = true; for (var uc = 0; uc < 10; uc++) { levelData[i].spikes.push({ x: 600 + uc * 180, y: groundLevel }); levelData[i].spikes.push({ x: 620 + uc * 180, y: groundLevel - 100 }); levelData[i].spikes.push({ x: 640 + uc * 180, y: groundLevel - 200 }); levelData[i].spikes.push({ x: 660 + uc * 180, y: groundLevel - 300 }); // Add very challenging coins if (uc % 3 === 0) { levelData[i].coins.push({ x: 630 + uc * 180, y: groundLevel - 150 }); } } } else if (masterPattern === 1) { // Precision platform jumps for (var pp = 0; pp < 8; pp++) { levelData[i].platforms.push({ x: 700 + pp * 200, y: groundLevel - 60 - pp % 3 * 40, width: 60 }); levelData[i].spikes.push({ x: 730 + pp * 200, y: groundLevel - 60 - pp % 3 * 40 }); } } else if (masterPattern === 2) { // Chaos mode - random but beatable for (var ch = 0; ch < 12; ch++) { if (ch % 3 === 0) { levelData[i].platforms.push({ x: 600 + ch * 150, y: groundLevel - 100, width: 100 }); } else { levelData[i].spikes.push({ x: 600 + ch * 150, y: groundLevel }); } } } else if (masterPattern === 3) { // Double layer platforms for (var dl = 0; dl < 5; dl++) { levelData[i].platforms.push({ x: 700 + dl * 300, y: groundLevel - 100, width: 120 }); levelData[i].platforms.push({ x: 760 + dl * 300, y: groundLevel - 180, width: 120 }); levelData[i].spikes.push({ x: 820 + dl * 300, y: groundLevel - 100 }); levelData[i].spikes.push({ x: 880 + dl * 300, y: groundLevel - 180 }); } } else if (masterPattern === 4) { // Speed run spikes for (var sr = 0; sr < 15; sr++) { levelData[i].spikes.push({ x: 600 + sr * 120, y: groundLevel }); if (sr % 3 === 2) { levelData[i].spikes.push({ x: 620 + sr * 120, y: groundLevel }); } } } else if (masterPattern === 5) { // Alternating ship/cube sections if (i % 2 === 0) { levelData[i].shipMode = true; } for (var as = 0; as < 8; as++) { levelData[i].spikes.push({ x: 700 + as * 200, y: groundLevel }); if (levelData[i].shipMode) { levelData[i].spikes.push({ x: 720 + as * 200, y: groundLevel - 200 }); } } } else if (masterPattern === 6) { // Extreme precision for (var ep = 0; ep < 6; ep++) { levelData[i].platforms.push({ x: 700 + ep * 250, y: groundLevel - 90, width: 50 }); levelData[i].spikes.push({ x: 725 + ep * 250, y: groundLevel - 90 }); levelData[i].spikes.push({ x: 750 + ep * 250, y: groundLevel - 90 }); levelData[i].spikes.push({ x: 950 + ep * 250, y: groundLevel }); } } else { // Final boss level patterns for (var fb = 0; fb < 5; fb++) { // Complex multi-height obstacles for (var h = 0; h < 4; h++) { if ((fb + h) % 2 === 0) { levelData[i].spikes.push({ x: 700 + fb * 300 + h * 40, y: groundLevel - h * 60 }); } else { levelData[i].platforms.push({ x: 700 + fb * 300 + h * 40, y: groundLevel - h * 60, width: 80 }); } } } } } // Special level 51 pattern with starting swing if (i === 51) { // Start with a swing anchor at the beginning levelData[i].swingAnchors.push({ x: 500, y: groundLevel - 150 }); // Add platform to swing to levelData[i].platforms.push({ x: 700, y: groundLevel - 100, width: 120 }); // Add spikes after platform for (var s51 = 0; s51 < 5; s51++) { levelData[i].spikes.push({ x: 900 + s51 * 200, y: groundLevel }); } // Add more swing anchors throughout level levelData[i].swingAnchors.push({ x: 1200, y: groundLevel - 200 }); levelData[i].swingAnchors.push({ x: 1600, y: groundLevel - 180 }); // Add challenging platform sequence for (var p51 = 0; p51 < 4; p51++) { levelData[i].platforms.push({ x: 1800 + p51 * 300, y: groundLevel - 120 - p51 % 2 * 60, width: 100 }); levelData[i].spikes.push({ x: 1850 + p51 * 300, y: groundLevel - 120 - p51 % 2 * 60 }); } } // Levels 52-68: Next page ultra-hard levels if (i >= 52 && i <= 68) { var ultraPattern = (i - 52) % 17; if (ultraPattern === 0) { // Level 52: Moving spike walls for (var msw = 0; msw < 6; msw++) { for (var wall = 0; wall < 5; wall++) { levelData[i].spikes.push({ x: 800 + msw * 350, y: groundLevel - wall * 45 }); } // Add narrow safe passage levelData[i].platforms.push({ x: 950 + msw * 350, y: groundLevel - 150, width: 60 }); } } else if (ultraPattern === 1) { // Level 53: Ship tunnel nightmare levelData[i].shipMode = true; for (var stn = 0; stn < 12; stn++) { levelData[i].spikes.push({ x: 700 + stn * 150, y: groundLevel }); levelData[i].spikes.push({ x: 725 + stn * 150, y: groundLevel - 80 }); levelData[i].spikes.push({ x: 750 + stn * 150, y: groundLevel - 160 }); levelData[i].spikes.push({ x: 775 + stn * 150, y: groundLevel - 240 }); } } else if (ultraPattern === 2) { // Level 54: Triple layer platform maze for (var tlm = 0; tlm < 5; tlm++) { // Bottom layer levelData[i].platforms.push({ x: 700 + tlm * 400, y: groundLevel - 80, width: 80 }); levelData[i].spikes.push({ x: 780 + tlm * 400, y: groundLevel - 80 }); // Middle layer levelData[i].platforms.push({ x: 850 + tlm * 400, y: groundLevel - 160, width: 80 }); levelData[i].spikes.push({ x: 930 + tlm * 400, y: groundLevel - 160 }); // Top layer levelData[i].platforms.push({ x: 1000 + tlm * 400, y: groundLevel - 240, width: 80 }); levelData[i].spikes.push({ x: 1080 + tlm * 400, y: groundLevel - 240 }); } } else if (ultraPattern === 3) { // Level 55: Swing chain challenge for (var scc = 0; scc < 8; scc++) { levelData[i].swingAnchors.push({ x: 600 + scc * 250, y: groundLevel - 200 - scc % 3 * 50 }); // Add spikes below each swing point levelData[i].spikes.push({ x: 575 + scc * 250, y: groundLevel }); levelData[i].spikes.push({ x: 625 + scc * 250, y: groundLevel }); } } else if (ultraPattern === 4) { // Level 56: Rapid fire precision for (var rfp = 0; rfp < 20; rfp++) { levelData[i].spikes.push({ x: 600 + rfp * 80, y: groundLevel }); if (rfp % 4 === 3) { levelData[i].spikes.push({ x: 620 + rfp * 80, y: groundLevel }); levelData[i].spikes.push({ x: 640 + rfp * 80, y: groundLevel }); } } } else if (ultraPattern === 5) { // Level 57: Alternating cube/ship sections for (var acs = 0; acs < 8; acs++) { if (acs < 4) { // Cube section levelData[i].spikes.push({ x: 700 + acs * 200, y: groundLevel }); levelData[i].platforms.push({ x: 800 + acs * 200, y: groundLevel - 100, width: 100 }); } else { // Ship section indicators (spikes arranged for ship mode) levelData[i].spikes.push({ x: 700 + acs * 200, y: groundLevel }); levelData[i].spikes.push({ x: 720 + acs * 200, y: groundLevel - 150 }); } } if (i % 2 === 1) { levelData[i].shipMode = true; } } else if (ultraPattern === 6) { // Level 58: Micro platforms for (var mp = 0; mp < 10; mp++) { levelData[i].platforms.push({ x: 700 + mp * 180, y: groundLevel - 100 - mp % 4 * 30, width: 40 }); levelData[i].spikes.push({ x: 740 + mp * 180, y: groundLevel - 100 - mp % 4 * 30 }); levelData[i].spikes.push({ x: 880 + mp * 180, y: groundLevel }); } } else if (ultraPattern === 7) { // Level 59: Ceiling and floor spikes levelData[i].shipMode = true; for (var cfs = 0; cfs < 10; cfs++) { levelData[i].spikes.push({ x: 700 + cfs * 150, y: groundLevel }); levelData[i].spikes.push({ x: 725 + cfs * 150, y: groundLevel - 300 }); // Create narrow safe corridor if (cfs % 3 === 1) { levelData[i].coins.push({ x: 712 + cfs * 150, y: groundLevel - 150 }); } } } else if (ultraPattern === 8) { // Level 60: Swing through spike field for (var stsf = 0; stsf < 6; stsf++) { levelData[i].swingAnchors.push({ x: 700 + stsf * 300, y: groundLevel - 250 }); // Dense spike field below for (var sf = 0; sf < 5; sf++) { levelData[i].spikes.push({ x: 600 + stsf * 300 + sf * 50, y: groundLevel }); levelData[i].spikes.push({ x: 625 + stsf * 300 + sf * 50, y: groundLevel - 60 }); } } } else if (ultraPattern === 9) { // Level 61: Stairway to hell for (var sth = 0; sth < 8; sth++) { var stairHeight = groundLevel - sth * 40; levelData[i].platforms.push({ x: 700 + sth * 150, y: stairHeight, width: 70 }); levelData[i].spikes.push({ x: 770 + sth * 150, y: stairHeight }); levelData[i].spikes.push({ x: 850 + sth * 150, y: groundLevel }); } } else if (ultraPattern === 10) { // Level 62: Ship slalom levelData[i].shipMode = true; for (var ss = 0; ss < 15; ss++) { var slalomY = groundLevel - 150 + Math.sin(ss * 0.8) * 100; levelData[i].spikes.push({ x: 700 + ss * 120, y: slalomY }); levelData[i].spikes.push({ x: 720 + ss * 120, y: slalomY + 50 }); } } else if (ultraPattern === 11) { // Level 63: Platform chains for (var pc = 0; pc < 6; pc++) { for (var chain = 0; chain < 4; chain++) { levelData[i].platforms.push({ x: 700 + pc * 350 + chain * 70, y: groundLevel - 80 - chain * 60, width: 50 }); if (chain < 3) { levelData[i].spikes.push({ x: 725 + pc * 350 + chain * 70, y: groundLevel - 80 - chain * 60 }); } } } } else if (ultraPattern === 12) { // Level 64: Double swing challenge for (var dsc = 0; dsc < 5; dsc++) { levelData[i].swingAnchors.push({ x: 700 + dsc * 400, y: groundLevel - 200 }); levelData[i].swingAnchors.push({ x: 900 + dsc * 400, y: groundLevel - 180 }); // Spike barriers for (var sb = 0; sb < 6; sb++) { levelData[i].spikes.push({ x: 650 + dsc * 400 + sb * 40, y: groundLevel }); } } } else if (ultraPattern === 13) { // Level 65: Speed demon for (var sd = 0; sd < 25; sd++) { levelData[i].spikes.push({ x: 600 + sd * 60, y: groundLevel }); if (sd % 5 === 2) { levelData[i].spikes.push({ x: 615 + sd * 60, y: groundLevel }); levelData[i].spikes.push({ x: 630 + sd * 60, y: groundLevel }); } } } else if (ultraPattern === 14) { // Level 66: Ship maze finale levelData[i].shipMode = true; for (var smf = 0; smf < 8; smf++) { levelData[i].spikes.push({ x: 700 + smf * 200, y: groundLevel }); levelData[i].spikes.push({ x: 720 + smf * 200, y: groundLevel - 80 }); levelData[i].spikes.push({ x: 740 + smf * 200, y: groundLevel - 160 }); levelData[i].spikes.push({ x: 760 + smf * 200, y: groundLevel - 240 }); levelData[i].spikes.push({ x: 780 + smf * 200, y: groundLevel - 320 }); } } else if (ultraPattern === 15) { // Level 67: Ultimate precision test for (var upt = 0; upt < 12; upt++) { levelData[i].platforms.push({ x: 700 + upt * 150, y: groundLevel - 80 - upt % 3 * 80, width: 30 }); levelData[i].spikes.push({ x: 730 + upt * 150, y: groundLevel - 80 - upt % 3 * 80 }); levelData[i].spikes.push({ x: 850 + upt * 150, y: groundLevel }); } } else { // Level 68: Final boss gauntlet for (var fbg = 0; fbg < 6; fbg++) { // Multi-height spike walls for (var wall = 0; wall < 6; wall++) { levelData[i].spikes.push({ x: 700 + fbg * 400, y: groundLevel - wall * 50 }); } // Narrow platform escape levelData[i].platforms.push({ x: 750 + fbg * 400, y: groundLevel - 200, width: 40 }); // Swing anchor for advanced navigation levelData[i].swingAnchors.push({ x: 850 + fbg * 400, y: groundLevel - 300 }); // More spikes after swing for (var afterSpike = 0; afterSpike < 4; afterSpike++) { levelData[i].spikes.push({ x: 900 + fbg * 400 + afterSpike * 30, y: groundLevel }); } } } } // Add default coins if none were added yet if (levelData[i].coins.length === 0) { var coinCount = Math.max(2, Math.floor(i / 5) + 1); for (var c = 0; c < coinCount; c++) { levelData[i].coins.push({ x: 600 + c * (levelData[i].length / (coinCount + 1)), y: groundLevel - 80 - c % 3 * 40 }); } } // Add checkpoints based on level length var checkpointCount = Math.max(1, Math.floor(levelData[i].length / 800)); for (var k = 1; k <= checkpointCount; k++) { levelData[i].checkpoints.push({ x: k * (levelData[i].length / (checkpointCount + 1)), y: groundLevel }); } } } // UI Setup function setupUI() { // Score display var scoreText = new Text2('Level: ' + currentLevel, { size: 60, fill: 0xFFFFFF }); scoreText.anchor.set(0, 0); scoreText.x = 120; scoreText.y = 50; LK.gui.topLeft.addChild(scoreText); // Coin counter var coinText = new Text2('Coins: ' + storage.totalCoins, { size: 50, fill: 0xFFD700 }); coinText.anchor.set(0, 0); coinText.x = 120; coinText.y = 120; LK.gui.topLeft.addChild(coinText); // Gem counter var gemText = new Text2('Gems: ' + storage.totalGems, { size: 50, fill: 0xFF00FF }); gemText.anchor.set(0, 0); gemText.x = 120; gemText.y = 190; LK.gui.topLeft.addChild(gemText); } // Level selection menu function showLevelMenu() { gameState = 'menu'; game.removeChildren(); levelButtons = []; // Title var titleText = new Text2('Geometry Dash: 50 Levels', { size: 80, fill: 0xFFFFFF }); titleText.anchor.set(0.5, 0); titleText.x = 1024; titleText.y = 200; game.addChild(titleText); // Create level buttons in grid var buttonsPerRow = 5; var buttonSpacing = 220; var startX = 1024 - (buttonsPerRow - 1) * buttonSpacing / 2; var startY = 480; for (var i = 1; i <= maxLevels; i++) { var row = Math.floor((i - 1) / buttonsPerRow); var col = (i - 1) % buttonsPerRow; var buttonX = startX + col * buttonSpacing; var buttonY = startY + row * 150; var levelBtn = game.addChild(new LevelButton(i, buttonX, buttonY)); levelButtons.push(levelBtn); } // Daily level button var dailyButton = LK.getAsset('levelButton', { anchorX: 0.5, anchorY: 0.5 }); dailyButton.x = 1024; dailyButton.y = startY + Math.ceil(maxLevels / buttonsPerRow) * 150 + 250; dailyButton.tint = storage.dailyLevelCompleted ? 0x00ff00 : 0xff6600; dailyButton.scaleX = 1.2; dailyButton.scaleY = 1.2; game.addChild(dailyButton); var dailyText = new Text2('DAILY', { size: 35, fill: 0xFFFFFF }); dailyText.anchor.set(0.5, 0.3); dailyText.x = dailyButton.x; dailyText.y = dailyButton.y; game.addChild(dailyText); var dailyCoinText = new Text2(storage.dailyLevelCoins + '/5', { size: 25, fill: 0xFFD700 }); dailyCoinText.anchor.set(0.5, 0.7); dailyCoinText.x = dailyButton.x; dailyCoinText.y = dailyButton.y; game.addChild(dailyCoinText); dailyButton.down = function (x, y, obj) { currentLevel = 'daily'; showGameplay(); }; // Video button var videoButton = LK.getAsset('levelButton', { anchorX: 0.5, anchorY: 0.5 }); videoButton.x = 1024; videoButton.y = startY + Math.ceil(maxLevels / buttonsPerRow) * 150 + 400; videoButton.tint = 0x9933ff; game.addChild(videoButton); var videoText = new Text2('Video', { size: 40, fill: 0xFFFFFF }); videoText.anchor.set(0.5, 0.5); videoText.x = videoButton.x; videoText.y = videoButton.y; game.addChild(videoText); videoButton.down = function (x, y, obj) { showVideoTutorial(); }; // Shop button var shopButton = LK.getAsset('levelButton', { anchorX: 0.5, anchorY: 0.5 }); shopButton.x = 924; shopButton.y = 300; shopButton.tint = 0x00aaff; game.addChild(shopButton); var shopText = new Text2('Shop', { size: 40, fill: 0xFFFFFF }); shopText.anchor.set(0.5, 0.5); shopText.x = shopButton.x; shopText.y = shopButton.y; game.addChild(shopText); shopButton.down = function (x, y, obj) { showShop(); }; // Daily Shop button var dailyShopButton = LK.getAsset('levelButton', { anchorX: 0.5, anchorY: 0.5 }); dailyShopButton.x = 1124; dailyShopButton.y = 300; dailyShopButton.tint = 0xff6600; game.addChild(dailyShopButton); var dailyShopText = new Text2('Daily Shop', { size: 32, fill: 0xFFFFFF }); dailyShopText.anchor.set(0.5, 0.5); dailyShopText.x = dailyShopButton.x; dailyShopText.y = dailyShopButton.y; game.addChild(dailyShopText); dailyShopButton.down = function (x, y, obj) { showDailyShop(); }; // Gem Shop button var gemShopButton = LK.getAsset('levelButton', { anchorX: 0.5, anchorY: 0.5 }); gemShopButton.x = 724; gemShopButton.y = 300; gemShopButton.tint = 0xff00ff; game.addChild(gemShopButton); var gemShopText = new Text2('Gem Shop', { size: 32, fill: 0xFFFFFF }); gemShopText.anchor.set(0.5, 0.5); gemShopText.x = gemShopButton.x; gemShopText.y = gemShopButton.y; game.addChild(gemShopText); gemShopButton.down = function (x, y, obj) { showGemShop(); }; // Owner commands button (moved down) var ownerButton = LK.getAsset('levelButton', { anchorX: 0.5, anchorY: 0.5 }); ownerButton.x = 1024; ownerButton.y = 450; ownerButton.tint = 0xffaa00; game.addChild(ownerButton); var ownerText = new Text2('Owner', { size: 40, fill: 0xFFFFFF }); ownerText.anchor.set(0.5, 0.5); ownerText.x = ownerButton.x; ownerText.y = ownerButton.y; game.addChild(ownerText); ownerButton.down = function (x, y, obj) { showOwnerCommands(); }; } // Show gameplay function showGameplay() { gameState = 'playing'; game.removeChildren(); // Reset camera cameraX = 0; currentCheckpoint = 0; deathCount = 0; // Reset shield for new level storage.shieldUsed = false; // Create player player = game.addChild(new Player()); player.x = playerStartX; player.y = playerStartY; // Set ship mode based on level data if (levelData[currentLevel] && levelData[currentLevel].shipMode) { player.setMode(true); player.y = groundLevel - 200; // Start ship higher up } else { player.setMode(false); } // Load current level loadLevel(currentLevel); } // Load level obstacles function loadLevel(levelNum) { obstacles = []; platforms = []; grounds = []; checkpoints = []; swingAnchors = []; coins = []; var level = levelData[levelNum]; if (!level) { // If level data doesn't exist, create a basic level level = { spikes: [], platforms: [], checkpoints: [], swingAnchors: [], coins: [], length: 3000, shipMode: false }; } // Create ground segments for (var x = 0; x <= level.length + 1000; x += 200) { var ground = game.addChild(new Ground(x, groundLevel, 200)); grounds.push(ground); } // Create spikes for (var i = 0; i < level.spikes.length; i++) { var spikeData = level.spikes[i]; var spike = game.addChild(new Spike(spikeData.x, spikeData.y)); obstacles.push(spike); } // Create platforms for (var j = 0; j < level.platforms.length; j++) { var platformData = level.platforms[j]; var platform = game.addChild(new Platform(platformData.x, platformData.y, platformData.width)); platforms.push(platform); } // Create checkpoints for (var k = 0; k < level.checkpoints.length; k++) { var checkpointData = level.checkpoints[k]; var checkpoint = game.addChild(new Checkpoint(checkpointData.x, checkpointData.y)); checkpoints.push(checkpoint); } // Create swing anchors for (var s = 0; s < level.swingAnchors.length; s++) { var anchorData = level.swingAnchors[s]; var swingAnchor = game.addChild(new SwingAnchor(anchorData.x, anchorData.y)); swingAnchors.push(swingAnchor); } // Create coins for (var c = 0; c < level.coins.length; c++) { var coinData = level.coins[c]; var coin = game.addChild(new Coin(coinData.x, coinData.y)); coins.push(coin); } } // Handle player death function handlePlayerDeath() { if (player.isDead || godModeEnabled) return; // Check shield protection if (storage.shield && !storage.shieldUsed) { storage.shieldUsed = true; LK.effects.flashScreen(0x00ffff, 300); LK.effects.flashObject(player, 0x00ffff, 1000); return; // Shield absorbs hit } player.isDead = true; deathCount++; LK.effects.flashScreen(0xff0000, 500); LK.getSound('death').play(); // Respawn after delay LK.setTimeout(function () { respawnPlayer(); }, 1000); } // Respawn player at checkpoint function respawnPlayer() { player.isDead = false; player.velocityY = 0; player.isGrounded = false; if (currentCheckpoint > 0 && checkpoints[currentCheckpoint - 1]) { player.x = checkpoints[currentCheckpoint - 1].x; cameraX = checkpoints[currentCheckpoint - 1].x - 400; } else { player.x = playerStartX; cameraX = 0; } player.y = groundLevel; } // Handle level completion function completeLevel() { if (currentLevel === 'daily') { storage.dailyLevelCompleted = true; // Give 2 gems for daily level completion storage.totalGems += 2; } else { storage.completedLevels[currentLevel] = true; // Give 1 gem for regular level completion storage.totalGems += 1; } LK.getSound('complete').play(); LK.effects.flashScreen(0x00ff00, 1000); // Show completion message var completeText = new Text2('Level Complete!', { size: 100, fill: 0x00FF00 }); completeText.anchor.set(0.5, 0.5); completeText.x = 1024; completeText.y = 1366; game.addChild(completeText); // Return to menu after delay LK.setTimeout(function () { showLevelMenu(); }, 2000); } // Input handling game.down = function (x, y, obj) { if (gameState === 'playing' && player && !player.isDead) { player.jump(); } }; game.up = function (x, y, obj) { if (gameState === 'playing' && player && !player.isDead) { player.stopJump(); } }; // Main game loop game.update = function () { if (gameState !== 'playing' || !player || player.isDead) return; // Auto-scroll camera with speed multiplier var currentScrollSpeed = scrollSpeed * (storage.speedMultiplier || 1.0); cameraX += currentScrollSpeed; player.x += currentScrollSpeed; // Update camera position var targetCameraX = player.x - 400; if (targetCameraX > cameraX) { cameraX = targetCameraX; } // Position all game objects relative to camera game.x = -cameraX; // Check obstacle collisions for (var i = 0; i < obstacles.length; i++) { var obstacle = obstacles[i]; if (player.intersects(obstacle)) { handlePlayerDeath(); break; } } // Check platform collisions (simple top collision) for (var j = 0; j < platforms.length; j++) { var platform = platforms[j]; if (player.intersects(platform) && player.velocityY > 0) { var playerBottom = player.y; var platformTop = platform.y; if (playerBottom >= platformTop && playerBottom <= platformTop + 20) { player.y = platformTop; player.velocityY = 0; player.isGrounded = true; } } } // Check checkpoint activation for (var k = 0; k < checkpoints.length; k++) { var checkpoint = checkpoints[k]; if (!checkpoint.activated && player.intersects(checkpoint)) { checkpoint.activated = true; currentCheckpoint = k + 1; LK.effects.flashObject(checkpoint, 0x00ffff, 500); } } // Check swing anchor activation for (var s = 0; s < swingAnchors.length; s++) { var anchor = swingAnchors[s]; if (!anchor.isActive && !player.isSwinging && player.intersects(anchor)) { var distance = Math.sqrt(Math.pow(player.x - anchor.x, 2) + Math.pow(player.y - anchor.y, 2)); if (distance < 80) { // Activation range anchor.activateSwing(player); break; } } } // Check coin collection for (var c = 0; c < coins.length; c++) { var coin = coins[c]; // Coin magnet effect if (!coin.collected && storage.coinMagnet) { var coinDistance = Math.sqrt(Math.pow(player.x - coin.x, 2) + Math.pow(player.y - coin.y, 2)); if (coinDistance < 150) { // Magnet range // Move coin towards player var magnetForce = 8; var dirX = (player.x - coin.x) / coinDistance; var dirY = (player.y - coin.y) / coinDistance; coin.x += dirX * magnetForce; coin.y += dirY * magnetForce; } } if (!coin.collected && player.intersects(coin)) { coin.collected = true; coin.visible = false; storage.totalCoins++; // Update level-specific coin tracking if (currentLevel === 'daily') { storage.dailyLevelCoins++; } else { if (!storage.levelCoins[currentLevel]) { storage.levelCoins[currentLevel] = 0; } storage.levelCoins[currentLevel]++; } // Play coin sound and visual effect LK.getSound('coin').play(); LK.effects.flashObject(coin, 0xFFD700, 300); // Update coin counter var coinTexts = LK.gui.topLeft.children; for (var t = 0; t < coinTexts.length; t++) { if (coinTexts[t].text && coinTexts[t].text.indexOf('Coins:') === 0) { coinTexts[t].setText('Coins: ' + storage.totalCoins); break; } } } } // Check level completion var levelLength = levelData[currentLevel] ? levelData[currentLevel].length : 3000; if (player.x >= levelLength) { completeLevel(); } // Check if player fell off screen if (player.y > 2800) { handlePlayerDeath(); } // Update debug info if (debugInfoVisible && debugText) { var debugInfo = 'X: ' + Math.floor(player.x) + '\nY: ' + Math.floor(player.y) + '\nVelocity Y: ' + Math.floor(player.velocityY) + '\nCheckpoint: ' + currentCheckpoint + '\nDeaths: ' + deathCount + '\nGod Mode: ' + (godModeEnabled ? 'ON' : 'OFF') + '\nSpeed Boost: ' + (speedBoostEnabled ? 'ON' : 'OFF'); debugText.setText(debugInfo); } }; // Video tutorial screen function showVideoTutorial() { gameState = 'video'; game.removeChildren(); // Title var titleText = new Text2('How to Beat Geometry Dash', { size: 70, fill: 0xFFFFFF }); titleText.anchor.set(0.5, 0); titleText.x = 1024; titleText.y = 150; game.addChild(titleText); // Instructions sections var instructions = ['BASIC CONTROLS:', 'β’ Tap/Click to jump in cube mode', 'β’ Hold to fly up in ship mode', 'β’ Release to fall down in ship mode', '', 'GAMEPLAY TIPS:', 'β’ Red spikes = deadly obstacles', 'β’ Gray platforms = safe to land on', 'β’ Cyan checkpoints = save your progress', 'β’ Green squares = completed levels', '', 'LEVEL PROGRESSION:', 'β’ Levels 1-10: Learn basic mechanics', 'β’ Levels 11-20: Master timing and ship mode', 'β’ Levels 21-35: Expert precision required', 'β’ Levels 36-50: Ultimate challenges', '', 'SURVIVAL STRATEGY:', 'β’ Practice timing on easier levels first', 'β’ Use checkpoints to avoid restarting', 'β’ Ship levels require smooth control', 'β’ Platform levels need precise jumps']; var instructionY = 300; var lineHeight = 45; for (var i = 0; i < instructions.length; i++) { var line = instructions[i]; var isHeader = line.endsWith(':'); var fontSize = isHeader ? 50 : 40; var color = isHeader ? 0x00FF00 : 0xFFFFFF; var instructionText = new Text2(line, { size: fontSize, fill: color }); instructionText.anchor.set(0, 0); instructionText.x = 200; instructionY += line === '' ? lineHeight * 0.5 : lineHeight; instructionText.y = instructionY; game.addChild(instructionText); } // Demo visual elements var demoY = 1800; // Show cube example var demoCube = LK.getAsset('player', { anchorX: 0.5, anchorY: 1.0 }); demoCube.x = 400; demoCube.y = demoY; game.addChild(demoCube); var cubeLabel = new Text2('Cube Mode', { size: 35, fill: 0x00FF00 }); cubeLabel.anchor.set(0.5, 0); cubeLabel.x = demoCube.x; cubeLabel.y = demoY + 20; game.addChild(cubeLabel); // Show ship example var demoShip = LK.getAsset('ship', { anchorX: 0.5, anchorY: 0.5 }); demoShip.x = 800; demoShip.y = demoY - 30; game.addChild(demoShip); var shipLabel = new Text2('Ship Mode', { size: 35, fill: 0x0088FF }); shipLabel.anchor.set(0.5, 0); shipLabel.x = demoShip.x; shipLabel.y = demoY + 20; game.addChild(shipLabel); // Show spike example var demoSpike = LK.getAsset('spike', { anchorX: 0.5, anchorY: 1.0 }); demoSpike.x = 1200; demoSpike.y = demoY; game.addChild(demoSpike); var spikeLabel = new Text2('Deadly Spike', { size: 35, fill: 0xFF0000 }); spikeLabel.anchor.set(0.5, 0); spikeLabel.x = demoSpike.x; spikeLabel.y = demoY + 20; game.addChild(spikeLabel); // Show platform example var demoPlatform = LK.getAsset('platform', { anchorX: 0, anchorY: 0 }); demoPlatform.x = 1500; demoPlatform.y = demoY - 40; demoPlatform.width = 150; game.addChild(demoPlatform); var platformLabel = new Text2('Safe Platform', { size: 35, fill: 0x888888 }); platformLabel.anchor.set(0.5, 0); platformLabel.x = demoPlatform.x + 75; platformLabel.y = demoY + 20; game.addChild(platformLabel); // Animate demo elements var animTime = 0; var videoUpdateTimer = LK.setInterval(function () { animTime += 0.1; // Bounce cube demoCube.y = demoY + Math.abs(Math.sin(animTime * 2)) * -30; // Float ship demoShip.y = demoY - 30 + Math.sin(animTime) * 15; // Pulse spike demoSpike.alpha = 0.7 + Math.sin(animTime * 3) * 0.3; }, 50); // Back button var backButton = LK.getAsset('levelButton', { anchorX: 0.5, anchorY: 0.5 }); backButton.x = 1024; backButton.y = 2400; backButton.tint = 0x666666; game.addChild(backButton); var backText = new Text2('Back to Menu', { size: 40, fill: 0xFFFFFF }); backText.anchor.set(0.5, 0.5); backText.x = backButton.x; backText.y = backButton.y; game.addChild(backText); backButton.down = function (x, y, obj) { LK.clearInterval(videoUpdateTimer); showLevelMenu(); }; } // Shop screen function showShop() { gameState = 'shop'; game.removeChildren(); // Title var titleText = new Text2('Geometry Dash Shop', { size: 80, fill: 0xFFFFFF }); titleText.anchor.set(0.5, 0); titleText.x = 1024; titleText.y = 150; game.addChild(titleText); // Coin display var coinDisplayText = new Text2('Coins: ' + storage.totalCoins, { size: 60, fill: 0xFFD700 }); coinDisplayText.anchor.set(0.5, 0); coinDisplayText.x = 1024; coinDisplayText.y = 250; game.addChild(coinDisplayText); // Shop items var shopItems = [{ name: 'Red Player', price: 100, type: 'playerColor', value: 0xff0000, description: 'Change player color to red' }, { name: 'Blue Player', price: 100, type: 'playerColor', value: 0x0000ff, description: 'Change player color to blue' }, { name: 'Yellow Player', price: 150, type: 'playerColor', value: 0xffff00, description: 'Change player color to yellow' }, { name: 'Purple Player', price: 150, type: 'playerColor', value: 0xff00ff, description: 'Change player color to purple' }, { name: 'Orange Player', price: 120, type: 'playerColor', value: 0xff8800, description: 'Change player color to orange' }, { name: 'Cyan Player', price: 120, type: 'playerColor', value: 0x00ffff, description: 'Change player color to cyan' }, { name: 'Pink Player', price: 180, type: 'playerColor', value: 0xff69b4, description: 'Change player color to pink' }, { name: 'Red Ship', price: 120, type: 'shipColor', value: 0xff0000, description: 'Change ship color to red' }, { name: 'Green Ship', price: 120, type: 'shipColor', value: 0x00ff00, description: 'Change ship color to green' }, { name: 'Yellow Ship', price: 180, type: 'shipColor', value: 0xffff00, description: 'Change ship color to yellow' }, { name: 'Purple Ship', price: 180, type: 'shipColor', value: 0xff00ff, description: 'Change ship color to purple' }, { name: 'Orange Ship', price: 160, type: 'shipColor', value: 0xff8800, description: 'Change ship color to orange' }, { name: 'Speed Boost', price: 300, type: 'speedMultiplier', value: 1.5, description: 'Increase movement speed by 50%' }, { name: 'Super Speed', price: 600, type: 'speedMultiplier', value: 2.0, description: 'Double movement speed' }, { name: 'Coin Magnet', price: 500, type: 'coinMagnet', value: true, description: 'Automatically collect nearby coins' }, { name: 'Extra Checkpoint', price: 250, type: 'checkpoint', value: true, description: 'Add extra checkpoints in levels' }, { name: 'Jump Boost', price: 400, type: 'jumpBoost', value: true, description: 'Jump 25% higher in cube mode' }, { name: 'Shield Protection', price: 800, type: 'shield', value: true, description: 'Survive one spike hit per level' }, { name: 'Size Reduction', price: 350, type: 'smallSize', value: true, description: 'Make player 25% smaller' }, { name: 'Trail Effect', price: 200, type: 'trail', value: true, description: 'Leave a colorful trail behind' }]; var itemY = 400; var itemsPerRow = 2; var itemSpacing = 400; for (var i = 0; i < shopItems.length; i++) { var item = shopItems[i]; var row = Math.floor(i / itemsPerRow); var col = i % itemsPerRow; var itemX = 1024 - (itemsPerRow - 1) * itemSpacing / 2 + col * itemSpacing; var currentItemY = itemY + row * 200; // Check if item is already purchased var isPurchased = storage.shopPurchases[item.name] || false; var canAfford = storage.totalCoins >= item.price; // Item button var itemButton = LK.getAsset('levelButton', { anchorX: 0.5, anchorY: 0.5 }); itemButton.x = itemX; itemButton.y = currentItemY; itemButton.scaleX = 1.8; itemButton.scaleY = 1.2; if (isPurchased) { itemButton.tint = 0x00ff00; // Green for purchased } else if (canAfford) { itemButton.tint = 0x0088ff; // Blue for affordable } else { itemButton.tint = 0x666666; // Gray for too expensive } game.addChild(itemButton); // Item name var nameText = new Text2(item.name, { size: 30, fill: 0xFFFFFF }); nameText.anchor.set(0.5, 0.5); nameText.x = itemX; nameText.y = currentItemY - 20; game.addChild(nameText); // Item price var priceText = new Text2(isPurchased ? 'OWNED' : item.price + ' coins', { size: 25, fill: isPurchased ? 0x00ff00 : 0xFFD700 }); priceText.anchor.set(0.5, 0.5); priceText.x = itemX; priceText.y = currentItemY + 20; game.addChild(priceText); // Purchase logic if (!isPurchased && canAfford) { itemButton.shopItem = item; itemButton.down = function (x, y, obj) { var itemToPurchase = this.shopItem; storage.totalCoins -= itemToPurchase.price; storage.shopPurchases[itemToPurchase.name] = true; storage[itemToPurchase.type] = itemToPurchase.value; showShop(); // Refresh shop display }; } } // Back button var backButton = LK.getAsset('levelButton', { anchorX: 0.5, anchorY: 0.5 }); backButton.x = 1024; backButton.y = itemY + Math.ceil(shopItems.length / itemsPerRow) * 200 + 100; backButton.tint = 0x666666; game.addChild(backButton); var backText = new Text2('Back to Menu', { size: 40, fill: 0xFFFFFF }); backText.anchor.set(0.5, 0.5); backText.x = backButton.x; backText.y = backButton.y; game.addChild(backText); backButton.down = function (x, y, obj) { showLevelMenu(); }; } // Generate daily shop items function generateDailyShop() { var today = new Date(); var dateString = today.getFullYear() + '-' + (today.getMonth() + 1) + '-' + today.getDate(); // Check if daily shop needs to be regenerated if (storage.dailyShopDate !== dateString) { storage.dailyShopDate = dateString; storage.dailyShopPurchases = {}; // Generate daily shop using date as seed for consistency var dayOfYear = Math.floor((today - new Date(today.getFullYear(), 0, 0)) / (1000 * 60 * 60 * 24)); var seed = dayOfYear + today.getFullYear() * 365; // All possible shop items var allItems = [{ name: 'Red Player', originalPrice: 100, type: 'playerColor', value: 0xff0000, description: 'Change player color to red' }, { name: 'Blue Player', originalPrice: 100, type: 'playerColor', value: 0x0000ff, description: 'Change player color to blue' }, { name: 'Yellow Player', originalPrice: 150, type: 'playerColor', value: 0xffff00, description: 'Change player color to yellow' }, { name: 'Purple Player', originalPrice: 150, type: 'playerColor', value: 0xff00ff, description: 'Change player color to purple' }, { name: 'Orange Player', originalPrice: 120, type: 'playerColor', value: 0xff8800, description: 'Change player color to orange' }, { name: 'Cyan Player', originalPrice: 120, type: 'playerColor', value: 0x00ffff, description: 'Change player color to cyan' }, { name: 'Pink Player', originalPrice: 180, type: 'playerColor', value: 0xff69b4, description: 'Change player color to pink' }, { name: 'Red Ship', originalPrice: 120, type: 'shipColor', value: 0xff0000, description: 'Change ship color to red' }, { name: 'Green Ship', originalPrice: 120, type: 'shipColor', value: 0x00ff00, description: 'Change ship color to green' }, { name: 'Yellow Ship', originalPrice: 180, type: 'shipColor', value: 0xffff00, description: 'Change ship color to yellow' }, { name: 'Purple Ship', originalPrice: 180, type: 'shipColor', value: 0xff00ff, description: 'Change ship color to purple' }, { name: 'Orange Ship', originalPrice: 160, type: 'shipColor', value: 0xff8800, description: 'Change ship color to orange' }, { name: 'Speed Boost', originalPrice: 300, type: 'speedMultiplier', value: 1.5, description: 'Increase movement speed by 50%' }, { name: 'Super Speed', originalPrice: 600, type: 'speedMultiplier', value: 2.0, description: 'Double movement speed' }, { name: 'Coin Magnet', originalPrice: 500, type: 'coinMagnet', value: true, description: 'Automatically collect nearby coins' }, { name: 'Extra Checkpoint', originalPrice: 250, type: 'checkpoint', value: true, description: 'Add extra checkpoints in levels' }, { name: 'Jump Boost', originalPrice: 400, type: 'jumpBoost', value: true, description: 'Jump 25% higher in cube mode' }, { name: 'Shield Protection', originalPrice: 800, type: 'shield', value: true, description: 'Survive one spike hit per level' }, { name: 'Size Reduction', originalPrice: 350, type: 'smallSize', value: true, description: 'Make player 25% smaller' }, { name: 'Trail Effect', originalPrice: 200, type: 'trail', value: true, description: 'Leave a colorful trail behind' }]; // Initialize daily shop items if not exists if (!storage.dailyShopItems) { storage.dailyShopItems = []; } // Select 3 random items for daily shop storage.dailyShopItems = []; var usedIndices = []; for (var i = 0; i < 3; i++) { var randomIndex; do { randomIndex = (seed + i * 7) % allItems.length; } while (usedIndices.indexOf(randomIndex) !== -1); usedIndices.push(randomIndex); var selectedItem = allItems[randomIndex]; // Apply random discount (20-50%) var discount = 20 + (seed + i * 3) % 31; var discountedPrice = Math.floor(selectedItem.originalPrice * (100 - discount) / 100); storage.dailyShopItems.push({ name: selectedItem.name, price: discountedPrice, discount: discount, type: selectedItem.type, value: selectedItem.value, description: selectedItem.description }); } } } // Daily shop screen function showDailyShop() { gameState = 'dailyShop'; game.removeChildren(); // Generate daily shop if needed generateDailyShop(); // Title var titleText = new Text2('Daily Shop', { size: 80, fill: 0xFFFFFF }); titleText.anchor.set(0.5, 0); titleText.x = 1024; titleText.y = 150; game.addChild(titleText); // Date display var today = new Date(); var dateString = today.getFullYear() + '-' + (today.getMonth() + 1) + '-' + today.getDate(); var dateText = new Text2('Date: ' + dateString, { size: 50, fill: 0x00FF00 }); dateText.anchor.set(0.5, 0); dateText.x = 1024; dateText.y = 250; game.addChild(dateText); // Coin display var coinDisplayText = new Text2('Coins: ' + storage.totalCoins, { size: 60, fill: 0xFFD700 }); coinDisplayText.anchor.set(0.5, 0); coinDisplayText.x = 1024; coinDisplayText.y = 320; game.addChild(coinDisplayText); // Shop items var itemY = 450; for (var i = 0; i < storage.dailyShopItems.length; i++) { var item = storage.dailyShopItems[i]; var currentItemY = itemY + i * 200; // Check if item is already purchased var isPurchased = storage.dailyShopPurchases[item.name] || false; var canAfford = storage.totalCoins >= item.price; // Item button var itemButton = LK.getAsset('levelButton', { anchorX: 0.5, anchorY: 0.5 }); itemButton.x = 1024; itemButton.y = currentItemY; itemButton.scaleX = 2.5; itemButton.scaleY = 1.2; if (isPurchased) { itemButton.tint = 0x00ff00; // Green for purchased } else if (canAfford) { itemButton.tint = 0xff6600; // Orange for daily special } else { itemButton.tint = 0x666666; // Gray for too expensive } game.addChild(itemButton); // Item name var nameText = new Text2(item.name, { size: 35, fill: 0xFFFFFF }); nameText.anchor.set(0.5, 0.5); nameText.x = 1024; nameText.y = currentItemY - 25; game.addChild(nameText); // Item price and discount var discountText = item.discount + '% OFF!'; var priceText = new Text2(isPurchased ? 'OWNED' : item.price + ' coins (' + discountText + ')', { size: 28, fill: isPurchased ? 0x00ff00 : 0xFFD700 }); priceText.anchor.set(0.5, 0.5); priceText.x = 1024; priceText.y = currentItemY + 10; game.addChild(priceText); // Description var descText = new Text2(item.description, { size: 24, fill: 0xCCCCCC }); descText.anchor.set(0.5, 0.5); descText.x = 1024; descText.y = currentItemY + 35; game.addChild(descText); // Purchase logic if (!isPurchased && canAfford) { itemButton.shopItem = item; itemButton.down = function (x, y, obj) { var itemToPurchase = this.shopItem; storage.totalCoins -= itemToPurchase.price; storage.dailyShopPurchases[itemToPurchase.name] = true; storage[itemToPurchase.type] = itemToPurchase.value; showDailyShop(); // Refresh shop display }; } } // Back button var backButton = LK.getAsset('levelButton', { anchorX: 0.5, anchorY: 0.5 }); backButton.x = 1024; backButton.y = itemY + storage.dailyShopItems.length * 200 + 100; backButton.tint = 0x666666; game.addChild(backButton); var backText = new Text2('Back to Menu', { size: 40, fill: 0xFFFFFF }); backText.anchor.set(0.5, 0.5); backText.x = backButton.x; backText.y = backButton.y; game.addChild(backText); backButton.down = function (x, y, obj) { showLevelMenu(); }; } // Gem shop screen function showGemShop() { gameState = 'gemShop'; game.removeChildren(); // Title var titleText = new Text2('Premium Gem Shop', { size: 80, fill: 0xFFFFFF }); titleText.anchor.set(0.5, 0); titleText.x = 1024; titleText.y = 150; game.addChild(titleText); // Gem display var gemDisplayText = new Text2('Gems: ' + storage.totalGems, { size: 60, fill: 0xFF00FF }); gemDisplayText.anchor.set(0.5, 0); gemDisplayText.x = 1024; gemDisplayText.y = 250; game.addChild(gemDisplayText); // Premium shop items var gemShopItems = [{ name: 'Rainbow Player', price: 5, type: 'playerColor', value: 0x00ffff, description: 'Exclusive rainbow-like cyan player' }, { name: 'Golden Player', price: 8, type: 'playerColor', value: 0xffd700, description: 'Luxurious golden player color' }, { name: 'Diamond Ship', price: 10, type: 'shipColor', value: 0xb9f2ff, description: 'Sparkling diamond ship' }, { name: 'Ruby Ship', price: 8, type: 'shipColor', value: 0xe0115f, description: 'Deep ruby red ship' }, { name: 'Ultra Speed', price: 15, type: 'speedMultiplier', value: 3.0, description: 'Triple movement speed' }, { name: 'Mega Jump', price: 12, type: 'jumpBoost', value: true, description: 'Jump 50% higher than normal' }, { name: 'Double Shield', price: 20, type: 'shield', value: true, description: 'Survive two spike hits per level' }, { name: 'Coin Multiplier x2', price: 25, type: 'coinMultiplier', value: 2.0, description: 'Double all coin rewards' }, { name: 'Ghost Mode', price: 30, type: 'ghostMode', value: true, description: 'Pass through spikes for 5 seconds' }, { name: 'Level Skip Token', price: 50, type: 'skipToken', value: true, description: 'Skip any level instantly' }]; var itemY = 400; var itemsPerRow = 2; var itemSpacing = 400; for (var i = 0; i < gemShopItems.length; i++) { var item = gemShopItems[i]; var row = Math.floor(i / itemsPerRow); var col = i % itemsPerRow; var itemX = 1024 - (itemsPerRow - 1) * itemSpacing / 2 + col * itemSpacing; var currentItemY = itemY + row * 200; // Check if item is already purchased var isPurchased = storage.gemShopPurchases[item.name] || false; var canAfford = storage.totalGems >= item.price; // Item button var itemButton = LK.getAsset('levelButton', { anchorX: 0.5, anchorY: 0.5 }); itemButton.x = itemX; itemButton.y = currentItemY; itemButton.scaleX = 1.8; itemButton.scaleY = 1.2; if (isPurchased) { itemButton.tint = 0x00ff00; // Green for purchased } else if (canAfford) { itemButton.tint = 0xff00ff; // Magenta for gem shop } else { itemButton.tint = 0x666666; // Gray for too expensive } game.addChild(itemButton); // Item name var nameText = new Text2(item.name, { size: 30, fill: 0xFFFFFF }); nameText.anchor.set(0.5, 0.5); nameText.x = itemX; nameText.y = currentItemY - 20; game.addChild(nameText); // Item price var priceText = new Text2(isPurchased ? 'OWNED' : item.price + ' gems', { size: 25, fill: isPurchased ? 0x00ff00 : 0xFF00FF }); priceText.anchor.set(0.5, 0.5); priceText.x = itemX; priceText.y = currentItemY + 20; game.addChild(priceText); // Purchase logic if (!isPurchased && canAfford) { itemButton.shopItem = item; itemButton.down = function (x, y, obj) { var itemToPurchase = this.shopItem; storage.totalGems -= itemToPurchase.price; storage.gemShopPurchases[itemToPurchase.name] = true; storage[itemToPurchase.type] = itemToPurchase.value; showGemShop(); // Refresh shop display }; } } // Back button var backButton = LK.getAsset('levelButton', { anchorX: 0.5, anchorY: 0.5 }); backButton.x = 1024; backButton.y = itemY + Math.ceil(gemShopItems.length / itemsPerRow) * 200 + 100; backButton.tint = 0x666666; game.addChild(backButton); var backText = new Text2('Back to Menu', { size: 40, fill: 0xFFFFFF }); backText.anchor.set(0.5, 0.5); backText.x = backButton.x; backText.y = backButton.y; game.addChild(backText); backButton.down = function (x, y, obj) { showLevelMenu(); }; } // Owner commands screen function showOwnerCommands() { gameState = 'owner'; game.removeChildren(); // Title var titleText = new Text2('Owner Commands', { size: 80, fill: 0xFFFFFF }); titleText.anchor.set(0.5, 0); titleText.x = 1024; titleText.y = 200; game.addChild(titleText); // Command buttons // Initialize page tracking if not exists if (!storage.ownerCommandsPage) { storage.ownerCommandsPage = 1; } var allCommandButtons = [{ text: 'Unlock All Levels', action: unlockAllLevels }, { text: 'Reset Progress', action: resetProgress }, { text: 'Complete All Levels', action: completeAllLevels }, { text: 'Give 1000 Coins', action: giveCoins }, { text: 'Reset Coins', action: resetCoins }, { text: 'Give 100 Gems', action: giveGems }, { text: 'Reset Gems', action: resetGems }, { text: 'Complete Daily Level', action: completeDailyLevel }, { text: 'Reset Daily Level', action: resetDailyLevel }, { text: 'Skip to Level 25', action: skipToLevel25 }, { text: 'Skip to Level 50', action: skipToLevel50 }, { text: 'God Mode On', action: enableGodMode }, { text: 'God Mode Off', action: disableGodMode }, { text: 'Speed Boost On', action: enableSpeedBoost }, { text: 'Speed Boost Off', action: disableSpeedBoost }, { text: 'Show Debug Info', action: showDebugInfo }, { text: 'Clear Debug Info', action: clearDebugInfo }, { text: 'Teleport to End', action: teleportToEnd }, { text: 'Toggle Invincibility', action: toggleInvincibility }, { text: 'Max All Shop Items', action: maxAllShopItems }, { text: 'Reset Shop Purchases', action: resetShopPurchases }, { text: 'Instant Level Complete', action: instantLevelComplete }, { text: 'Unlock Daily Shop', action: unlockDailyShop }, { text: 'Reset All Data', action: resetAllData }]; var commandsPerPage = 10; var totalPages = Math.ceil(allCommandButtons.length / commandsPerPage); var currentPage = storage.ownerCommandsPage || 1; // Get commands for current page var startIndex = (currentPage - 1) * commandsPerPage; var endIndex = Math.min(startIndex + commandsPerPage, allCommandButtons.length); var commandButtons = allCommandButtons.slice(startIndex, endIndex); // Add navigation buttons if (currentPage < totalPages) { commandButtons.push({ text: 'Next Page (' + (currentPage + 1) + '/' + totalPages + ')', action: function action() { storage.ownerCommandsPage = currentPage + 1; showOwnerCommands(); } }); } if (currentPage > 1) { commandButtons.push({ text: 'Previous Page (' + (currentPage - 1) + '/' + totalPages + ')', action: function action() { storage.ownerCommandsPage = currentPage - 1; showOwnerCommands(); } }); } // Add back to menu as last option commandButtons.push({ text: 'Back to Menu', action: showLevelMenu }); var buttonY = 400; for (var i = 0; i < commandButtons.length; i++) { var cmdButton = LK.getAsset('levelButton', { anchorX: 0.5, anchorY: 0.5 }); cmdButton.x = 1024; cmdButton.y = buttonY + i * 150; cmdButton.tint = 0x444444; game.addChild(cmdButton); var cmdText = new Text2(commandButtons[i].text, { size: 35, fill: 0xFFFFFF }); cmdText.anchor.set(0.5, 0.5); cmdText.x = cmdButton.x; cmdText.y = cmdButton.y; game.addChild(cmdText); cmdButton.commandAction = commandButtons[i].action; cmdButton.down = function (x, y, obj) { this.commandAction(); }; } } // Owner command functions function unlockAllLevels() { for (var i = 1; i <= maxLevels; i++) { storage.completedLevels[i] = false; // Unlocked but not completed } showLevelMenu(); } function resetProgress() { storage.completedLevels = {}; storage.totalCoins = 0; storage.levelCoins = {}; showLevelMenu(); } function completeAllLevels() { for (var i = 1; i <= maxLevels; i++) { storage.completedLevels[i] = true; } showLevelMenu(); } function giveCoins() { storage.totalCoins += 1000; showOwnerCommands(); } function resetCoins() { storage.totalCoins = 0; storage.levelCoins = {}; showOwnerCommands(); } function completeDailyLevel() { storage.dailyLevelCompleted = true; storage.dailyLevelCoins = 5; showOwnerCommands(); } function resetDailyLevel() { storage.dailyLevelCompleted = false; storage.dailyLevelCoins = 0; showOwnerCommands(); } function skipToLevel25() { for (var i = 1; i <= 25; i++) { storage.completedLevels[i] = true; } showLevelMenu(); } function skipToLevel50() { for (var i = 1; i <= 50; i++) { storage.completedLevels[i] = true; } showLevelMenu(); } function enableGodMode() { godModeEnabled = true; showOwnerCommands(); } function disableGodMode() { godModeEnabled = false; showOwnerCommands(); } function enableSpeedBoost() { speedBoostEnabled = true; scrollSpeed = 24; // Double speed showOwnerCommands(); } function disableSpeedBoost() { speedBoostEnabled = false; scrollSpeed = 12; // Normal speed showOwnerCommands(); } function showDebugInfo() { debugInfoVisible = true; if (!debugText) { debugText = new Text2('Debug Info', { size: 30, fill: 0x00FF00 }); debugText.anchor.set(0, 0); debugText.x = 120; debugText.y = 180; LK.gui.topLeft.addChild(debugText); } showOwnerCommands(); } function clearDebugInfo() { debugInfoVisible = false; if (debugText) { LK.gui.topLeft.removeChild(debugText); debugText = null; } showOwnerCommands(); } function giveGems() { storage.totalGems += 100; showOwnerCommands(); } function resetGems() { storage.totalGems = 0; showOwnerCommands(); } function teleportToEnd() { if (gameState === 'playing' && player) { var levelLength = levelData[currentLevel] ? levelData[currentLevel].length : 3000; player.x = levelLength - 100; cameraX = levelLength - 500; } showGameplay(); } function toggleInvincibility() { godModeEnabled = !godModeEnabled; showOwnerCommands(); } function maxAllShopItems() { var allShopItemNames = ['Red Player', 'Blue Player', 'Yellow Player', 'Purple Player', 'Orange Player', 'Cyan Player', 'Pink Player', 'Red Ship', 'Green Ship', 'Yellow Ship', 'Purple Ship', 'Orange Ship', 'Speed Boost', 'Super Speed', 'Coin Magnet', 'Extra Checkpoint', 'Jump Boost', 'Shield Protection', 'Size Reduction', 'Trail Effect']; for (var i = 0; i < allShopItemNames.length; i++) { storage.shopPurchases[allShopItemNames[i]] = true; } // Apply all effects storage.playerColor = 0xff69b4; // Pink storage.shipColor = 0xffff00; // Yellow storage.speedMultiplier = 2.0; storage.coinMagnet = true; storage.checkpoint = true; storage.jumpBoost = true; storage.shield = true; storage.smallSize = true; storage.trail = true; showOwnerCommands(); } function resetShopPurchases() { storage.shopPurchases = {}; storage.dailyShopPurchases = {}; storage.gemShopPurchases = {}; // Reset to defaults storage.playerColor = 0x00ff00; storage.shipColor = 0x0088ff; storage.speedMultiplier = 1.0; storage.coinMagnet = false; storage.checkpoint = false; storage.jumpBoost = false; storage.shield = false; storage.smallSize = false; storage.trail = false; showOwnerCommands(); } function instantLevelComplete() { if (gameState === 'playing') { completeLevel(); } showOwnerCommands(); } function unlockDailyShop() { // Force regenerate daily shop with all items available storage.dailyShopDate = ''; generateDailyShop(); showOwnerCommands(); } function resetAllData() { storage.completedLevels = {}; storage.totalCoins = 0; storage.levelCoins = {}; storage.totalGems = 0; storage.shopPurchases = {}; storage.dailyShopPurchases = {}; storage.gemShopPurchases = {}; storage.dailyLevelCompleted = false; storage.dailyLevelCoins = 0; storage.ownerCommandsPage = 1; // Reset to defaults storage.playerColor = 0x00ff00; storage.shipColor = 0x0088ff; storage.speedMultiplier = 1.0; storage.coinMagnet = false; storage.checkpoint = false; storage.jumpBoost = false; storage.shield = false; storage.smallSize = false; storage.trail = false; showLevelMenu(); } // Initialize game initializeLevelData(); setupUI(); showLevelMenu();
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/****
* Classes
****/
var Checkpoint = Container.expand(function (x, y) {
var self = Container.call(this);
var checkpointGraphics = self.attachAsset('checkpoint', {
anchorX: 0.5,
anchorY: 1.0
});
self.x = x;
self.y = y;
self.activated = false;
return self;
});
var Coin = Container.expand(function (x, y) {
var self = Container.call(this);
var coinGraphics = self.attachAsset('coin', {
anchorX: 0.5,
anchorY: 0.5
});
self.x = x;
self.y = y;
self.collected = false;
self.rotationSpeed = 0.05;
self.update = function () {
if (!self.collected) {
coinGraphics.rotation += self.rotationSpeed;
}
};
return self;
});
var Ground = Container.expand(function (x, y, width) {
var self = Container.call(this);
var groundGraphics = self.attachAsset('ground', {
anchorX: 0,
anchorY: 0
});
groundGraphics.width = width || 200;
self.x = x;
self.y = y;
return self;
});
var LevelButton = Container.expand(function (levelNum, x, y) {
var self = Container.call(this);
var buttonGraphics = self.attachAsset('levelButton', {
anchorX: 0.5,
anchorY: 0.5
});
self.levelNum = levelNum;
self.x = x;
self.y = y;
self.locked = levelNum > 1 && !storage.completedLevels[levelNum - 1];
// Set button color based on status
if (self.locked) {
buttonGraphics.tint = 0x666666;
} else if (storage.completedLevels[levelNum]) {
buttonGraphics.tint = 0x00ff00;
}
// Level number text
self.levelText = new Text2(levelNum.toString(), {
size: 40,
fill: 0xFFFFFF
});
self.levelText.anchor.set(0.5, 0.3);
self.addChild(self.levelText);
// Coin count text
var coinCount = storage.levelCoins[levelNum] || 0;
var maxCoins = levelData[levelNum] ? levelData[levelNum].coins.length : 0;
self.coinText = new Text2(coinCount + '/' + maxCoins, {
size: 25,
fill: 0xFFD700
});
self.coinText.anchor.set(0.5, 0.7);
self.addChild(self.coinText);
self.down = function (x, y, obj) {
if (!self.locked) {
currentLevel = self.levelNum;
showGameplay();
}
};
return self;
});
var Platform = Container.expand(function (x, y, width) {
var self = Container.call(this);
var platformGraphics = self.attachAsset('platform', {
anchorX: 0,
anchorY: 0
});
platformGraphics.width = width || 200;
self.x = x;
self.y = y;
return self;
});
var Player = Container.expand(function () {
var self = Container.call(this);
self.isShipMode = false;
self.playerGraphics = null;
self.shipGraphics = null;
self.setMode = function (isShip) {
if (self.playerGraphics) {
self.removeChild(self.playerGraphics);
self.playerGraphics = null;
}
if (self.shipGraphics) {
self.removeChild(self.shipGraphics);
self.shipGraphics = null;
}
self.isShipMode = isShip;
if (isShip) {
self.shipGraphics = self.attachAsset('ship', {
anchorX: 0.5,
anchorY: 0.5
});
// Apply purchased ship color
if (storage.shipColor) {
self.shipGraphics.tint = storage.shipColor;
}
// Apply size reduction
if (storage.smallSize) {
self.shipGraphics.scaleX = 0.75;
self.shipGraphics.scaleY = 0.75;
}
} else {
self.playerGraphics = self.attachAsset('player', {
anchorX: 0.5,
anchorY: 1.0
});
// Apply purchased player color
if (storage.playerColor) {
self.playerGraphics.tint = storage.playerColor;
}
// Apply size reduction
if (storage.smallSize) {
self.playerGraphics.scaleX = 0.75;
self.playerGraphics.scaleY = 0.75;
}
}
};
// Initialize with player mode
self.setMode(false);
self.velocityY = 0;
self.isGrounded = false;
self.isDead = false;
self.isFlying = false;
self.isSwinging = false;
self.swingAnchor = null;
self.swingAngle = 0;
self.swingLength = 0;
self.swingSpeed = 0;
self.jump = function () {
if (self.isShipMode) {
if (!self.isDead) {
self.isFlying = true;
self.velocityY = -12;
LK.getSound('jump').play();
}
} else {
if (self.isGrounded && !self.isDead) {
var jumpPower = storage.jumpBoost ? -30 : -24;
self.velocityY = jumpPower;
self.isGrounded = false;
LK.getSound('jump').play();
}
}
};
self.stopJump = function () {
if (self.isShipMode) {
self.isFlying = false;
} else if (self.isSwinging) {
// Release from swing
var releaseVelX = Math.cos(self.swingAngle + Math.PI / 2) * self.swingSpeed * 0.8;
var releaseVelY = Math.sin(self.swingAngle + Math.PI / 2) * self.swingSpeed * 0.8;
self.velocityY = releaseVelY;
self.releaseVelX = releaseVelX;
self.isSwinging = false;
if (self.swingAnchor) {
self.swingAnchor.deactivateSwing();
self.swingAnchor = null;
}
}
};
self.update = function () {
if (self.isDead) return;
// Trail effect
if (storage.trail) {
var trailParticle = LK.getAsset('coin', {
anchorX: 0.5,
anchorY: 0.5
});
trailParticle.x = self.x;
trailParticle.y = self.y;
trailParticle.scaleX = 0.3;
trailParticle.scaleY = 0.3;
trailParticle.alpha = 0.6;
trailParticle.tint = storage.playerColor || 0x00ff00;
game.addChild(trailParticle);
// Fade out trail particle
tween(trailParticle, {
alpha: 0,
scaleX: 0,
scaleY: 0
}, {
duration: 500,
onComplete: function onComplete() {
game.removeChild(trailParticle);
}
});
}
if (self.isSwinging) {
// Swing physics
var gravity = 0.8;
var dampening = 0.995;
// Apply gravity to swing speed
var gravityForce = gravity * Math.cos(self.swingAngle);
self.swingSpeed += gravityForce;
self.swingSpeed *= dampening;
// Update swing angle
self.swingAngle += self.swingSpeed / self.swingLength;
// Update player position based on swing
self.x = self.swingAnchor.x + Math.cos(self.swingAngle) * self.swingLength;
self.y = self.swingAnchor.y + Math.sin(self.swingAngle) * self.swingLength;
// Update rope visual if exists
if (self.swingAnchor.rope) {
self.swingAnchor.rope.rotation = self.swingAngle;
}
} else if (self.isShipMode) {
// Ship mode physics
if (self.isFlying) {
self.velocityY -= 2.5;
} else {
self.velocityY += 2.0;
}
// Limit ship velocity
if (self.velocityY > 18) self.velocityY = 18;
if (self.velocityY < -18) self.velocityY = -18;
self.y += self.velocityY;
// Ship ground collision
if (self.y >= groundLevel - 20) {
self.y = groundLevel - 20;
self.velocityY = 0;
}
// Ship ceiling collision
if (self.y <= 100) {
self.y = 100;
self.velocityY = 0;
}
} else {
// Regular cube mode physics
if (self.releaseVelX) {
// Apply horizontal velocity from swing release
self.x += self.releaseVelX;
self.releaseVelX *= 0.95; // Decay horizontal velocity
if (Math.abs(self.releaseVelX) < 0.5) {
self.releaseVelX = 0;
}
}
self.velocityY += 2.0;
self.y += self.velocityY;
// Ground collision
if (self.y >= groundLevel) {
self.y = groundLevel;
self.velocityY = 0;
self.isGrounded = true;
self.releaseVelX = 0; // Stop horizontal movement on ground
}
}
};
return self;
});
var Spike = Container.expand(function (x, y) {
var self = Container.call(this);
var spikeGraphics = self.attachAsset('spike', {
anchorX: 0.5,
anchorY: 1.0
});
self.x = x;
self.y = y;
return self;
});
var SwingAnchor = Container.expand(function (x, y) {
var self = Container.call(this);
var anchorGraphics = self.attachAsset('swingAnchor', {
anchorX: 0.5,
anchorY: 0.5
});
self.x = x;
self.y = y;
self.isActive = false;
self.rope = null;
self.activateSwing = function (player) {
if (!self.isActive && !player.isSwinging) {
self.isActive = true;
player.isSwinging = true;
player.swingAnchor = self;
player.swingAngle = Math.atan2(player.y - self.y, player.x - self.x);
player.swingLength = Math.sqrt(Math.pow(player.x - self.x, 2) + Math.pow(player.y - self.y, 2));
player.swingSpeed = 0;
// Create visual rope
self.rope = LK.getAsset('ground', {
anchorX: 0,
anchorY: 0.5
});
self.rope.width = player.swingLength;
self.rope.height = 4;
self.rope.tint = 0x8B4513;
self.rope.x = self.x;
self.rope.y = self.y;
self.rope.rotation = self.swingAngle;
game.addChild(self.rope);
// Animate anchor activation
tween(anchorGraphics, {
scaleX: 1.5,
scaleY: 1.5
}, {
duration: 200,
easing: tween.bounceOut
});
}
};
self.deactivateSwing = function () {
self.isActive = false;
if (self.rope) {
game.removeChild(self.rope);
self.rope = null;
}
tween(anchorGraphics, {
scaleX: 1,
scaleY: 1
}, {
duration: 150
});
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x222222
});
/****
* Game Code
****/
// Game states
var gameState = 'menu'; // 'menu' or 'playing'
var currentLevel = 1;
var maxLevels = 68;
var groundLevel = 2400;
var cameraX = 0;
var scrollSpeed = 12;
// Player variables
var player;
var playerStartX = 300;
var playerStartY = groundLevel;
// Level data
var obstacles = [];
var platforms = [];
var grounds = [];
var checkpoints = [];
var swingAnchors = [];
var coins = [];
var currentCheckpoint = 0;
var levelData = {};
// UI elements
var levelButtons = [];
var backButton;
var levelCompleteText;
var deathCount = 0;
var godModeEnabled = false;
var speedBoostEnabled = false;
var debugInfoVisible = false;
var debugText = null;
// Storage initialization
if (!storage.completedLevels) {
storage.completedLevels = {};
}
if (!storage.currentLevel) {
storage.currentLevel = 1;
}
if (!storage.totalCoins) {
storage.totalCoins = 0;
}
if (!storage.levelCoins) {
storage.levelCoins = {};
}
if (!storage.dailyLevelDate) {
storage.dailyLevelDate = '';
}
if (!storage.dailyLevelCompleted) {
storage.dailyLevelCompleted = false;
}
if (!storage.dailyLevelCoins) {
storage.dailyLevelCoins = 0;
}
// Shop storage initialization
if (!storage.shopPurchases) {
storage.shopPurchases = {};
}
if (!storage.playerColor) {
storage.playerColor = 0x00ff00; // Default green
}
if (!storage.shipColor) {
storage.shipColor = 0x0088ff; // Default blue
}
if (!storage.speedMultiplier) {
storage.speedMultiplier = 1.0;
}
if (!storage.coinMagnet) {
storage.coinMagnet = false;
}
if (!storage.checkpoint) {
storage.checkpoint = false;
}
if (!storage.jumpBoost) {
storage.jumpBoost = false;
}
if (!storage.shield) {
storage.shield = false;
}
if (!storage.smallSize) {
storage.smallSize = false;
}
if (!storage.trail) {
storage.trail = false;
}
if (!storage.shieldUsed) {
storage.shieldUsed = false;
}
// Daily shop storage initialization
if (!storage.dailyShopDate) {
storage.dailyShopDate = '';
}
if (!storage.dailyShopItems) {
storage.dailyShopItems = [];
}
if (!storage.dailyShopPurchases) {
storage.dailyShopPurchases = {};
}
// Gem shop storage initialization
if (!storage.totalGems) {
storage.totalGems = 10; // Start with 10 gems
}
if (!storage.gemShopPurchases) {
storage.gemShopPurchases = {};
}
// Generate daily level based on current date
function generateDailyLevel() {
var today = new Date();
var dateString = today.getFullYear() + '-' + (today.getMonth() + 1) + '-' + today.getDate();
// Check if daily level needs to be regenerated
if (storage.dailyLevelDate !== dateString) {
storage.dailyLevelDate = dateString;
storage.dailyLevelCompleted = false;
storage.dailyLevelCoins = 0;
}
// Generate daily level using date as seed for consistency
var dayOfYear = Math.floor((today - new Date(today.getFullYear(), 0, 0)) / (1000 * 60 * 60 * 24));
var seed = dayOfYear + today.getFullYear() * 365;
levelData['daily'] = {
spikes: [],
platforms: [],
checkpoints: [],
swingAnchors: [],
coins: [],
length: 3000,
shipMode: seed % 3 === 0 // Ship mode every 3rd type of pattern
};
// Generate pattern based on seed
var patternType = seed % 5;
if (patternType === 0) {
// Spike gauntlet
for (var i = 0; i < 8; i++) {
levelData['daily'].spikes.push({
x: 800 + i * 300,
y: groundLevel
});
if (i % 2 === 1) {
levelData['daily'].spikes.push({
x: 840 + i * 300,
y: groundLevel
});
}
}
} else if (patternType === 1) {
// Platform jumps with swings
for (var i = 0; i < 6; i++) {
levelData['daily'].platforms.push({
x: 700 + i * 400,
y: groundLevel - 120,
width: 120
});
levelData['daily'].spikes.push({
x: 820 + i * 400,
y: groundLevel - 120
});
if (i < 5) {
levelData['daily'].swingAnchors.push({
x: 1000 + i * 400,
y: groundLevel - 250
});
}
}
} else if (patternType === 2) {
// Mixed chaos
for (var i = 0; i < 10; i++) {
if (i % 3 === 0) {
levelData['daily'].platforms.push({
x: 700 + i * 250,
y: groundLevel - 100,
width: 100
});
} else {
levelData['daily'].spikes.push({
x: 700 + i * 250,
y: groundLevel
});
}
}
} else if (patternType === 3) {
// Staircase challenge
for (var i = 0; i < 7; i++) {
levelData['daily'].platforms.push({
x: 700 + i * 300,
y: groundLevel - i * 50,
width: 150
});
levelData['daily'].spikes.push({
x: 850 + i * 300,
y: groundLevel - i * 50
});
}
} else {
// Speed run
for (var i = 0; i < 12; i++) {
levelData['daily'].spikes.push({
x: 700 + i * 200,
y: groundLevel
});
if (i % 4 === 3) {
levelData['daily'].spikes.push({
x: 720 + i * 200,
y: groundLevel
});
}
}
}
// Add daily coins (always 5 coins for daily level)
for (var i = 0; i < 5; i++) {
levelData['daily'].coins.push({
x: 600 + (i + 1) * (levelData['daily'].length / 6),
y: groundLevel - 100 - i % 3 * 40
});
}
// Add checkpoints
levelData['daily'].checkpoints.push({
x: 1500,
y: groundLevel
});
levelData['daily'].checkpoints.push({
x: 2250,
y: groundLevel
});
}
// Initialize level data with unique patterns for each level
function initializeLevelData() {
for (var i = 1; i <= 68; i++) {
levelData[i] = {
spikes: [],
platforms: [],
checkpoints: [],
swingAnchors: [],
coins: [],
length: 2500 + i * 150,
shipMode: false
};
// Define unique patterns for each level
if (i === 1) {
// Level 1: Ship mode tutorial - simple gaps
levelData[i].shipMode = true;
levelData[i].length = 2000;
for (var s = 0; s < 3; s++) {
levelData[i].spikes.push({
x: 1000 + s * 600,
y: groundLevel
});
levelData[i].spikes.push({
x: 1000 + s * 600,
y: groundLevel - 300
});
// Add coins between spikes
if (s < 2) {
levelData[i].coins.push({
x: 1300 + s * 600,
y: groundLevel - 150
});
}
}
} else if (i === 2) {
// Level 2: Single spike jumps
for (var s = 0; s < 4; s++) {
levelData[i].spikes.push({
x: 800 + s * 400,
y: groundLevel
});
// Add coin above each spike
levelData[i].coins.push({
x: 800 + s * 400,
y: groundLevel - 100
});
}
} else if (i === 3) {
// Level 3: Double spike jumps
for (var s = 0; s < 3; s++) {
levelData[i].spikes.push({
x: 800 + s * 500,
y: groundLevel
});
levelData[i].spikes.push({
x: 840 + s * 500,
y: groundLevel
});
}
} else if (i === 4) {
// Level 4: Platform jumps with swing anchors
for (var p = 0; p < 4; p++) {
levelData[i].platforms.push({
x: 800 + p * 400,
y: groundLevel - 120,
width: 150
});
levelData[i].spikes.push({
x: 975 + p * 400,
y: groundLevel - 120
});
// Add swing anchor between platforms
if (p < 3) {
levelData[i].swingAnchors.push({
x: 1075 + p * 400,
y: groundLevel - 200
});
}
}
} else if (i === 5) {
// Level 5: Spike clusters
for (var c = 0; c < 3; c++) {
for (var s = 0; s < 3; s++) {
levelData[i].spikes.push({
x: 800 + c * 600 + s * 50,
y: groundLevel
});
}
// Add coin above each cluster
levelData[i].coins.push({
x: 850 + c * 600,
y: groundLevel - 120
});
}
} else if (i >= 6 && i <= 10) {
// Levels 6-10: Mixed patterns with increasing difficulty
var patternType = (i - 6) % 3;
if (patternType === 0) {
// Alternating single and double spikes
for (var s = 0; s < 5; s++) {
levelData[i].spikes.push({
x: 700 + s * 350,
y: groundLevel
});
if (s % 2 === 1) {
levelData[i].spikes.push({
x: 740 + s * 350,
y: groundLevel
});
}
// Add coins between spikes
if (s < 4) {
levelData[i].coins.push({
x: 875 + s * 350,
y: groundLevel - 80
});
}
}
} else if (patternType === 1) {
// Platform hopping
for (var p = 0; p < 4; p++) {
var height = groundLevel - 100 - p % 2 * 80;
levelData[i].platforms.push({
x: 800 + p * 350,
y: height,
width: 120
});
levelData[i].spikes.push({
x: 920 + p * 350,
y: height
});
}
} else {
// Triple spike jumps
for (var t = 0; t < 3; t++) {
for (var s = 0; s < 3; s++) {
levelData[i].spikes.push({
x: 800 + t * 500 + s * 45,
y: groundLevel
});
}
}
}
} else if (i >= 11 && i <= 20) {
// Levels 11-20: Advanced patterns
var complexity = i - 10;
if (i % 4 === 1) {
// Staircase platforms with spikes
for (var st = 0; st < 5; st++) {
var stairY = groundLevel - st * 60;
levelData[i].platforms.push({
x: 700 + st * 300,
y: stairY,
width: 150
});
levelData[i].spikes.push({
x: 850 + st * 300,
y: stairY
});
}
} else if (i % 4 === 2) {
// Ship mode level
levelData[i].shipMode = true;
for (var s = 0; s < 6; s++) {
levelData[i].spikes.push({
x: 800 + s * 300,
y: groundLevel
});
levelData[i].spikes.push({
x: 800 + s * 300,
y: groundLevel - 250
});
}
} else if (i % 4 === 3) {
// Maze-like platforms with swing challenges
for (var m = 0; m < 4; m++) {
var upper = m % 2 === 0;
var platY = upper ? groundLevel - 200 : groundLevel - 100;
levelData[i].platforms.push({
x: 700 + m * 400,
y: platY,
width: 200
});
levelData[i].spikes.push({
x: 800 + m * 400,
y: platY
});
// Add swing anchors for advanced navigation
if (m < 3) {
levelData[i].swingAnchors.push({
x: 900 + m * 400,
y: groundLevel - 300
});
}
}
} else {
// Rapid fire spikes
for (var r = 0; r < 8; r++) {
levelData[i].spikes.push({
x: 700 + r * 200,
y: groundLevel
});
}
}
} else if (i >= 21 && i <= 35) {
// Levels 21-35: Expert patterns
if (i % 5 === 1) {
// Multi-level platforms
for (var ml = 0; ml < 3; ml++) {
for (var level = 0; level < 3; level++) {
var platY = groundLevel - 80 - level * 70;
levelData[i].platforms.push({
x: 700 + ml * 500 + level * 100,
y: platY,
width: 100
});
if (level < 2) {
levelData[i].spikes.push({
x: 750 + ml * 500 + level * 100,
y: platY
});
}
}
// Add challenging coin placement
levelData[i].coins.push({
x: 850 + ml * 500,
y: groundLevel - 250
});
}
} else if (i % 5 === 2) {
// Ship maze
levelData[i].shipMode = true;
for (var sm = 0; sm < 5; sm++) {
levelData[i].spikes.push({
x: 800 + sm * 250,
y: groundLevel
});
levelData[i].spikes.push({
x: 825 + sm * 250,
y: groundLevel - 150
});
levelData[i].spikes.push({
x: 850 + sm * 250,
y: groundLevel - 300
});
}
} else if (i % 5 === 3) {
// Wave pattern spikes
for (var w = 0; w < 8; w++) {
var wave = Math.sin(w * 0.8) * 100;
levelData[i].spikes.push({
x: 700 + w * 150,
y: groundLevel + wave
});
}
} else if (i % 5 === 4) {
// Tight platform sequences
for (var tp = 0; tp < 6; tp++) {
levelData[i].platforms.push({
x: 700 + tp * 250,
y: groundLevel - 120,
width: 80
});
levelData[i].spikes.push({
x: 780 + tp * 250,
y: groundLevel - 120
});
levelData[i].spikes.push({
x: 950 + tp * 250,
y: groundLevel
});
}
} else {
// Spike walls
for (var sw = 0; sw < 4; sw++) {
for (var wall = 0; wall < 4; wall++) {
levelData[i].spikes.push({
x: 800 + sw * 400,
y: groundLevel - wall * 50
});
}
}
}
} else {
// Levels 36-50: Master difficulty
var masterPattern = (i - 35) % 8;
if (masterPattern === 0) {
// Ultimate ship challenge
levelData[i].shipMode = true;
for (var uc = 0; uc < 10; uc++) {
levelData[i].spikes.push({
x: 600 + uc * 180,
y: groundLevel
});
levelData[i].spikes.push({
x: 620 + uc * 180,
y: groundLevel - 100
});
levelData[i].spikes.push({
x: 640 + uc * 180,
y: groundLevel - 200
});
levelData[i].spikes.push({
x: 660 + uc * 180,
y: groundLevel - 300
});
// Add very challenging coins
if (uc % 3 === 0) {
levelData[i].coins.push({
x: 630 + uc * 180,
y: groundLevel - 150
});
}
}
} else if (masterPattern === 1) {
// Precision platform jumps
for (var pp = 0; pp < 8; pp++) {
levelData[i].platforms.push({
x: 700 + pp * 200,
y: groundLevel - 60 - pp % 3 * 40,
width: 60
});
levelData[i].spikes.push({
x: 730 + pp * 200,
y: groundLevel - 60 - pp % 3 * 40
});
}
} else if (masterPattern === 2) {
// Chaos mode - random but beatable
for (var ch = 0; ch < 12; ch++) {
if (ch % 3 === 0) {
levelData[i].platforms.push({
x: 600 + ch * 150,
y: groundLevel - 100,
width: 100
});
} else {
levelData[i].spikes.push({
x: 600 + ch * 150,
y: groundLevel
});
}
}
} else if (masterPattern === 3) {
// Double layer platforms
for (var dl = 0; dl < 5; dl++) {
levelData[i].platforms.push({
x: 700 + dl * 300,
y: groundLevel - 100,
width: 120
});
levelData[i].platforms.push({
x: 760 + dl * 300,
y: groundLevel - 180,
width: 120
});
levelData[i].spikes.push({
x: 820 + dl * 300,
y: groundLevel - 100
});
levelData[i].spikes.push({
x: 880 + dl * 300,
y: groundLevel - 180
});
}
} else if (masterPattern === 4) {
// Speed run spikes
for (var sr = 0; sr < 15; sr++) {
levelData[i].spikes.push({
x: 600 + sr * 120,
y: groundLevel
});
if (sr % 3 === 2) {
levelData[i].spikes.push({
x: 620 + sr * 120,
y: groundLevel
});
}
}
} else if (masterPattern === 5) {
// Alternating ship/cube sections
if (i % 2 === 0) {
levelData[i].shipMode = true;
}
for (var as = 0; as < 8; as++) {
levelData[i].spikes.push({
x: 700 + as * 200,
y: groundLevel
});
if (levelData[i].shipMode) {
levelData[i].spikes.push({
x: 720 + as * 200,
y: groundLevel - 200
});
}
}
} else if (masterPattern === 6) {
// Extreme precision
for (var ep = 0; ep < 6; ep++) {
levelData[i].platforms.push({
x: 700 + ep * 250,
y: groundLevel - 90,
width: 50
});
levelData[i].spikes.push({
x: 725 + ep * 250,
y: groundLevel - 90
});
levelData[i].spikes.push({
x: 750 + ep * 250,
y: groundLevel - 90
});
levelData[i].spikes.push({
x: 950 + ep * 250,
y: groundLevel
});
}
} else {
// Final boss level patterns
for (var fb = 0; fb < 5; fb++) {
// Complex multi-height obstacles
for (var h = 0; h < 4; h++) {
if ((fb + h) % 2 === 0) {
levelData[i].spikes.push({
x: 700 + fb * 300 + h * 40,
y: groundLevel - h * 60
});
} else {
levelData[i].platforms.push({
x: 700 + fb * 300 + h * 40,
y: groundLevel - h * 60,
width: 80
});
}
}
}
}
}
// Special level 51 pattern with starting swing
if (i === 51) {
// Start with a swing anchor at the beginning
levelData[i].swingAnchors.push({
x: 500,
y: groundLevel - 150
});
// Add platform to swing to
levelData[i].platforms.push({
x: 700,
y: groundLevel - 100,
width: 120
});
// Add spikes after platform
for (var s51 = 0; s51 < 5; s51++) {
levelData[i].spikes.push({
x: 900 + s51 * 200,
y: groundLevel
});
}
// Add more swing anchors throughout level
levelData[i].swingAnchors.push({
x: 1200,
y: groundLevel - 200
});
levelData[i].swingAnchors.push({
x: 1600,
y: groundLevel - 180
});
// Add challenging platform sequence
for (var p51 = 0; p51 < 4; p51++) {
levelData[i].platforms.push({
x: 1800 + p51 * 300,
y: groundLevel - 120 - p51 % 2 * 60,
width: 100
});
levelData[i].spikes.push({
x: 1850 + p51 * 300,
y: groundLevel - 120 - p51 % 2 * 60
});
}
}
// Levels 52-68: Next page ultra-hard levels
if (i >= 52 && i <= 68) {
var ultraPattern = (i - 52) % 17;
if (ultraPattern === 0) {
// Level 52: Moving spike walls
for (var msw = 0; msw < 6; msw++) {
for (var wall = 0; wall < 5; wall++) {
levelData[i].spikes.push({
x: 800 + msw * 350,
y: groundLevel - wall * 45
});
}
// Add narrow safe passage
levelData[i].platforms.push({
x: 950 + msw * 350,
y: groundLevel - 150,
width: 60
});
}
} else if (ultraPattern === 1) {
// Level 53: Ship tunnel nightmare
levelData[i].shipMode = true;
for (var stn = 0; stn < 12; stn++) {
levelData[i].spikes.push({
x: 700 + stn * 150,
y: groundLevel
});
levelData[i].spikes.push({
x: 725 + stn * 150,
y: groundLevel - 80
});
levelData[i].spikes.push({
x: 750 + stn * 150,
y: groundLevel - 160
});
levelData[i].spikes.push({
x: 775 + stn * 150,
y: groundLevel - 240
});
}
} else if (ultraPattern === 2) {
// Level 54: Triple layer platform maze
for (var tlm = 0; tlm < 5; tlm++) {
// Bottom layer
levelData[i].platforms.push({
x: 700 + tlm * 400,
y: groundLevel - 80,
width: 80
});
levelData[i].spikes.push({
x: 780 + tlm * 400,
y: groundLevel - 80
});
// Middle layer
levelData[i].platforms.push({
x: 850 + tlm * 400,
y: groundLevel - 160,
width: 80
});
levelData[i].spikes.push({
x: 930 + tlm * 400,
y: groundLevel - 160
});
// Top layer
levelData[i].platforms.push({
x: 1000 + tlm * 400,
y: groundLevel - 240,
width: 80
});
levelData[i].spikes.push({
x: 1080 + tlm * 400,
y: groundLevel - 240
});
}
} else if (ultraPattern === 3) {
// Level 55: Swing chain challenge
for (var scc = 0; scc < 8; scc++) {
levelData[i].swingAnchors.push({
x: 600 + scc * 250,
y: groundLevel - 200 - scc % 3 * 50
});
// Add spikes below each swing point
levelData[i].spikes.push({
x: 575 + scc * 250,
y: groundLevel
});
levelData[i].spikes.push({
x: 625 + scc * 250,
y: groundLevel
});
}
} else if (ultraPattern === 4) {
// Level 56: Rapid fire precision
for (var rfp = 0; rfp < 20; rfp++) {
levelData[i].spikes.push({
x: 600 + rfp * 80,
y: groundLevel
});
if (rfp % 4 === 3) {
levelData[i].spikes.push({
x: 620 + rfp * 80,
y: groundLevel
});
levelData[i].spikes.push({
x: 640 + rfp * 80,
y: groundLevel
});
}
}
} else if (ultraPattern === 5) {
// Level 57: Alternating cube/ship sections
for (var acs = 0; acs < 8; acs++) {
if (acs < 4) {
// Cube section
levelData[i].spikes.push({
x: 700 + acs * 200,
y: groundLevel
});
levelData[i].platforms.push({
x: 800 + acs * 200,
y: groundLevel - 100,
width: 100
});
} else {
// Ship section indicators (spikes arranged for ship mode)
levelData[i].spikes.push({
x: 700 + acs * 200,
y: groundLevel
});
levelData[i].spikes.push({
x: 720 + acs * 200,
y: groundLevel - 150
});
}
}
if (i % 2 === 1) {
levelData[i].shipMode = true;
}
} else if (ultraPattern === 6) {
// Level 58: Micro platforms
for (var mp = 0; mp < 10; mp++) {
levelData[i].platforms.push({
x: 700 + mp * 180,
y: groundLevel - 100 - mp % 4 * 30,
width: 40
});
levelData[i].spikes.push({
x: 740 + mp * 180,
y: groundLevel - 100 - mp % 4 * 30
});
levelData[i].spikes.push({
x: 880 + mp * 180,
y: groundLevel
});
}
} else if (ultraPattern === 7) {
// Level 59: Ceiling and floor spikes
levelData[i].shipMode = true;
for (var cfs = 0; cfs < 10; cfs++) {
levelData[i].spikes.push({
x: 700 + cfs * 150,
y: groundLevel
});
levelData[i].spikes.push({
x: 725 + cfs * 150,
y: groundLevel - 300
});
// Create narrow safe corridor
if (cfs % 3 === 1) {
levelData[i].coins.push({
x: 712 + cfs * 150,
y: groundLevel - 150
});
}
}
} else if (ultraPattern === 8) {
// Level 60: Swing through spike field
for (var stsf = 0; stsf < 6; stsf++) {
levelData[i].swingAnchors.push({
x: 700 + stsf * 300,
y: groundLevel - 250
});
// Dense spike field below
for (var sf = 0; sf < 5; sf++) {
levelData[i].spikes.push({
x: 600 + stsf * 300 + sf * 50,
y: groundLevel
});
levelData[i].spikes.push({
x: 625 + stsf * 300 + sf * 50,
y: groundLevel - 60
});
}
}
} else if (ultraPattern === 9) {
// Level 61: Stairway to hell
for (var sth = 0; sth < 8; sth++) {
var stairHeight = groundLevel - sth * 40;
levelData[i].platforms.push({
x: 700 + sth * 150,
y: stairHeight,
width: 70
});
levelData[i].spikes.push({
x: 770 + sth * 150,
y: stairHeight
});
levelData[i].spikes.push({
x: 850 + sth * 150,
y: groundLevel
});
}
} else if (ultraPattern === 10) {
// Level 62: Ship slalom
levelData[i].shipMode = true;
for (var ss = 0; ss < 15; ss++) {
var slalomY = groundLevel - 150 + Math.sin(ss * 0.8) * 100;
levelData[i].spikes.push({
x: 700 + ss * 120,
y: slalomY
});
levelData[i].spikes.push({
x: 720 + ss * 120,
y: slalomY + 50
});
}
} else if (ultraPattern === 11) {
// Level 63: Platform chains
for (var pc = 0; pc < 6; pc++) {
for (var chain = 0; chain < 4; chain++) {
levelData[i].platforms.push({
x: 700 + pc * 350 + chain * 70,
y: groundLevel - 80 - chain * 60,
width: 50
});
if (chain < 3) {
levelData[i].spikes.push({
x: 725 + pc * 350 + chain * 70,
y: groundLevel - 80 - chain * 60
});
}
}
}
} else if (ultraPattern === 12) {
// Level 64: Double swing challenge
for (var dsc = 0; dsc < 5; dsc++) {
levelData[i].swingAnchors.push({
x: 700 + dsc * 400,
y: groundLevel - 200
});
levelData[i].swingAnchors.push({
x: 900 + dsc * 400,
y: groundLevel - 180
});
// Spike barriers
for (var sb = 0; sb < 6; sb++) {
levelData[i].spikes.push({
x: 650 + dsc * 400 + sb * 40,
y: groundLevel
});
}
}
} else if (ultraPattern === 13) {
// Level 65: Speed demon
for (var sd = 0; sd < 25; sd++) {
levelData[i].spikes.push({
x: 600 + sd * 60,
y: groundLevel
});
if (sd % 5 === 2) {
levelData[i].spikes.push({
x: 615 + sd * 60,
y: groundLevel
});
levelData[i].spikes.push({
x: 630 + sd * 60,
y: groundLevel
});
}
}
} else if (ultraPattern === 14) {
// Level 66: Ship maze finale
levelData[i].shipMode = true;
for (var smf = 0; smf < 8; smf++) {
levelData[i].spikes.push({
x: 700 + smf * 200,
y: groundLevel
});
levelData[i].spikes.push({
x: 720 + smf * 200,
y: groundLevel - 80
});
levelData[i].spikes.push({
x: 740 + smf * 200,
y: groundLevel - 160
});
levelData[i].spikes.push({
x: 760 + smf * 200,
y: groundLevel - 240
});
levelData[i].spikes.push({
x: 780 + smf * 200,
y: groundLevel - 320
});
}
} else if (ultraPattern === 15) {
// Level 67: Ultimate precision test
for (var upt = 0; upt < 12; upt++) {
levelData[i].platforms.push({
x: 700 + upt * 150,
y: groundLevel - 80 - upt % 3 * 80,
width: 30
});
levelData[i].spikes.push({
x: 730 + upt * 150,
y: groundLevel - 80 - upt % 3 * 80
});
levelData[i].spikes.push({
x: 850 + upt * 150,
y: groundLevel
});
}
} else {
// Level 68: Final boss gauntlet
for (var fbg = 0; fbg < 6; fbg++) {
// Multi-height spike walls
for (var wall = 0; wall < 6; wall++) {
levelData[i].spikes.push({
x: 700 + fbg * 400,
y: groundLevel - wall * 50
});
}
// Narrow platform escape
levelData[i].platforms.push({
x: 750 + fbg * 400,
y: groundLevel - 200,
width: 40
});
// Swing anchor for advanced navigation
levelData[i].swingAnchors.push({
x: 850 + fbg * 400,
y: groundLevel - 300
});
// More spikes after swing
for (var afterSpike = 0; afterSpike < 4; afterSpike++) {
levelData[i].spikes.push({
x: 900 + fbg * 400 + afterSpike * 30,
y: groundLevel
});
}
}
}
}
// Add default coins if none were added yet
if (levelData[i].coins.length === 0) {
var coinCount = Math.max(2, Math.floor(i / 5) + 1);
for (var c = 0; c < coinCount; c++) {
levelData[i].coins.push({
x: 600 + c * (levelData[i].length / (coinCount + 1)),
y: groundLevel - 80 - c % 3 * 40
});
}
}
// Add checkpoints based on level length
var checkpointCount = Math.max(1, Math.floor(levelData[i].length / 800));
for (var k = 1; k <= checkpointCount; k++) {
levelData[i].checkpoints.push({
x: k * (levelData[i].length / (checkpointCount + 1)),
y: groundLevel
});
}
}
}
// UI Setup
function setupUI() {
// Score display
var scoreText = new Text2('Level: ' + currentLevel, {
size: 60,
fill: 0xFFFFFF
});
scoreText.anchor.set(0, 0);
scoreText.x = 120;
scoreText.y = 50;
LK.gui.topLeft.addChild(scoreText);
// Coin counter
var coinText = new Text2('Coins: ' + storage.totalCoins, {
size: 50,
fill: 0xFFD700
});
coinText.anchor.set(0, 0);
coinText.x = 120;
coinText.y = 120;
LK.gui.topLeft.addChild(coinText);
// Gem counter
var gemText = new Text2('Gems: ' + storage.totalGems, {
size: 50,
fill: 0xFF00FF
});
gemText.anchor.set(0, 0);
gemText.x = 120;
gemText.y = 190;
LK.gui.topLeft.addChild(gemText);
}
// Level selection menu
function showLevelMenu() {
gameState = 'menu';
game.removeChildren();
levelButtons = [];
// Title
var titleText = new Text2('Geometry Dash: 50 Levels', {
size: 80,
fill: 0xFFFFFF
});
titleText.anchor.set(0.5, 0);
titleText.x = 1024;
titleText.y = 200;
game.addChild(titleText);
// Create level buttons in grid
var buttonsPerRow = 5;
var buttonSpacing = 220;
var startX = 1024 - (buttonsPerRow - 1) * buttonSpacing / 2;
var startY = 480;
for (var i = 1; i <= maxLevels; i++) {
var row = Math.floor((i - 1) / buttonsPerRow);
var col = (i - 1) % buttonsPerRow;
var buttonX = startX + col * buttonSpacing;
var buttonY = startY + row * 150;
var levelBtn = game.addChild(new LevelButton(i, buttonX, buttonY));
levelButtons.push(levelBtn);
}
// Daily level button
var dailyButton = LK.getAsset('levelButton', {
anchorX: 0.5,
anchorY: 0.5
});
dailyButton.x = 1024;
dailyButton.y = startY + Math.ceil(maxLevels / buttonsPerRow) * 150 + 250;
dailyButton.tint = storage.dailyLevelCompleted ? 0x00ff00 : 0xff6600;
dailyButton.scaleX = 1.2;
dailyButton.scaleY = 1.2;
game.addChild(dailyButton);
var dailyText = new Text2('DAILY', {
size: 35,
fill: 0xFFFFFF
});
dailyText.anchor.set(0.5, 0.3);
dailyText.x = dailyButton.x;
dailyText.y = dailyButton.y;
game.addChild(dailyText);
var dailyCoinText = new Text2(storage.dailyLevelCoins + '/5', {
size: 25,
fill: 0xFFD700
});
dailyCoinText.anchor.set(0.5, 0.7);
dailyCoinText.x = dailyButton.x;
dailyCoinText.y = dailyButton.y;
game.addChild(dailyCoinText);
dailyButton.down = function (x, y, obj) {
currentLevel = 'daily';
showGameplay();
};
// Video button
var videoButton = LK.getAsset('levelButton', {
anchorX: 0.5,
anchorY: 0.5
});
videoButton.x = 1024;
videoButton.y = startY + Math.ceil(maxLevels / buttonsPerRow) * 150 + 400;
videoButton.tint = 0x9933ff;
game.addChild(videoButton);
var videoText = new Text2('Video', {
size: 40,
fill: 0xFFFFFF
});
videoText.anchor.set(0.5, 0.5);
videoText.x = videoButton.x;
videoText.y = videoButton.y;
game.addChild(videoText);
videoButton.down = function (x, y, obj) {
showVideoTutorial();
};
// Shop button
var shopButton = LK.getAsset('levelButton', {
anchorX: 0.5,
anchorY: 0.5
});
shopButton.x = 924;
shopButton.y = 300;
shopButton.tint = 0x00aaff;
game.addChild(shopButton);
var shopText = new Text2('Shop', {
size: 40,
fill: 0xFFFFFF
});
shopText.anchor.set(0.5, 0.5);
shopText.x = shopButton.x;
shopText.y = shopButton.y;
game.addChild(shopText);
shopButton.down = function (x, y, obj) {
showShop();
};
// Daily Shop button
var dailyShopButton = LK.getAsset('levelButton', {
anchorX: 0.5,
anchorY: 0.5
});
dailyShopButton.x = 1124;
dailyShopButton.y = 300;
dailyShopButton.tint = 0xff6600;
game.addChild(dailyShopButton);
var dailyShopText = new Text2('Daily Shop', {
size: 32,
fill: 0xFFFFFF
});
dailyShopText.anchor.set(0.5, 0.5);
dailyShopText.x = dailyShopButton.x;
dailyShopText.y = dailyShopButton.y;
game.addChild(dailyShopText);
dailyShopButton.down = function (x, y, obj) {
showDailyShop();
};
// Gem Shop button
var gemShopButton = LK.getAsset('levelButton', {
anchorX: 0.5,
anchorY: 0.5
});
gemShopButton.x = 724;
gemShopButton.y = 300;
gemShopButton.tint = 0xff00ff;
game.addChild(gemShopButton);
var gemShopText = new Text2('Gem Shop', {
size: 32,
fill: 0xFFFFFF
});
gemShopText.anchor.set(0.5, 0.5);
gemShopText.x = gemShopButton.x;
gemShopText.y = gemShopButton.y;
game.addChild(gemShopText);
gemShopButton.down = function (x, y, obj) {
showGemShop();
};
// Owner commands button (moved down)
var ownerButton = LK.getAsset('levelButton', {
anchorX: 0.5,
anchorY: 0.5
});
ownerButton.x = 1024;
ownerButton.y = 450;
ownerButton.tint = 0xffaa00;
game.addChild(ownerButton);
var ownerText = new Text2('Owner', {
size: 40,
fill: 0xFFFFFF
});
ownerText.anchor.set(0.5, 0.5);
ownerText.x = ownerButton.x;
ownerText.y = ownerButton.y;
game.addChild(ownerText);
ownerButton.down = function (x, y, obj) {
showOwnerCommands();
};
}
// Show gameplay
function showGameplay() {
gameState = 'playing';
game.removeChildren();
// Reset camera
cameraX = 0;
currentCheckpoint = 0;
deathCount = 0;
// Reset shield for new level
storage.shieldUsed = false;
// Create player
player = game.addChild(new Player());
player.x = playerStartX;
player.y = playerStartY;
// Set ship mode based on level data
if (levelData[currentLevel] && levelData[currentLevel].shipMode) {
player.setMode(true);
player.y = groundLevel - 200; // Start ship higher up
} else {
player.setMode(false);
}
// Load current level
loadLevel(currentLevel);
}
// Load level obstacles
function loadLevel(levelNum) {
obstacles = [];
platforms = [];
grounds = [];
checkpoints = [];
swingAnchors = [];
coins = [];
var level = levelData[levelNum];
if (!level) {
// If level data doesn't exist, create a basic level
level = {
spikes: [],
platforms: [],
checkpoints: [],
swingAnchors: [],
coins: [],
length: 3000,
shipMode: false
};
}
// Create ground segments
for (var x = 0; x <= level.length + 1000; x += 200) {
var ground = game.addChild(new Ground(x, groundLevel, 200));
grounds.push(ground);
}
// Create spikes
for (var i = 0; i < level.spikes.length; i++) {
var spikeData = level.spikes[i];
var spike = game.addChild(new Spike(spikeData.x, spikeData.y));
obstacles.push(spike);
}
// Create platforms
for (var j = 0; j < level.platforms.length; j++) {
var platformData = level.platforms[j];
var platform = game.addChild(new Platform(platformData.x, platformData.y, platformData.width));
platforms.push(platform);
}
// Create checkpoints
for (var k = 0; k < level.checkpoints.length; k++) {
var checkpointData = level.checkpoints[k];
var checkpoint = game.addChild(new Checkpoint(checkpointData.x, checkpointData.y));
checkpoints.push(checkpoint);
}
// Create swing anchors
for (var s = 0; s < level.swingAnchors.length; s++) {
var anchorData = level.swingAnchors[s];
var swingAnchor = game.addChild(new SwingAnchor(anchorData.x, anchorData.y));
swingAnchors.push(swingAnchor);
}
// Create coins
for (var c = 0; c < level.coins.length; c++) {
var coinData = level.coins[c];
var coin = game.addChild(new Coin(coinData.x, coinData.y));
coins.push(coin);
}
}
// Handle player death
function handlePlayerDeath() {
if (player.isDead || godModeEnabled) return;
// Check shield protection
if (storage.shield && !storage.shieldUsed) {
storage.shieldUsed = true;
LK.effects.flashScreen(0x00ffff, 300);
LK.effects.flashObject(player, 0x00ffff, 1000);
return; // Shield absorbs hit
}
player.isDead = true;
deathCount++;
LK.effects.flashScreen(0xff0000, 500);
LK.getSound('death').play();
// Respawn after delay
LK.setTimeout(function () {
respawnPlayer();
}, 1000);
}
// Respawn player at checkpoint
function respawnPlayer() {
player.isDead = false;
player.velocityY = 0;
player.isGrounded = false;
if (currentCheckpoint > 0 && checkpoints[currentCheckpoint - 1]) {
player.x = checkpoints[currentCheckpoint - 1].x;
cameraX = checkpoints[currentCheckpoint - 1].x - 400;
} else {
player.x = playerStartX;
cameraX = 0;
}
player.y = groundLevel;
}
// Handle level completion
function completeLevel() {
if (currentLevel === 'daily') {
storage.dailyLevelCompleted = true;
// Give 2 gems for daily level completion
storage.totalGems += 2;
} else {
storage.completedLevels[currentLevel] = true;
// Give 1 gem for regular level completion
storage.totalGems += 1;
}
LK.getSound('complete').play();
LK.effects.flashScreen(0x00ff00, 1000);
// Show completion message
var completeText = new Text2('Level Complete!', {
size: 100,
fill: 0x00FF00
});
completeText.anchor.set(0.5, 0.5);
completeText.x = 1024;
completeText.y = 1366;
game.addChild(completeText);
// Return to menu after delay
LK.setTimeout(function () {
showLevelMenu();
}, 2000);
}
// Input handling
game.down = function (x, y, obj) {
if (gameState === 'playing' && player && !player.isDead) {
player.jump();
}
};
game.up = function (x, y, obj) {
if (gameState === 'playing' && player && !player.isDead) {
player.stopJump();
}
};
// Main game loop
game.update = function () {
if (gameState !== 'playing' || !player || player.isDead) return;
// Auto-scroll camera with speed multiplier
var currentScrollSpeed = scrollSpeed * (storage.speedMultiplier || 1.0);
cameraX += currentScrollSpeed;
player.x += currentScrollSpeed;
// Update camera position
var targetCameraX = player.x - 400;
if (targetCameraX > cameraX) {
cameraX = targetCameraX;
}
// Position all game objects relative to camera
game.x = -cameraX;
// Check obstacle collisions
for (var i = 0; i < obstacles.length; i++) {
var obstacle = obstacles[i];
if (player.intersects(obstacle)) {
handlePlayerDeath();
break;
}
}
// Check platform collisions (simple top collision)
for (var j = 0; j < platforms.length; j++) {
var platform = platforms[j];
if (player.intersects(platform) && player.velocityY > 0) {
var playerBottom = player.y;
var platformTop = platform.y;
if (playerBottom >= platformTop && playerBottom <= platformTop + 20) {
player.y = platformTop;
player.velocityY = 0;
player.isGrounded = true;
}
}
}
// Check checkpoint activation
for (var k = 0; k < checkpoints.length; k++) {
var checkpoint = checkpoints[k];
if (!checkpoint.activated && player.intersects(checkpoint)) {
checkpoint.activated = true;
currentCheckpoint = k + 1;
LK.effects.flashObject(checkpoint, 0x00ffff, 500);
}
}
// Check swing anchor activation
for (var s = 0; s < swingAnchors.length; s++) {
var anchor = swingAnchors[s];
if (!anchor.isActive && !player.isSwinging && player.intersects(anchor)) {
var distance = Math.sqrt(Math.pow(player.x - anchor.x, 2) + Math.pow(player.y - anchor.y, 2));
if (distance < 80) {
// Activation range
anchor.activateSwing(player);
break;
}
}
}
// Check coin collection
for (var c = 0; c < coins.length; c++) {
var coin = coins[c];
// Coin magnet effect
if (!coin.collected && storage.coinMagnet) {
var coinDistance = Math.sqrt(Math.pow(player.x - coin.x, 2) + Math.pow(player.y - coin.y, 2));
if (coinDistance < 150) {
// Magnet range
// Move coin towards player
var magnetForce = 8;
var dirX = (player.x - coin.x) / coinDistance;
var dirY = (player.y - coin.y) / coinDistance;
coin.x += dirX * magnetForce;
coin.y += dirY * magnetForce;
}
}
if (!coin.collected && player.intersects(coin)) {
coin.collected = true;
coin.visible = false;
storage.totalCoins++;
// Update level-specific coin tracking
if (currentLevel === 'daily') {
storage.dailyLevelCoins++;
} else {
if (!storage.levelCoins[currentLevel]) {
storage.levelCoins[currentLevel] = 0;
}
storage.levelCoins[currentLevel]++;
}
// Play coin sound and visual effect
LK.getSound('coin').play();
LK.effects.flashObject(coin, 0xFFD700, 300);
// Update coin counter
var coinTexts = LK.gui.topLeft.children;
for (var t = 0; t < coinTexts.length; t++) {
if (coinTexts[t].text && coinTexts[t].text.indexOf('Coins:') === 0) {
coinTexts[t].setText('Coins: ' + storage.totalCoins);
break;
}
}
}
}
// Check level completion
var levelLength = levelData[currentLevel] ? levelData[currentLevel].length : 3000;
if (player.x >= levelLength) {
completeLevel();
}
// Check if player fell off screen
if (player.y > 2800) {
handlePlayerDeath();
}
// Update debug info
if (debugInfoVisible && debugText) {
var debugInfo = 'X: ' + Math.floor(player.x) + '\nY: ' + Math.floor(player.y) + '\nVelocity Y: ' + Math.floor(player.velocityY) + '\nCheckpoint: ' + currentCheckpoint + '\nDeaths: ' + deathCount + '\nGod Mode: ' + (godModeEnabled ? 'ON' : 'OFF') + '\nSpeed Boost: ' + (speedBoostEnabled ? 'ON' : 'OFF');
debugText.setText(debugInfo);
}
};
// Video tutorial screen
function showVideoTutorial() {
gameState = 'video';
game.removeChildren();
// Title
var titleText = new Text2('How to Beat Geometry Dash', {
size: 70,
fill: 0xFFFFFF
});
titleText.anchor.set(0.5, 0);
titleText.x = 1024;
titleText.y = 150;
game.addChild(titleText);
// Instructions sections
var instructions = ['BASIC CONTROLS:', 'β’ Tap/Click to jump in cube mode', 'β’ Hold to fly up in ship mode', 'β’ Release to fall down in ship mode', '', 'GAMEPLAY TIPS:', 'β’ Red spikes = deadly obstacles', 'β’ Gray platforms = safe to land on', 'β’ Cyan checkpoints = save your progress', 'β’ Green squares = completed levels', '', 'LEVEL PROGRESSION:', 'β’ Levels 1-10: Learn basic mechanics', 'β’ Levels 11-20: Master timing and ship mode', 'β’ Levels 21-35: Expert precision required', 'β’ Levels 36-50: Ultimate challenges', '', 'SURVIVAL STRATEGY:', 'β’ Practice timing on easier levels first', 'β’ Use checkpoints to avoid restarting', 'β’ Ship levels require smooth control', 'β’ Platform levels need precise jumps'];
var instructionY = 300;
var lineHeight = 45;
for (var i = 0; i < instructions.length; i++) {
var line = instructions[i];
var isHeader = line.endsWith(':');
var fontSize = isHeader ? 50 : 40;
var color = isHeader ? 0x00FF00 : 0xFFFFFF;
var instructionText = new Text2(line, {
size: fontSize,
fill: color
});
instructionText.anchor.set(0, 0);
instructionText.x = 200;
instructionY += line === '' ? lineHeight * 0.5 : lineHeight;
instructionText.y = instructionY;
game.addChild(instructionText);
}
// Demo visual elements
var demoY = 1800;
// Show cube example
var demoCube = LK.getAsset('player', {
anchorX: 0.5,
anchorY: 1.0
});
demoCube.x = 400;
demoCube.y = demoY;
game.addChild(demoCube);
var cubeLabel = new Text2('Cube Mode', {
size: 35,
fill: 0x00FF00
});
cubeLabel.anchor.set(0.5, 0);
cubeLabel.x = demoCube.x;
cubeLabel.y = demoY + 20;
game.addChild(cubeLabel);
// Show ship example
var demoShip = LK.getAsset('ship', {
anchorX: 0.5,
anchorY: 0.5
});
demoShip.x = 800;
demoShip.y = demoY - 30;
game.addChild(demoShip);
var shipLabel = new Text2('Ship Mode', {
size: 35,
fill: 0x0088FF
});
shipLabel.anchor.set(0.5, 0);
shipLabel.x = demoShip.x;
shipLabel.y = demoY + 20;
game.addChild(shipLabel);
// Show spike example
var demoSpike = LK.getAsset('spike', {
anchorX: 0.5,
anchorY: 1.0
});
demoSpike.x = 1200;
demoSpike.y = demoY;
game.addChild(demoSpike);
var spikeLabel = new Text2('Deadly Spike', {
size: 35,
fill: 0xFF0000
});
spikeLabel.anchor.set(0.5, 0);
spikeLabel.x = demoSpike.x;
spikeLabel.y = demoY + 20;
game.addChild(spikeLabel);
// Show platform example
var demoPlatform = LK.getAsset('platform', {
anchorX: 0,
anchorY: 0
});
demoPlatform.x = 1500;
demoPlatform.y = demoY - 40;
demoPlatform.width = 150;
game.addChild(demoPlatform);
var platformLabel = new Text2('Safe Platform', {
size: 35,
fill: 0x888888
});
platformLabel.anchor.set(0.5, 0);
platformLabel.x = demoPlatform.x + 75;
platformLabel.y = demoY + 20;
game.addChild(platformLabel);
// Animate demo elements
var animTime = 0;
var videoUpdateTimer = LK.setInterval(function () {
animTime += 0.1;
// Bounce cube
demoCube.y = demoY + Math.abs(Math.sin(animTime * 2)) * -30;
// Float ship
demoShip.y = demoY - 30 + Math.sin(animTime) * 15;
// Pulse spike
demoSpike.alpha = 0.7 + Math.sin(animTime * 3) * 0.3;
}, 50);
// Back button
var backButton = LK.getAsset('levelButton', {
anchorX: 0.5,
anchorY: 0.5
});
backButton.x = 1024;
backButton.y = 2400;
backButton.tint = 0x666666;
game.addChild(backButton);
var backText = new Text2('Back to Menu', {
size: 40,
fill: 0xFFFFFF
});
backText.anchor.set(0.5, 0.5);
backText.x = backButton.x;
backText.y = backButton.y;
game.addChild(backText);
backButton.down = function (x, y, obj) {
LK.clearInterval(videoUpdateTimer);
showLevelMenu();
};
}
// Shop screen
function showShop() {
gameState = 'shop';
game.removeChildren();
// Title
var titleText = new Text2('Geometry Dash Shop', {
size: 80,
fill: 0xFFFFFF
});
titleText.anchor.set(0.5, 0);
titleText.x = 1024;
titleText.y = 150;
game.addChild(titleText);
// Coin display
var coinDisplayText = new Text2('Coins: ' + storage.totalCoins, {
size: 60,
fill: 0xFFD700
});
coinDisplayText.anchor.set(0.5, 0);
coinDisplayText.x = 1024;
coinDisplayText.y = 250;
game.addChild(coinDisplayText);
// Shop items
var shopItems = [{
name: 'Red Player',
price: 100,
type: 'playerColor',
value: 0xff0000,
description: 'Change player color to red'
}, {
name: 'Blue Player',
price: 100,
type: 'playerColor',
value: 0x0000ff,
description: 'Change player color to blue'
}, {
name: 'Yellow Player',
price: 150,
type: 'playerColor',
value: 0xffff00,
description: 'Change player color to yellow'
}, {
name: 'Purple Player',
price: 150,
type: 'playerColor',
value: 0xff00ff,
description: 'Change player color to purple'
}, {
name: 'Orange Player',
price: 120,
type: 'playerColor',
value: 0xff8800,
description: 'Change player color to orange'
}, {
name: 'Cyan Player',
price: 120,
type: 'playerColor',
value: 0x00ffff,
description: 'Change player color to cyan'
}, {
name: 'Pink Player',
price: 180,
type: 'playerColor',
value: 0xff69b4,
description: 'Change player color to pink'
}, {
name: 'Red Ship',
price: 120,
type: 'shipColor',
value: 0xff0000,
description: 'Change ship color to red'
}, {
name: 'Green Ship',
price: 120,
type: 'shipColor',
value: 0x00ff00,
description: 'Change ship color to green'
}, {
name: 'Yellow Ship',
price: 180,
type: 'shipColor',
value: 0xffff00,
description: 'Change ship color to yellow'
}, {
name: 'Purple Ship',
price: 180,
type: 'shipColor',
value: 0xff00ff,
description: 'Change ship color to purple'
}, {
name: 'Orange Ship',
price: 160,
type: 'shipColor',
value: 0xff8800,
description: 'Change ship color to orange'
}, {
name: 'Speed Boost',
price: 300,
type: 'speedMultiplier',
value: 1.5,
description: 'Increase movement speed by 50%'
}, {
name: 'Super Speed',
price: 600,
type: 'speedMultiplier',
value: 2.0,
description: 'Double movement speed'
}, {
name: 'Coin Magnet',
price: 500,
type: 'coinMagnet',
value: true,
description: 'Automatically collect nearby coins'
}, {
name: 'Extra Checkpoint',
price: 250,
type: 'checkpoint',
value: true,
description: 'Add extra checkpoints in levels'
}, {
name: 'Jump Boost',
price: 400,
type: 'jumpBoost',
value: true,
description: 'Jump 25% higher in cube mode'
}, {
name: 'Shield Protection',
price: 800,
type: 'shield',
value: true,
description: 'Survive one spike hit per level'
}, {
name: 'Size Reduction',
price: 350,
type: 'smallSize',
value: true,
description: 'Make player 25% smaller'
}, {
name: 'Trail Effect',
price: 200,
type: 'trail',
value: true,
description: 'Leave a colorful trail behind'
}];
var itemY = 400;
var itemsPerRow = 2;
var itemSpacing = 400;
for (var i = 0; i < shopItems.length; i++) {
var item = shopItems[i];
var row = Math.floor(i / itemsPerRow);
var col = i % itemsPerRow;
var itemX = 1024 - (itemsPerRow - 1) * itemSpacing / 2 + col * itemSpacing;
var currentItemY = itemY + row * 200;
// Check if item is already purchased
var isPurchased = storage.shopPurchases[item.name] || false;
var canAfford = storage.totalCoins >= item.price;
// Item button
var itemButton = LK.getAsset('levelButton', {
anchorX: 0.5,
anchorY: 0.5
});
itemButton.x = itemX;
itemButton.y = currentItemY;
itemButton.scaleX = 1.8;
itemButton.scaleY = 1.2;
if (isPurchased) {
itemButton.tint = 0x00ff00; // Green for purchased
} else if (canAfford) {
itemButton.tint = 0x0088ff; // Blue for affordable
} else {
itemButton.tint = 0x666666; // Gray for too expensive
}
game.addChild(itemButton);
// Item name
var nameText = new Text2(item.name, {
size: 30,
fill: 0xFFFFFF
});
nameText.anchor.set(0.5, 0.5);
nameText.x = itemX;
nameText.y = currentItemY - 20;
game.addChild(nameText);
// Item price
var priceText = new Text2(isPurchased ? 'OWNED' : item.price + ' coins', {
size: 25,
fill: isPurchased ? 0x00ff00 : 0xFFD700
});
priceText.anchor.set(0.5, 0.5);
priceText.x = itemX;
priceText.y = currentItemY + 20;
game.addChild(priceText);
// Purchase logic
if (!isPurchased && canAfford) {
itemButton.shopItem = item;
itemButton.down = function (x, y, obj) {
var itemToPurchase = this.shopItem;
storage.totalCoins -= itemToPurchase.price;
storage.shopPurchases[itemToPurchase.name] = true;
storage[itemToPurchase.type] = itemToPurchase.value;
showShop(); // Refresh shop display
};
}
}
// Back button
var backButton = LK.getAsset('levelButton', {
anchorX: 0.5,
anchorY: 0.5
});
backButton.x = 1024;
backButton.y = itemY + Math.ceil(shopItems.length / itemsPerRow) * 200 + 100;
backButton.tint = 0x666666;
game.addChild(backButton);
var backText = new Text2('Back to Menu', {
size: 40,
fill: 0xFFFFFF
});
backText.anchor.set(0.5, 0.5);
backText.x = backButton.x;
backText.y = backButton.y;
game.addChild(backText);
backButton.down = function (x, y, obj) {
showLevelMenu();
};
}
// Generate daily shop items
function generateDailyShop() {
var today = new Date();
var dateString = today.getFullYear() + '-' + (today.getMonth() + 1) + '-' + today.getDate();
// Check if daily shop needs to be regenerated
if (storage.dailyShopDate !== dateString) {
storage.dailyShopDate = dateString;
storage.dailyShopPurchases = {};
// Generate daily shop using date as seed for consistency
var dayOfYear = Math.floor((today - new Date(today.getFullYear(), 0, 0)) / (1000 * 60 * 60 * 24));
var seed = dayOfYear + today.getFullYear() * 365;
// All possible shop items
var allItems = [{
name: 'Red Player',
originalPrice: 100,
type: 'playerColor',
value: 0xff0000,
description: 'Change player color to red'
}, {
name: 'Blue Player',
originalPrice: 100,
type: 'playerColor',
value: 0x0000ff,
description: 'Change player color to blue'
}, {
name: 'Yellow Player',
originalPrice: 150,
type: 'playerColor',
value: 0xffff00,
description: 'Change player color to yellow'
}, {
name: 'Purple Player',
originalPrice: 150,
type: 'playerColor',
value: 0xff00ff,
description: 'Change player color to purple'
}, {
name: 'Orange Player',
originalPrice: 120,
type: 'playerColor',
value: 0xff8800,
description: 'Change player color to orange'
}, {
name: 'Cyan Player',
originalPrice: 120,
type: 'playerColor',
value: 0x00ffff,
description: 'Change player color to cyan'
}, {
name: 'Pink Player',
originalPrice: 180,
type: 'playerColor',
value: 0xff69b4,
description: 'Change player color to pink'
}, {
name: 'Red Ship',
originalPrice: 120,
type: 'shipColor',
value: 0xff0000,
description: 'Change ship color to red'
}, {
name: 'Green Ship',
originalPrice: 120,
type: 'shipColor',
value: 0x00ff00,
description: 'Change ship color to green'
}, {
name: 'Yellow Ship',
originalPrice: 180,
type: 'shipColor',
value: 0xffff00,
description: 'Change ship color to yellow'
}, {
name: 'Purple Ship',
originalPrice: 180,
type: 'shipColor',
value: 0xff00ff,
description: 'Change ship color to purple'
}, {
name: 'Orange Ship',
originalPrice: 160,
type: 'shipColor',
value: 0xff8800,
description: 'Change ship color to orange'
}, {
name: 'Speed Boost',
originalPrice: 300,
type: 'speedMultiplier',
value: 1.5,
description: 'Increase movement speed by 50%'
}, {
name: 'Super Speed',
originalPrice: 600,
type: 'speedMultiplier',
value: 2.0,
description: 'Double movement speed'
}, {
name: 'Coin Magnet',
originalPrice: 500,
type: 'coinMagnet',
value: true,
description: 'Automatically collect nearby coins'
}, {
name: 'Extra Checkpoint',
originalPrice: 250,
type: 'checkpoint',
value: true,
description: 'Add extra checkpoints in levels'
}, {
name: 'Jump Boost',
originalPrice: 400,
type: 'jumpBoost',
value: true,
description: 'Jump 25% higher in cube mode'
}, {
name: 'Shield Protection',
originalPrice: 800,
type: 'shield',
value: true,
description: 'Survive one spike hit per level'
}, {
name: 'Size Reduction',
originalPrice: 350,
type: 'smallSize',
value: true,
description: 'Make player 25% smaller'
}, {
name: 'Trail Effect',
originalPrice: 200,
type: 'trail',
value: true,
description: 'Leave a colorful trail behind'
}];
// Initialize daily shop items if not exists
if (!storage.dailyShopItems) {
storage.dailyShopItems = [];
}
// Select 3 random items for daily shop
storage.dailyShopItems = [];
var usedIndices = [];
for (var i = 0; i < 3; i++) {
var randomIndex;
do {
randomIndex = (seed + i * 7) % allItems.length;
} while (usedIndices.indexOf(randomIndex) !== -1);
usedIndices.push(randomIndex);
var selectedItem = allItems[randomIndex];
// Apply random discount (20-50%)
var discount = 20 + (seed + i * 3) % 31;
var discountedPrice = Math.floor(selectedItem.originalPrice * (100 - discount) / 100);
storage.dailyShopItems.push({
name: selectedItem.name,
price: discountedPrice,
discount: discount,
type: selectedItem.type,
value: selectedItem.value,
description: selectedItem.description
});
}
}
}
// Daily shop screen
function showDailyShop() {
gameState = 'dailyShop';
game.removeChildren();
// Generate daily shop if needed
generateDailyShop();
// Title
var titleText = new Text2('Daily Shop', {
size: 80,
fill: 0xFFFFFF
});
titleText.anchor.set(0.5, 0);
titleText.x = 1024;
titleText.y = 150;
game.addChild(titleText);
// Date display
var today = new Date();
var dateString = today.getFullYear() + '-' + (today.getMonth() + 1) + '-' + today.getDate();
var dateText = new Text2('Date: ' + dateString, {
size: 50,
fill: 0x00FF00
});
dateText.anchor.set(0.5, 0);
dateText.x = 1024;
dateText.y = 250;
game.addChild(dateText);
// Coin display
var coinDisplayText = new Text2('Coins: ' + storage.totalCoins, {
size: 60,
fill: 0xFFD700
});
coinDisplayText.anchor.set(0.5, 0);
coinDisplayText.x = 1024;
coinDisplayText.y = 320;
game.addChild(coinDisplayText);
// Shop items
var itemY = 450;
for (var i = 0; i < storage.dailyShopItems.length; i++) {
var item = storage.dailyShopItems[i];
var currentItemY = itemY + i * 200;
// Check if item is already purchased
var isPurchased = storage.dailyShopPurchases[item.name] || false;
var canAfford = storage.totalCoins >= item.price;
// Item button
var itemButton = LK.getAsset('levelButton', {
anchorX: 0.5,
anchorY: 0.5
});
itemButton.x = 1024;
itemButton.y = currentItemY;
itemButton.scaleX = 2.5;
itemButton.scaleY = 1.2;
if (isPurchased) {
itemButton.tint = 0x00ff00; // Green for purchased
} else if (canAfford) {
itemButton.tint = 0xff6600; // Orange for daily special
} else {
itemButton.tint = 0x666666; // Gray for too expensive
}
game.addChild(itemButton);
// Item name
var nameText = new Text2(item.name, {
size: 35,
fill: 0xFFFFFF
});
nameText.anchor.set(0.5, 0.5);
nameText.x = 1024;
nameText.y = currentItemY - 25;
game.addChild(nameText);
// Item price and discount
var discountText = item.discount + '% OFF!';
var priceText = new Text2(isPurchased ? 'OWNED' : item.price + ' coins (' + discountText + ')', {
size: 28,
fill: isPurchased ? 0x00ff00 : 0xFFD700
});
priceText.anchor.set(0.5, 0.5);
priceText.x = 1024;
priceText.y = currentItemY + 10;
game.addChild(priceText);
// Description
var descText = new Text2(item.description, {
size: 24,
fill: 0xCCCCCC
});
descText.anchor.set(0.5, 0.5);
descText.x = 1024;
descText.y = currentItemY + 35;
game.addChild(descText);
// Purchase logic
if (!isPurchased && canAfford) {
itemButton.shopItem = item;
itemButton.down = function (x, y, obj) {
var itemToPurchase = this.shopItem;
storage.totalCoins -= itemToPurchase.price;
storage.dailyShopPurchases[itemToPurchase.name] = true;
storage[itemToPurchase.type] = itemToPurchase.value;
showDailyShop(); // Refresh shop display
};
}
}
// Back button
var backButton = LK.getAsset('levelButton', {
anchorX: 0.5,
anchorY: 0.5
});
backButton.x = 1024;
backButton.y = itemY + storage.dailyShopItems.length * 200 + 100;
backButton.tint = 0x666666;
game.addChild(backButton);
var backText = new Text2('Back to Menu', {
size: 40,
fill: 0xFFFFFF
});
backText.anchor.set(0.5, 0.5);
backText.x = backButton.x;
backText.y = backButton.y;
game.addChild(backText);
backButton.down = function (x, y, obj) {
showLevelMenu();
};
}
// Gem shop screen
function showGemShop() {
gameState = 'gemShop';
game.removeChildren();
// Title
var titleText = new Text2('Premium Gem Shop', {
size: 80,
fill: 0xFFFFFF
});
titleText.anchor.set(0.5, 0);
titleText.x = 1024;
titleText.y = 150;
game.addChild(titleText);
// Gem display
var gemDisplayText = new Text2('Gems: ' + storage.totalGems, {
size: 60,
fill: 0xFF00FF
});
gemDisplayText.anchor.set(0.5, 0);
gemDisplayText.x = 1024;
gemDisplayText.y = 250;
game.addChild(gemDisplayText);
// Premium shop items
var gemShopItems = [{
name: 'Rainbow Player',
price: 5,
type: 'playerColor',
value: 0x00ffff,
description: 'Exclusive rainbow-like cyan player'
}, {
name: 'Golden Player',
price: 8,
type: 'playerColor',
value: 0xffd700,
description: 'Luxurious golden player color'
}, {
name: 'Diamond Ship',
price: 10,
type: 'shipColor',
value: 0xb9f2ff,
description: 'Sparkling diamond ship'
}, {
name: 'Ruby Ship',
price: 8,
type: 'shipColor',
value: 0xe0115f,
description: 'Deep ruby red ship'
}, {
name: 'Ultra Speed',
price: 15,
type: 'speedMultiplier',
value: 3.0,
description: 'Triple movement speed'
}, {
name: 'Mega Jump',
price: 12,
type: 'jumpBoost',
value: true,
description: 'Jump 50% higher than normal'
}, {
name: 'Double Shield',
price: 20,
type: 'shield',
value: true,
description: 'Survive two spike hits per level'
}, {
name: 'Coin Multiplier x2',
price: 25,
type: 'coinMultiplier',
value: 2.0,
description: 'Double all coin rewards'
}, {
name: 'Ghost Mode',
price: 30,
type: 'ghostMode',
value: true,
description: 'Pass through spikes for 5 seconds'
}, {
name: 'Level Skip Token',
price: 50,
type: 'skipToken',
value: true,
description: 'Skip any level instantly'
}];
var itemY = 400;
var itemsPerRow = 2;
var itemSpacing = 400;
for (var i = 0; i < gemShopItems.length; i++) {
var item = gemShopItems[i];
var row = Math.floor(i / itemsPerRow);
var col = i % itemsPerRow;
var itemX = 1024 - (itemsPerRow - 1) * itemSpacing / 2 + col * itemSpacing;
var currentItemY = itemY + row * 200;
// Check if item is already purchased
var isPurchased = storage.gemShopPurchases[item.name] || false;
var canAfford = storage.totalGems >= item.price;
// Item button
var itemButton = LK.getAsset('levelButton', {
anchorX: 0.5,
anchorY: 0.5
});
itemButton.x = itemX;
itemButton.y = currentItemY;
itemButton.scaleX = 1.8;
itemButton.scaleY = 1.2;
if (isPurchased) {
itemButton.tint = 0x00ff00; // Green for purchased
} else if (canAfford) {
itemButton.tint = 0xff00ff; // Magenta for gem shop
} else {
itemButton.tint = 0x666666; // Gray for too expensive
}
game.addChild(itemButton);
// Item name
var nameText = new Text2(item.name, {
size: 30,
fill: 0xFFFFFF
});
nameText.anchor.set(0.5, 0.5);
nameText.x = itemX;
nameText.y = currentItemY - 20;
game.addChild(nameText);
// Item price
var priceText = new Text2(isPurchased ? 'OWNED' : item.price + ' gems', {
size: 25,
fill: isPurchased ? 0x00ff00 : 0xFF00FF
});
priceText.anchor.set(0.5, 0.5);
priceText.x = itemX;
priceText.y = currentItemY + 20;
game.addChild(priceText);
// Purchase logic
if (!isPurchased && canAfford) {
itemButton.shopItem = item;
itemButton.down = function (x, y, obj) {
var itemToPurchase = this.shopItem;
storage.totalGems -= itemToPurchase.price;
storage.gemShopPurchases[itemToPurchase.name] = true;
storage[itemToPurchase.type] = itemToPurchase.value;
showGemShop(); // Refresh shop display
};
}
}
// Back button
var backButton = LK.getAsset('levelButton', {
anchorX: 0.5,
anchorY: 0.5
});
backButton.x = 1024;
backButton.y = itemY + Math.ceil(gemShopItems.length / itemsPerRow) * 200 + 100;
backButton.tint = 0x666666;
game.addChild(backButton);
var backText = new Text2('Back to Menu', {
size: 40,
fill: 0xFFFFFF
});
backText.anchor.set(0.5, 0.5);
backText.x = backButton.x;
backText.y = backButton.y;
game.addChild(backText);
backButton.down = function (x, y, obj) {
showLevelMenu();
};
}
// Owner commands screen
function showOwnerCommands() {
gameState = 'owner';
game.removeChildren();
// Title
var titleText = new Text2('Owner Commands', {
size: 80,
fill: 0xFFFFFF
});
titleText.anchor.set(0.5, 0);
titleText.x = 1024;
titleText.y = 200;
game.addChild(titleText);
// Command buttons
// Initialize page tracking if not exists
if (!storage.ownerCommandsPage) {
storage.ownerCommandsPage = 1;
}
var allCommandButtons = [{
text: 'Unlock All Levels',
action: unlockAllLevels
}, {
text: 'Reset Progress',
action: resetProgress
}, {
text: 'Complete All Levels',
action: completeAllLevels
}, {
text: 'Give 1000 Coins',
action: giveCoins
}, {
text: 'Reset Coins',
action: resetCoins
}, {
text: 'Give 100 Gems',
action: giveGems
}, {
text: 'Reset Gems',
action: resetGems
}, {
text: 'Complete Daily Level',
action: completeDailyLevel
}, {
text: 'Reset Daily Level',
action: resetDailyLevel
}, {
text: 'Skip to Level 25',
action: skipToLevel25
}, {
text: 'Skip to Level 50',
action: skipToLevel50
}, {
text: 'God Mode On',
action: enableGodMode
}, {
text: 'God Mode Off',
action: disableGodMode
}, {
text: 'Speed Boost On',
action: enableSpeedBoost
}, {
text: 'Speed Boost Off',
action: disableSpeedBoost
}, {
text: 'Show Debug Info',
action: showDebugInfo
}, {
text: 'Clear Debug Info',
action: clearDebugInfo
}, {
text: 'Teleport to End',
action: teleportToEnd
}, {
text: 'Toggle Invincibility',
action: toggleInvincibility
}, {
text: 'Max All Shop Items',
action: maxAllShopItems
}, {
text: 'Reset Shop Purchases',
action: resetShopPurchases
}, {
text: 'Instant Level Complete',
action: instantLevelComplete
}, {
text: 'Unlock Daily Shop',
action: unlockDailyShop
}, {
text: 'Reset All Data',
action: resetAllData
}];
var commandsPerPage = 10;
var totalPages = Math.ceil(allCommandButtons.length / commandsPerPage);
var currentPage = storage.ownerCommandsPage || 1;
// Get commands for current page
var startIndex = (currentPage - 1) * commandsPerPage;
var endIndex = Math.min(startIndex + commandsPerPage, allCommandButtons.length);
var commandButtons = allCommandButtons.slice(startIndex, endIndex);
// Add navigation buttons
if (currentPage < totalPages) {
commandButtons.push({
text: 'Next Page (' + (currentPage + 1) + '/' + totalPages + ')',
action: function action() {
storage.ownerCommandsPage = currentPage + 1;
showOwnerCommands();
}
});
}
if (currentPage > 1) {
commandButtons.push({
text: 'Previous Page (' + (currentPage - 1) + '/' + totalPages + ')',
action: function action() {
storage.ownerCommandsPage = currentPage - 1;
showOwnerCommands();
}
});
}
// Add back to menu as last option
commandButtons.push({
text: 'Back to Menu',
action: showLevelMenu
});
var buttonY = 400;
for (var i = 0; i < commandButtons.length; i++) {
var cmdButton = LK.getAsset('levelButton', {
anchorX: 0.5,
anchorY: 0.5
});
cmdButton.x = 1024;
cmdButton.y = buttonY + i * 150;
cmdButton.tint = 0x444444;
game.addChild(cmdButton);
var cmdText = new Text2(commandButtons[i].text, {
size: 35,
fill: 0xFFFFFF
});
cmdText.anchor.set(0.5, 0.5);
cmdText.x = cmdButton.x;
cmdText.y = cmdButton.y;
game.addChild(cmdText);
cmdButton.commandAction = commandButtons[i].action;
cmdButton.down = function (x, y, obj) {
this.commandAction();
};
}
}
// Owner command functions
function unlockAllLevels() {
for (var i = 1; i <= maxLevels; i++) {
storage.completedLevels[i] = false; // Unlocked but not completed
}
showLevelMenu();
}
function resetProgress() {
storage.completedLevels = {};
storage.totalCoins = 0;
storage.levelCoins = {};
showLevelMenu();
}
function completeAllLevels() {
for (var i = 1; i <= maxLevels; i++) {
storage.completedLevels[i] = true;
}
showLevelMenu();
}
function giveCoins() {
storage.totalCoins += 1000;
showOwnerCommands();
}
function resetCoins() {
storage.totalCoins = 0;
storage.levelCoins = {};
showOwnerCommands();
}
function completeDailyLevel() {
storage.dailyLevelCompleted = true;
storage.dailyLevelCoins = 5;
showOwnerCommands();
}
function resetDailyLevel() {
storage.dailyLevelCompleted = false;
storage.dailyLevelCoins = 0;
showOwnerCommands();
}
function skipToLevel25() {
for (var i = 1; i <= 25; i++) {
storage.completedLevels[i] = true;
}
showLevelMenu();
}
function skipToLevel50() {
for (var i = 1; i <= 50; i++) {
storage.completedLevels[i] = true;
}
showLevelMenu();
}
function enableGodMode() {
godModeEnabled = true;
showOwnerCommands();
}
function disableGodMode() {
godModeEnabled = false;
showOwnerCommands();
}
function enableSpeedBoost() {
speedBoostEnabled = true;
scrollSpeed = 24; // Double speed
showOwnerCommands();
}
function disableSpeedBoost() {
speedBoostEnabled = false;
scrollSpeed = 12; // Normal speed
showOwnerCommands();
}
function showDebugInfo() {
debugInfoVisible = true;
if (!debugText) {
debugText = new Text2('Debug Info', {
size: 30,
fill: 0x00FF00
});
debugText.anchor.set(0, 0);
debugText.x = 120;
debugText.y = 180;
LK.gui.topLeft.addChild(debugText);
}
showOwnerCommands();
}
function clearDebugInfo() {
debugInfoVisible = false;
if (debugText) {
LK.gui.topLeft.removeChild(debugText);
debugText = null;
}
showOwnerCommands();
}
function giveGems() {
storage.totalGems += 100;
showOwnerCommands();
}
function resetGems() {
storage.totalGems = 0;
showOwnerCommands();
}
function teleportToEnd() {
if (gameState === 'playing' && player) {
var levelLength = levelData[currentLevel] ? levelData[currentLevel].length : 3000;
player.x = levelLength - 100;
cameraX = levelLength - 500;
}
showGameplay();
}
function toggleInvincibility() {
godModeEnabled = !godModeEnabled;
showOwnerCommands();
}
function maxAllShopItems() {
var allShopItemNames = ['Red Player', 'Blue Player', 'Yellow Player', 'Purple Player', 'Orange Player', 'Cyan Player', 'Pink Player', 'Red Ship', 'Green Ship', 'Yellow Ship', 'Purple Ship', 'Orange Ship', 'Speed Boost', 'Super Speed', 'Coin Magnet', 'Extra Checkpoint', 'Jump Boost', 'Shield Protection', 'Size Reduction', 'Trail Effect'];
for (var i = 0; i < allShopItemNames.length; i++) {
storage.shopPurchases[allShopItemNames[i]] = true;
}
// Apply all effects
storage.playerColor = 0xff69b4; // Pink
storage.shipColor = 0xffff00; // Yellow
storage.speedMultiplier = 2.0;
storage.coinMagnet = true;
storage.checkpoint = true;
storage.jumpBoost = true;
storage.shield = true;
storage.smallSize = true;
storage.trail = true;
showOwnerCommands();
}
function resetShopPurchases() {
storage.shopPurchases = {};
storage.dailyShopPurchases = {};
storage.gemShopPurchases = {};
// Reset to defaults
storage.playerColor = 0x00ff00;
storage.shipColor = 0x0088ff;
storage.speedMultiplier = 1.0;
storage.coinMagnet = false;
storage.checkpoint = false;
storage.jumpBoost = false;
storage.shield = false;
storage.smallSize = false;
storage.trail = false;
showOwnerCommands();
}
function instantLevelComplete() {
if (gameState === 'playing') {
completeLevel();
}
showOwnerCommands();
}
function unlockDailyShop() {
// Force regenerate daily shop with all items available
storage.dailyShopDate = '';
generateDailyShop();
showOwnerCommands();
}
function resetAllData() {
storage.completedLevels = {};
storage.totalCoins = 0;
storage.levelCoins = {};
storage.totalGems = 0;
storage.shopPurchases = {};
storage.dailyShopPurchases = {};
storage.gemShopPurchases = {};
storage.dailyLevelCompleted = false;
storage.dailyLevelCoins = 0;
storage.ownerCommandsPage = 1;
// Reset to defaults
storage.playerColor = 0x00ff00;
storage.shipColor = 0x0088ff;
storage.speedMultiplier = 1.0;
storage.coinMagnet = false;
storage.checkpoint = false;
storage.jumpBoost = false;
storage.shield = false;
storage.smallSize = false;
storage.trail = false;
showLevelMenu();
}
// Initialize game
initializeLevelData();
setupUI();
showLevelMenu();