Code edit (1 edits merged)
Please save this source code
User prompt
Please fix the bug: 'Uncaught ReferenceError: createAchievementsMenu is not defined' in or related to this line: 'createAchievementsMenu();' Line Number: 1650
User prompt
Please fix the bug: 'Uncaught TypeError: Cannot read properties of undefined (reading 'elapsed')' in or related to this line: 'var currentTime = LK.time.elapsed;' Line Number: 407
User prompt
Please fix the bug: 'TypeError: game.sortChildren is not a function' in or related to this line: 'game.sortChildren();' Line Number: 541
Code edit (2 edits merged)
Please save this source code
User prompt
Please fix the bug: 'Uncaught TypeError: Cannot read properties of undefined (reading 'elapsed')' in or related to this line: 'var currentTime = LK.time.elapsed;' Line Number: 383
Code edit (4 edits merged)
Please save this source code
User prompt
Move the cancel button on upgrade menu 50 pixels right and 50 pixels up
User prompt
set the opacity of the "rectangle" asset to 90%
User prompt
make rectangle asset opacity 75%
Code edit (1 edits merged)
Please save this source code
User prompt
add these sounds /**** * SOUND INITIALIZATION ****/ LK.init.sound('mine_coal', { volume:0.5 }); LK.init.sound('mine_iron', { volume:0.5 }); LK.init.sound('mine_gold', { volume:0.5 }); LK.init.sound('mine_diamond', { volume:0.5 }); LK.init.sound('mine_sapphire', { volume:0.5 }); LK.init.sound('mine_emerald', { volume:0.5 }); LK.init.sound('mine_ruby', { volume:0.5 }); LK.init.sound('mine_chronostone', { volume:0.5 }); LK.init.sound('mine_soulember', { volume:0.5 }); LK.init.sound('mine_quantumshard', { volume:0.5 }); LK.init.sound('drone_shot', { volume:0.5 }); LK.init.sound('ore_destroy_coal', { volume:0.7 }); LK.init.sound('ore_destroy_iron', { volume:0.7 }); LK.init.sound('ore_destroy_gold', { volume:0.7 }); LK.init.sound('ore_destroy_diamond', { volume:0.7 }); LK.init.sound('ore_destroy_sapphire', { volume:0.7 }); LK.init.sound('ore_destroy_emerald', { volume:0.7 }); LK.init.sound('ore_destroy_ruby', { volume:0.7 }); LK.init.sound('ore_destroy_chronostone', { volume:0.7 }); LK.init.sound('ore_destroy_soulember', { volume:0.7 }); LK.init.sound('ore_destroy_quantumshard', { volume:0.7 });
Code edit (3 edits merged)
Please save this source code
User prompt
add these sounds /**** * SOUND INITIALIZATION ****/ LK.init.sound('mine_coal', { volume:0.5 }); LK.init.sound('mine_iron', { volume:0.5 }); LK.init.sound('mine_gold', { volume:0.5 }); LK.init.sound('mine_diamond', { volume:0.5 }); LK.init.sound('mine_sapphire', { volume:0.5 }); LK.init.sound('mine_emerald', { volume:0.5 }); LK.init.sound('mine_ruby', { volume:0.5 }); LK.init.sound('mine_chronostone', { volume:0.5 }); LK.init.sound('mine_soulember', { volume:0.5 }); LK.init.sound('mine_quantumshard', { volume:0.5 }); LK.init.sound('drone_shot', { volume:0.5 }); LK.init.sound('ore_destroy_coal', { volume:0.7 }); LK.init.sound('ore_destroy_iron', { volume:0.7 }); LK.init.sound('ore_destroy_gold', { volume:0.7 }); LK.init.sound('ore_destroy_diamond', { volume:0.7 }); LK.init.sound('ore_destroy_sapphire', { volume:0.7 }); LK.init.sound('ore_destroy_emerald', { volume:0.7 }); LK.init.sound('ore_destroy_ruby', { volume:0.7 }); LK.init.sound('ore_destroy_chronostone', { volume:0.7 }); LK.init.sound('ore_destroy_soulember', { volume:0.7 }); LK.init.sound('ore_destroy_quantumshard', { volume:0.7 });
User prompt
Add these sound assets: /**** * SOUND INITIALIZATION ****/ LK.init.sound('mine_coal', { volume:0.5 }); LK.init.sound('mine_iron', { volume:0.5 }); LK.init.sound('mine_gold', { volume:0.5 }); LK.init.sound('mine_diamond', { volume:0.5 }); LK.init.sound('mine_sapphire', { volume:0.5 }); LK.init.sound('mine_emerald', { volume:0.5 }); LK.init.sound('mine_ruby', { volume:0.5 }); LK.init.sound('mine_chronostone', { volume:0.5 }); LK.init.sound('mine_soulember', { volume:0.5 }); LK.init.sound('mine_quantumshard', { volume:0.5 }); LK.init.sound('drone_shot', { volume:0.5 }); LK.init.sound('ore_destroy_coal', { volume:0.7 }); LK.init.sound('ore_destroy_iron', { volume:0.7 }); LK.init.sound('ore_destroy_gold', { volume:0.7 }); LK.init.sound('ore_destroy_diamond', { volume:0.7 }); LK.init.sound('ore_destroy_sapphire', { volume:0.7 }); LK.init.sound('ore_destroy_emerald', { volume:0.7 }); LK.init.sound('ore_destroy_ruby', { volume:0.7 }); LK.init.sound('ore_destroy_chronostone', { volume:0.7 }); LK.init.sound('ore_destroy_soulember', { volume:0.7 }); LK.init.sound('ore_destroy_quantumshard', { volume:0.7 });
User prompt
Please fix the bug: 'Uncaught ReferenceError: hideUpgradeDesc is not defined' in or related to this line: 'hideUpgradeDesc();' Line Number: 1492
Code edit (1 edits merged)
Please save this source code
User prompt
Please fix the bug: 'Uncaught ReferenceError: canPrestige is not defined' in or related to this line: 'if (canPrestige()) {' Line Number: 1212
User prompt
Please fix the bug: 'Uncaught ReferenceError: canPrestige is not defined' in or related to this line: 'if (canPrestige()) {' Line Number: 1230
Code edit (2 edits merged)
Please save this source code
User prompt
Please fix the bug: 'initialSpawn is not defined' in or related to this line: 'initialSpawn();' Line Number: 778
User prompt
Please fix the bug: 'ReferenceError: quantumSelectionActive is not defined' in or related to this line: 'if (quantumSelectionActive) {' Line Number: 746
User prompt
Please fix the bug: 'ReferenceError: upgradeMenu is not defined' in or related to this line: 'if (upgradeMenu.parent) {' Line Number: 733
User prompt
Please fix the bug: 'ReferenceError: droneObjects is not defined' in or related to this line: 'for (var i = 0; i < droneObjects.length; i++) {' Line Number: 715
User prompt
Please fix the bug: 'ReferenceError: clusters is not defined' in or related to this line: 'clusters.forEach(function (c) {' Line Number: 167
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ /**** * Prestige and Background Helpers **** // New prestige requirement: 1e9, 2e9, 4e9, etc. function getPrestigeRequirement() { return 1e9 * Math.pow(2, gameState.prestigeCount); } function canPrestige() { return gameState.money >= getPrestigeRequirement(); } function calculatePrestigeShards() { // For now, simply give 1 shard per prestige. return 1; } function doPrestige() { // Clear clusters for (var i = clusters.length - 1; i >= 0; i--) { var c = clusters[i]; c.removeChildren(); if (c.parent) { c.parent.removeChild(c); } clusters.splice(i, 1); } var shards = calculatePrestigeShards(); gameState.prestigeCurrency += shards; gameState.prestigeCount++; gameState.money = 0; gameState.currentTier = 1; for (var key in gameState.clusterCount) { gameState.clusterCount[key] = 0; } handleBackgroundTransition(); initialSpawn(); updateUI(); } function handleBackgroundTransition() { if (nextBackground && nextBackground.parent) { nextBackground.parent.removeChild(nextBackground); } var newBg = null; if (gameState.prestigeCount >= 8) { newBg = LK.getAsset('background_tier8', { anchorX: 0.5, anchorY: 0.5 }); } else if (gameState.prestigeCount >= 5) { newBg = LK.getAsset('background_tier5', { anchorX: 0.5, anchorY: 0.5 }); } else if (gameState.prestigeCount >= 3) { newBg = LK.getAsset('background_tier3', { anchorX: 0.5, anchorY: 0.5 }); } else { newBg = LK.getAsset('background', { anchorX: 0.5, anchorY: 0.5 }); } newBg.x = 2048 / 2; newBg.y = 2732 + 2732 / 2; // Add new background at index 0 so all UI elements remain on top game.addChildAt(newBg, 0); nextBackground = newBg; var oldBg = currentBackground; if (!oldBg) { oldBg = LK.getAsset('background', { anchorX: 0.5, anchorY: 0.5 }); oldBg.x = 2048 / 2; oldBg.y = 2732 / 2; game.addChildAt(oldBg, 0); } if (oldBg === newBg) { currentBackground = newBg; return; } var dur = 3000; tween(oldBg, { y: oldBg.y - 2732 }, { duration: dur, onFinish: function () { if (oldBg && oldBg.parent) { oldBg.parent.removeChild(oldBg); } } }); tween(newBg, { y: 2732 / 2 }, { duration: dur, onFinish: function () { currentBackground = newBg; } }); } /**** * CLASSES ****/ /** * Cluster – spawns multiple ore objects of a given type. */ var Cluster = Container.expand(function (type) { var self = Container.call(this); self.type = type; self.oreList = []; var centerX = 100 + Math.random() * (2048 - 200); var centerY = 100 + Math.random() * (2732 - 200); self.x = centerX; self.y = centerY; var cc = gameState.clusterConfig; var count = randomInt(cc.min, cc.max); for (var i = 0; i < count; i++) { var ore = new Ore(type, self); ore.x = (Math.random() - 0.5) * 120; ore.y = (Math.random() - 0.5) * 120; self.oreList.push(ore); self.addChild(ore); } self.notifyOreDestroyed = function (ore) { var idx = self.oreList.indexOf(ore); if (idx >= 0) { self.oreList.splice(idx, 1); } ore.destroy(); if (self.oreList.length === 0) { if (self.parent) { self.parent.removeChild(self); } var cidx = clusters.indexOf(self); if (cidx >= 0) { clusters.splice(cidx, 1); } gameState.clusterCount[type]--; var finalDelay = gameState.respawnTime; if (type === 'coal') { finalDelay *= 2; } LK.setTimeout(function () { maybeSpawnCluster(type); }, finalDelay); } }; return self; }); /** * Drone – moves around and zaps nearby ores (with slight random deviations). */ var Drone = Container.expand(function () { var self = Container.call(this); self.droneSprite = LK.getAsset('drone_asset', { anchorX: 0.5, anchorY: 0.5 }); self.addChild(self.droneSprite); var SPEED = 8, MIN_X = 50, MAX_X = 2000, MIN_Y = 50, MAX_Y = 2682; self.vx = Math.random() < 0.5 ? SPEED : -SPEED; self.vy = Math.random() < 0.5 ? SPEED : -SPEED; self.AOE_RANGE = 100; self.droneDamage = 2; self.COOLDOWN_MAX = 60; self.cooldown = 0; self.updateDrone = function () { self.x += self.vx; self.y += self.vy; if (self.x < MIN_X || self.x > MAX_X) { self.vx = -self.vx; } if (self.y < MIN_Y || self.y > MAX_Y) { self.vy = -self.vy; } if (Math.random() < 0.01) { self.vx += (Math.random() - 0.5) * 2; self.vy += (Math.random() - 0.5) * 2; var speed = Math.sqrt(self.vx * self.vx + self.vy * self.vy); if (speed > SPEED) { self.vx = self.vx / speed * SPEED; self.vy = self.vy / speed * SPEED; } } if (self.cooldown > 0) { self.cooldown--; } else { self.tryZap(); } }; self.tryZap = function () { var hitSomething = false; clusters.forEach(function (cluster) { cluster.oreList.forEach(function (ore) { if (ore.health > 0) { var oreGlobalX = cluster.x + ore.x; var oreGlobalY = cluster.y + ore.y; var dx = self.x - oreGlobalX, dy = self.y - oreGlobalY; var dist = Math.sqrt(dx * dx + dy * dy); if (dist < self.AOE_RANGE) { ore.health -= self.droneDamage; hitSomething = true; if (ore.health <= 0) { var baseValue = ore.getValue(); gameState.money += baseValue; updateUI(); ore.cluster.notifyOreDestroyed(ore); spawnMiningParticles(ore, 5); } } } }); }); if (hitSomething) { // Play drone shot sound once per zap LK.getSound('drone_shot').play(); self.cooldown = self.COOLDOWN_MAX; } }; return self; }); /** * Miner – moves toward and mines the nearest ore. * Includes Chronostone, Soul Ember, Quantum Shard, and the new Hyper Mining Mode. */ var Miner = Container.expand(function () { var self = Container.call(this); self.attachAsset('miner', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 5; self.currentTarget = null; self.miningRange = 25; self.miningCooldown = 0; self.miningRate = 30; self.miningDamage = 1; // Save originals for hyper mode self.originalMiningRate = self.miningRate; self.originalMiningDamage = self.miningDamage; // Chronostone boost self.speedBoostMultiplier = 1; self.speedBoostTimer = 0; // Soul Ember boost self.soulEmberStacks = 0; // Quantum Shard mode self.quantumPathActive = false; self.quantumPath = []; self.quantumShardValueBonus = false; // New Hyper Mining Mode self.hyperMiningActive = false; self.hyperMiningTimer = 0; self.activateHyperMining = function () { self.hyperMiningActive = true; self.hyperMiningTimer = 10 * 60; self.miningDamage *= 2; self.miningRate = Math.max(1, Math.floor(self.miningRate / 2)); }; self.findNewTarget = function () { if (self.quantumPathActive && self.quantumPath.length > 0) { self.currentTarget = self.quantumPath[0]; if (!self.currentTarget || self.currentTarget.health <= 0) { self.quantumPath.shift(); if (self.quantumPath.length === 0) { if (self.quantumShardValueBonus) { self.quantumShardValueBonus = false; } self.quantumPathActive = false; self.currentTarget = null; } return; } return; } var validOre = []; clusters.forEach(function (c) { c.oreList.forEach(function (ore) { if (ore.health > 0 && ore.tier <= gameState.currentTier) { validOre.push(ore); } }); }); if (validOre.length === 0) { self.currentTarget = null; return; } self.currentTarget = validOre.sort(function (a, b) { var aX = a.parent.x + a.x, aY = a.parent.y + a.y; var bX = b.parent.x + b.x, bY = b.parent.y + b.y; return Math.hypot(aX - self.x, aY - self.y) - Math.hypot(bX - self.x, bY - self.y); })[0]; }; self.update = function () { if (self.hyperMiningActive) { self.hyperMiningTimer--; if (self.hyperMiningTimer <= 0) { self.miningDamage = self.originalMiningDamage; self.miningRate = self.originalMiningRate; self.hyperMiningActive = false; } } if (self.speedBoostTimer > 0) { self.speedBoostTimer--; if (self.speedBoostTimer <= 0) { self.speedBoostMultiplier = 1; } } self.findNewTarget(); if (self.currentTarget) { var tx = self.currentTarget.parent.x + self.currentTarget.x; var ty = self.currentTarget.parent.y + self.currentTarget.y; var dx = tx - self.x, dy = ty - self.y; var dist = Math.sqrt(dx * dx + dy * dy); var finalSpeed = self.speed * self.speedBoostMultiplier; if (dist > self.miningRange) { self.x += dx / dist * finalSpeed; self.y += dy / dist * finalSpeed; } else { self.mineOre(self.currentTarget); } } else { if (typeof LK.time !== 'undefined') { self.y += Math.sin(LK.time.elapsed / 250) * 0.5; } } }; self.mineOre = function (ore) { if (self.miningCooldown > 0) { self.miningCooldown--; return; } if (self.quantumPathActive && self.quantumPath.length > 0 && self.quantumPath[0] === ore) { self.quantumPath.shift(); if (self.quantumPath.length === 0) { self.quantumPathActive = false; } } var damageDealt = self.miningDamage * gameState.pickaxeLevel * (gameState.pickaxeBaseMultiplier || 1); ore.health -= damageDealt; self.miningCooldown = self.miningRate; // Play mining sound for this ore type var mineSound = LK.getSound('mine_' + ore.type); if (mineSound) { mineSound.play(); } if (ore.health <= 0) { var baseValue = ore.getValue(); var finalValue = baseValue; if (self.soulEmberStacks > 0) { finalValue *= 5; self.soulEmberStacks--; } if (self.quantumShardValueBonus) { finalValue *= 1.5; } gameState.money += finalValue; updateUI(); ore.cluster.notifyOreDestroyed(ore); spawnMiningParticles(ore, 5); // Play ore-destroy sound var destroySound = LK.getSound('ore_destroy_' + ore.type); if (destroySound) { destroySound.play(); } if (ore.type === "explosive" && ore.explode) { ore.explode(); } } else { spawnMiningParticles(ore, 2); } }; // Boost functions self.applyChronostoneBoost = function () { self.speedBoostMultiplier *= 3; self.speedBoostTimer = 30 * 60; }; self.applySoulEmberBoost = function () { if (gameState.money >= 1e6) { var drain = gameState.money * 0.10; gameState.money -= drain; self.soulEmberStacks = 10; updateUI(); } }; self.triggerQuantumShardMode = function () { self.quantumShardValueBonus = true; self.quantumPathActive = true; self.quantumPath = []; game.pauseForQuantumSelection(); }; return self; }); /** * Ore – represents a single ore. * Includes a health bar, pulsing glow for special ores, and explosive behavior. */ var Ore = Container.expand(function (type, cluster) { var self = Container.call(this); self.type = type; self.cluster = cluster; var typeList = ['coal', 'iron', 'gold', 'diamond', 'sapphire', 'emerald', 'ruby']; if (typeList.indexOf(type) >= 0) { self.tier = typeList.indexOf(type) + 1; } else { self.tier = 999; } self.baseValue = oreData[type].baseValue; self.maxHealth = oreData[type].baseHealth; self.health = self.maxHealth; self.attachAsset(oreData[type].assetId, { anchorX: 0.5, anchorY: 0.5 }); self.healthBar = LK.getAsset('rectangle', { width: 120, height: 20, fill: 0x00FF00, anchorX: 0.5, anchorY: 0.5 }); self.healthBar.x = 0; self.healthBar.y = -70; self.addChild(self.healthBar); if (["chronostone", "soulember", "quantumshard"].indexOf(type) >= 0) { var _pulseGlow = function pulseGlow() { tween(glow, { alpha: 1 }, { duration: 1000, onFinish: function onFinish() { tween(glow, { alpha: 0.5 }, { duration: 1000, onFinish: _pulseGlow }); } }); }; var glow = LK.getAsset('glowing_line_asset', { anchorX: 0.5, anchorY: 0.5 }); glow.alpha = 0.5; self.addChildAt(glow, 0); _pulseGlow(); } if (type === "explosive") { self.explode = function () { var explosionRadius = 100; clusters.forEach(function (cluster) { cluster.oreList.forEach(function (otherOre) { if (otherOre !== self && otherOre.health > 0) { var oreGlobalX = cluster.x + otherOre.x; var oreGlobalY = cluster.y + otherOre.y; var dx = self.parent.x + self.x - oreGlobalX; var dy = self.parent.y + self.y - oreGlobalY; var dist = Math.sqrt(dx * dx + dy * dy); if (dist < explosionRadius) { otherOre.health -= 50; if (otherOre.health <= 0) { var baseValue = otherOre.getValue(); gameState.money += baseValue; updateUI(); otherOre.cluster.notifyOreDestroyed(otherOre); spawnMiningParticles(otherOre, 5); } else { spawnMiningParticles(otherOre, 2); } } } }); }); screenShake(500, 10); }; } self.getValue = function () { return self.baseValue * gameState.oreMultipliers[self.type]; }; return self; }); /**** * Initialize Game ****/ /**** * GAME INITIALIZATION AND HELPER FUNCTIONS ****/ var game = new LK.Game({ backgroundColor: 0x1a1a1a }); /**** * Game Code ****/ // Returns a random integer between min and max (inclusive) /**** * HELPER FUNCTIONS ****/ /**** * PLUGINS ****/ /**** * SOUND INITIALIZATION ****/ // Shapes and Images /**** * ASSETS ****/ function randomInt(min, max) { return Math.floor(Math.random() * (max - min + 1)) + min; } // Enhanced mining particles – tint special ores if needed function spawnMiningParticles(ore, num) { for (var i = 0; i < num; i++) { var p = LK.getAsset('mining_particle', { anchorX: 0.5, anchorY: 0.5 }); if (ore.parent) { p.x = ore.parent.x + ore.x; p.y = ore.parent.y + ore.y; } else { p.x = ore.x; p.y = ore.y; } if (["chronostone", "soulember", "quantumshard"].indexOf(ore.type) >= 0) { p.tint = oreData[ore.type].color || 0xffffff; } p.vx = (Math.random() - 0.5) * 10; p.vy = (Math.random() - 0.5) * 10; p.alpha = 1; tween(p, { alpha: 0, y: p.y - 50 }, { duration: 1000, onFinish: function onFinish() { p.destroy(); } }); game.addChild(p); } } // Interpolates between two colors (used for health bars) function interpolateColor(c1, c2, f) { var r1 = c1 >> 16 & 0xFF, g1 = c1 >> 8 & 0xFF, b1 = c1 & 0xFF; var r2 = c2 >> 16 & 0xFF, g2 = c2 >> 8 & 0xFF, b2 = c2 & 0xFF; var r = Math.round(r1 + f * (r2 - r1)); var g = Math.round(g1 + f * (g2 - g1)); var b = Math.round(b1 + f * (b2 - b1)); return r << 16 | g << 8 | b; } // Simple screen shake for explosions function screenShake(duration, magnitude) { var originalX = game.x, originalY = game.y; var shakeInterval = 50; var elapsed = 0; var shake = setInterval(function () { elapsed += shakeInterval; game.x = originalX + (Math.random() - 0.5) * magnitude; game.y = originalY + (Math.random() - 0.5) * magnitude; if (elapsed >= duration) { clearInterval(shake); game.x = originalX; game.y = originalY; } }, shakeInterval); } /**** * ACHIEVEMENT SYSTEM ****/ var achievements = [{ id: 'first_mine', name: 'First Mine', description: 'Mine your first ore', achieved: false, condition: function condition() { return gameState.money > 0; } }, { id: 'rich_miner', name: 'Rich Miner', description: 'Earn 1 Billion money', achieved: false, condition: function condition() { return gameState.money >= 1e9; } }]; /**** * ORE DATA ****/ var oreData = { coal: { baseValue: 5, baseHealth: 10, assetId: 'coal_ore' }, iron: { baseValue: 500, baseHealth: 100, assetId: 'iron_ore' }, gold: { baseValue: 10000, baseHealth: 500, assetId: 'gold_ore' }, diamond: { baseValue: 25000, baseHealth: 1000, assetId: 'diamond_ore' }, sapphire: { baseValue: 100000, baseHealth: 2000, assetId: 'sapphire_ore' }, emerald: { baseValue: 500000, baseHealth: 5000, assetId: 'emerald_ore' }, ruby: { baseValue: 1000000, baseHealth: 10000, assetId: 'ruby_ore' }, chronostone: { baseValue: 2000000, baseHealth: 2000, assetId: 'chronostone_ore', color: 0xc997d8 }, soulember: { baseValue: 5000000, baseHealth: 5000, assetId: 'soulember_ore', color: 0xdef3e5 }, quantumshard: { baseValue: 10000000, baseHealth: 10000, assetId: 'quantumshard_ore', color: 0xa1bb12 } }; /**** * GAME STATE ****/ var gameState = { money: 0, pickaxeLevel: 1, pickaxeBaseMultiplier: 1, droneLevel: 0, currentTier: 1, oreMultipliers: { coal: 1, iron: 1, gold: 1, diamond: 1, sapphire: 1, emerald: 1, ruby: 1, chronostone: 1, soulember: 1, quantumshard: 1 }, respawnTime: 3000, maxClustersPerType: 3, clusterCount: { coal: 0, iron: 0, gold: 0, diamond: 0, sapphire: 0, emerald: 0, ruby: 0, chronostone: 0, soulember: 0, quantumshard: 0 }, clusterConfigLevels: [{ min: 2, max: 3 }, { min: 2, max: 4 }, { min: 3, max: 5 }, { min: 5, max: 10 }], clusterUpgradeTier: 0, get clusterConfig() { return this.clusterConfigLevels[this.clusterUpgradeTier] || { min: 2, max: 3 }; }, // Prestige (with new requirements) prestigeCount: 0, prestigeCurrency: 0 }; var clusters = []; var currentBackground = null; var nextBackground = null; var miner = null; var droneObjects = []; var droneSprites = []; // Initial spawn of clusters function initialSpawn() { var allTypes = ['coal', 'iron', 'gold', 'diamond', 'sapphire', 'emerald', 'ruby']; allTypes.forEach(function (type, idx) { var t = idx + 1; if (t <= gameState.currentTier) { for (var i = 0; i < gameState.maxClustersPerType; i++) { maybeSpawnCluster(type); } } }); maybeSpawnSpecialOres(); } // Create drones up to droneLevel function updateDroneObjects() { while (droneObjects.length < gameState.droneLevel) { var d = new Drone(); d.x = 200 + Math.random() * (2048 - 400); d.y = 200 + Math.random() * (2732 - 400); droneObjects.push(d); game.addChild(d); } } function updateDroneSprites() { while (droneSprites.length < gameState.droneLevel) { var drone = LK.getAsset('drone_asset', { anchorX: 0.5, anchorY: 0.5 }); drone.x = 100 + droneSprites.length * 90; drone.y = 200; droneSprites.push(drone); game.addChild(drone); } } // Spawn a cluster of a given ore type function maybeSpawnCluster(type) { var typeList = ['coal', 'iron', 'gold', 'diamond', 'sapphire', 'emerald', 'ruby']; if (typeList.indexOf(type) >= 0) { var tIndex = typeList.indexOf(type) + 1; if (tIndex > gameState.currentTier) { return; } } if (gameState.clusterCount[type] >= gameState.maxClustersPerType) { return; } var cluster = new Cluster(type); game.addChild(cluster); clusters.push(cluster); gameState.clusterCount[type]++; } // Attempt to spawn special ores based on prestige level function maybeSpawnSpecialOres() { var spawnChances = []; if (gameState.prestigeCount >= 3) { spawnChances.push({ type: 'chronostone', min: 3, max: 5 }); } if (gameState.prestigeCount >= 5) { spawnChances.push({ type: 'soulember', min: 1.5, max: 2.5 }); } if (gameState.prestigeCount >= 8) { spawnChances.push({ type: 'quantumshard', min: 0.8, max: 1.2 }); } if (spawnChances.length === 0) { return; } var standardTypes = ['coal', 'iron', 'gold', 'diamond', 'sapphire', 'emerald', 'ruby']; standardTypes.forEach(function (type) { if (gameState.clusterCount[type] < gameState.maxClustersPerType) { for (var i = 0; i < spawnChances.length; i++) { var chanceObj = spawnChances[i]; var chance = randomInt(chanceObj.min * 10, chanceObj.max * 10) / 10; var roll = Math.random() * 100; if (roll < chance) { if (gameState.clusterCount[chanceObj.type] < gameState.maxClustersPerType) { maybeSpawnCluster(chanceObj.type); } } } } }); } /**** * Drone DPS Functions ****/ function getDroneDPS() { return 10 * gameState.droneLevel; } function droneDamageTick() { var dps = getDroneDPS(); if (dps <= 0) { return; } var allValidOres = []; clusters.forEach(function (c) { c.oreList.forEach(function (ore) { if (ore.health > 0 && ore.tier <= gameState.currentTier) { allValidOres.push(ore); } }); }); if (allValidOres.length === 0) { return; } var damageRemaining = dps; while (damageRemaining > 0 && allValidOres.length > 0) { var randomIndex = Math.floor(Math.random() * allValidOres.length); var ore = allValidOres[randomIndex]; var chunk = Math.min(damageRemaining, 10); ore.health -= chunk; damageRemaining -= chunk; if (ore.health <= 0) { var baseValue = ore.getValue(); gameState.money += baseValue; updateUI(); ore.cluster.notifyOreDestroyed(ore); spawnMiningParticles(ore, 5); allValidOres.splice(randomIndex, 1); } } } /**** * UPGRADE DATA ****/ var oreUpgrades = { coal: [{ id: 'double_coal', name: 'Double Coal Value', cost: 100, multi: true, level: 0, effect: 'Doubles Coal Value each purchase', action: function action() { this.level++; gameState.oreMultipliers.coal *= 2; this.cost *= 2; } }], iron: [{ id: 'unlock_iron', name: 'Unlock Iron Mining', cost: 500, effect: 'Allows iron ore clusters to spawn', purchased: false, action: function action() { if (gameState.currentTier < 2) { gameState.currentTier = 2; } for (var i = 0; i < gameState.maxClustersPerType; i++) { maybeSpawnCluster('iron'); } } }, { id: 'double_iron', name: 'Double Iron Value', cost: 1000, multi: true, level: 0, effect: 'Doubles Iron Value each purchase', action: function action() { this.level++; gameState.oreMultipliers.iron *= 2; this.cost *= 2; } }], gold: [{ id: 'unlock_gold', name: 'Unlock Gold Mining', cost: 5000, effect: 'Allows gold ore clusters to spawn', purchased: false, action: function action() { if (gameState.currentTier < 3) { gameState.currentTier = 3; } for (var i = 0; i < gameState.maxClustersPerType; i++) { maybeSpawnCluster('gold'); } } }, { id: 'double_gold', name: 'Double Gold Value', cost: 20000, multi: true, level: 0, effect: 'Doubles Gold Value each purchase', action: function action() { this.level++; gameState.oreMultipliers.gold *= 2; this.cost *= 2; } }], diamond: [{ id: 'unlock_diamond', name: 'Unlock Diamond Mining', cost: 20000, effect: 'Allows diamond ore clusters to spawn', purchased: false, action: function action() { if (gameState.currentTier < 4) { gameState.currentTier = 4; } for (var i = 0; i < gameState.maxClustersPerType; i++) { maybeSpawnCluster('diamond'); } } }, { id: 'double_diamond', name: 'Double Diamond Value', cost: 50000, multi: true, level: 0, effect: 'Doubles Diamond Value each purchase', action: function action() { this.level++; gameState.oreMultipliers.diamond *= 2; this.cost *= 2; } }], sapphire: [{ id: 'unlock_sapphire', name: 'Unlock Sapphire Mining', cost: 100000, effect: 'Allows sapphire ore clusters to spawn', purchased: false, action: function action() { if (gameState.currentTier < 5) { gameState.currentTier = 5; } for (var i = 0; i < gameState.maxClustersPerType; i++) { maybeSpawnCluster('sapphire'); } } }, { id: 'double_sapphire', name: 'Double Sapphire Value', cost: 200000, multi: true, level: 0, effect: 'Doubles Sapphire Value each purchase', action: function action() { this.level++; gameState.oreMultipliers.sapphire *= 2; this.cost *= 2; } }], emerald: [{ id: 'unlock_emerald', name: 'Unlock Emerald Mining', cost: 500000, effect: 'Allows emerald ore clusters to spawn', purchased: false, action: function action() { if (gameState.currentTier < 6) { gameState.currentTier = 6; } for (var i = 0; i < gameState.maxClustersPerType; i++) { maybeSpawnCluster('emerald'); } } }, { id: 'double_emerald', name: 'Double Emerald Value', cost: 1000000, multi: true, level: 0, effect: 'Doubles Emerald Value each purchase', action: function action() { this.level++; gameState.oreMultipliers.emerald *= 2; this.cost *= 2; } }], ruby: [{ id: 'unlock_ruby', name: 'Unlock Ruby Mining', cost: 1000000, effect: 'Allows ruby ore clusters to spawn', purchased: false, action: function action() { if (gameState.currentTier < 7) { gameState.currentTier = 7; } for (var i = 0; i < gameState.maxClustersPerType; i++) { maybeSpawnCluster('ruby'); } } }, { id: 'double_ruby', name: 'Double Ruby Value', cost: 2000000, multi: true, level: 0, effect: 'Doubles Ruby Value each purchase', action: function action() { this.level++; gameState.oreMultipliers.ruby *= 2; this.cost *= 2; } }] }; var generalUpgrades = [{ id: 'faster_respawn', name: 'Quicker Respawn', cost: 8000, effect: 'Halves respawn time (min 500 ms)', purchased: false, action: function action() { gameState.respawnTime = Math.max(500, gameState.respawnTime / 2); } }, { id: 'cluster_up', name: 'Cluster Growth', cost: 1000, effect: 'Increases cluster size range', purchased: false, action: function action() { if (gameState.clusterUpgradeTier < gameState.clusterConfigLevels.length - 1) { gameState.clusterUpgradeTier++; } this.cost += 2000; } }, { id: 'pickaxe_buff', name: 'Pickaxe DMG +20%', cost: 20000, effect: 'Increases your total pickaxe damage by 20%', purchased: false, multi: true, level: 0, action: function action() { this.level++; gameState.pickaxeBaseMultiplier *= 1.2; this.cost = Math.floor(this.cost * 2); } }]; // Prestige shop upgrades (lower costs and some new high‐value rewards) var prestigeUpgrades = [{ id: 'pickaxe_plus_1', name: 'Pickaxe Level +1', cost: 3, effect: 'Increases pickaxe damage by 1', purchased: false, action: function action() { gameState.pickaxeLevel++; } }, { id: 'pickaxe_plus_2', name: 'Pickaxe Speed +10%', cost: 4, effect: 'Reduces mining cooldown by 10%', purchased: false, action: function action() { miner.miningRate = Math.floor(miner.miningRate * 0.90); if (miner.miningRate < 1) { miner.miningRate = 1; } } }, { id: 'pickaxe_plus_3', name: 'Pickaxe Bonus DMG +2', cost: 6, effect: 'Increases pickaxe damage by an additional 2', purchased: false, action: function action() { gameState.pickaxeLevel += 2; } }, { id: 'pickaxe_plus_4', name: 'Mega Pickaxe', cost: 15, effect: 'Increases pickaxe damage by an additional 5', purchased: false, action: function action() { gameState.pickaxeLevel += 5; } }]; var prestigeDrones = [{ id: 'drone_speedup', name: 'Drone Technology +1', cost: 8, effect: 'Increases Drone DPS by 50', purchased: false, action: function action() { if (!gameState.droneLevel) { gameState.droneLevel = 0; } gameState.droneLevel += 5; } }, { id: 'drone_overclock', name: 'Drone Overclock', cost: 12, effect: 'Increases Drone DPS by 100', purchased: false, action: function action() { gameState.droneLevel += 10; } }]; var droneUpgrades = [{ id: 'drone_level_1', name: 'Buy Drones (Lv +1)', cost: 5000, effect: 'Each level adds +10 DPS', purchased: false, multi: true, level: 0, action: function action() { if (!gameState.droneLevel) { gameState.droneLevel = 0; } gameState.droneLevel++; this.level++; this.cost = Math.floor(this.cost * 1.5); updateDroneObjects(); } }]; /**** * UI ****/ var upgradeMenu = new Container(); var tooltip = new Text2('', { size: 40, fill: 0xFFFFFF }); game.addChild(tooltip); var moneyDisplay = new Text2('$0', { size: 80, fill: 0xFFFFFF, fontWeight: 'bold', stroke: 0x000000, strokeThickness: 5 }); moneyDisplay.x = 2048 / 2 - moneyDisplay.width / 2; moneyDisplay.y = 50; game.addChild(moneyDisplay); // Position prestige display so as not to conflict with pause button (avoid upper-left 200×200) var prestigeDisplay = new Text2('Prestige: 0', { size: 50, fill: 0xFFFFFF, fontWeight: 'bold', stroke: 0x000000, strokeThickness: 4 }); prestigeDisplay.x = 250; prestigeDisplay.y = 50; game.addChild(prestigeDisplay); var shopOpenButton = LK.getAsset('shop_icon', { anchorX: 0.5, anchorY: 0.5 }); shopOpenButton.x = 2048 - 150; shopOpenButton.y = 2732 - 150; shopOpenButton.down = function () { createMainUpgradeMenu(); game.addChild(upgradeMenu); }; game.addChild(shopOpenButton); // Move prestige shop button to avoid the upper left corner var prestigeShopButton = LK.getAsset('prestige_shop_icon', { anchorX: 0.5, anchorY: 0.5 }); prestigeShopButton.x = 250; prestigeShopButton.y = 2732 - 150; prestigeShopButton.down = function () { if (canPrestige()) { doPrestige(); } else { createPrestigeShopMenu(); game.addChild(upgradeMenu); } }; game.addChild(prestigeShopButton); // Debug: Add money button var addMoneyButton = LK.getAsset('buy_button', { anchorX: 0.5, anchorY: 0.5 }); addMoneyButton.x = 200; addMoneyButton.y = 2732 - 300; addMoneyButton.down = function () { gameState.money += 5000000000; updateUI(); }; game.addChild(addMoneyButton); /**** * Upgrade Interaction Helpers (for showing/hiding descriptions) ****/ var currentUpgradeDesc = null; var currentUpgradeDescText = null; function showUpgradeDesc(upg, btn) { hideUpgradeDesc(); currentUpgradeDesc = upg; currentUpgradeDescText = new Text2(upg.effect, { size: 35, fill: 0xFFFFFF, align: 'center' }); currentUpgradeDescText.x = btn.x; currentUpgradeDescText.y = btn.y - 120; upgradeMenu.addChild(currentUpgradeDescText); } function hideUpgradeDesc() { currentUpgradeDesc = null; if (currentUpgradeDescText) { currentUpgradeDescText.destroy(); currentUpgradeDescText = null; } } /**** * Main Upgrade Menu – arranged in two columns ****/ function createMainUpgradeMenu() { upgradeMenu.removeChildren(); subUpgradeItemRefs = []; var menuBg = LK.getAsset('rectangle', { width: 1800, height: 2200, color: 0x2a2a2a, anchorX: 0.5, anchorY: 0.5 }); menuBg.x = 2048 / 2; menuBg.y = 2732 / 2 + 50; upgradeMenu.addChild(menuBg); var categories = [{ name: 'Coal Upgrades', type: 'coal' }, { name: 'Iron Upgrades', type: 'iron' }, { name: 'Gold Upgrades', type: 'gold' }, { name: 'Diamond Upgrades', type: 'diamond' }, { name: 'Sapphire Upgrades', type: 'sapphire' }, { name: 'Emerald Upgrades', type: 'emerald' }, { name: 'Ruby Upgrades', type: 'ruby' }, { name: 'General Upgrades', type: 'general' }, { name: 'Drones', type: 'drones' }, { name: 'Achievements', type: 'achievements' }]; var colSpacing = 400, rowSpacing = 300; for (var i = 0; i < categories.length; i++) { var col = i % 2; var row = Math.floor(i / 2); var x = menuBg.x + (col === 0 ? -colSpacing : colSpacing); var y = menuBg.y - 600 + row * rowSpacing; var btn = LK.getAsset('buy_button', { anchorX: 0.5, anchorY: 0.5 }); btn.x = x; btn.y = y; upgradeMenu.addChild(btn); var txt = new Text2(categories[i].name, { size: 50, fill: 0x000000, align: 'center' }); txt.anchor.set(0.5); txt.x = btn.x; txt.y = btn.y; upgradeMenu.addChild(txt); // When button is tapped, check category type: btn.down = function (cat) { return function (event) { event.stopPropagation && event.stopPropagation(); hideUpgradeDesc(); if (cat.type === 'general') { createSubUpgradeMenu('General Upgrades', generalUpgrades); } else if (cat.type === 'drones') { createSubUpgradeMenu('Drone Upgrades', droneUpgrades); } else if (cat.type === 'achievements') { createAchievementsMenu(); } else { createSubUpgradeMenu(cat.name, oreUpgrades[cat.type]); } }; }(categories[i]); } var closeBtn = LK.getAsset('cancelButton', { anchorX: 0.5, anchorY: 0.5 }); closeBtn.x = menuBg.x + 700; closeBtn.y = menuBg.y - 900; closeBtn.down = function () { game.removeChild(upgradeMenu); }; upgradeMenu.addChild(closeBtn); // Allow tapping on background to hide any open description upgradeMenu.down = function (event) { hideUpgradeDesc(); }; } var subUpgradeItemRefs = []; function createSubUpgradeMenu(title, upgList) { upgradeMenu.removeChildren(); subUpgradeItemRefs = []; var menuBg = LK.getAsset('rectangle', { width: 1800, height: 2200, color: 0x2a2a2a, anchorX: 0.5, anchorY: 0.5 }); menuBg.x = 2048 / 2; menuBg.y = 2732 / 2 + 50; upgradeMenu.addChild(menuBg); var titleText = new Text2(title, { size: 60, fill: 0xFFFFFF, align: 'center' }); titleText.anchor.set(0.5); titleText.x = menuBg.x; titleText.y = menuBg.y - 1000; upgradeMenu.addChild(titleText); var startY = menuBg.y - 800; // Arrange upgrade items in two columns var colSpacing = 400; for (var i = 0; i < upgList.length; i++) { var col = i % 2; var row = Math.floor(i / 2); var btn = LK.getAsset('buy_button', { anchorX: 0.5, anchorY: 0.5 }); btn.x = menuBg.x + (col === 0 ? -colSpacing : colSpacing); btn.y = startY + row * 250; upgradeMenu.addChild(btn); var displayName = upgList[i].name; if (typeof upgList[i].level === 'number' && upgList[i].level > 0) { displayName += " (Lv " + upgList[i].level + ")"; } var costStr = upgList[i].multi ? "$" + upgList[i].cost : "$" + upgList[i].cost; var txt = new Text2(displayName, { size: 45, fill: 0x000000, align: 'center' }); txt.anchor.set(0.5); txt.x = btn.x; txt.y = btn.y; upgradeMenu.addChild(txt); // Each upgrade button – first tap shows description; second tap purchases. btn.down = function (upg, btn) { return function (event) { event.stopPropagation && event.stopPropagation(); if (currentUpgradeDesc && currentUpgradeDesc === upg) { if (canPurchaseUpgrade(upgList, upg)) { gameState.money -= upg.cost; upg.purchased = true; upg.action(); updateUI(); hideUpgradeDesc(); createSubUpgradeMenu(title, upgList); } } else { showUpgradeDesc(upg, btn); } }; }(upgList[i], btn); subUpgradeItemRefs.push({ upgList: upgList, upgrade: upgList[i], textObj: txt }); } var backBtn = LK.getAsset('cancelButton', { anchorX: 0.5, anchorY: 0.5 }); backBtn.x = menuBg.x + 700; backBtn.y = menuBg.y - 1000; backBtn.down = function () { createMainUpgradeMenu(); }; upgradeMenu.addChild(backBtn); upgradeMenu.down = function (event) { hideUpgradeDesc(); }; } function canPurchaseUpgrade(upgList, upg) { if (upg.requires) { var needed = upgList.find(function (u) { return u.id === upg.requires; }); if (!needed || !needed.purchased) { return false; } } if (!upg.multi && upg.purchased) { return false; } if (gameState.money < upg.cost) { return false; } return true; } // Prestige Shop Menu – similar interaction for prestige upgrades function createPrestigeShopMenu() { upgradeMenu.removeChildren(); var menuBg = LK.getAsset('rectangle', { width: 1800, height: 2200, color: 0x2a2a2a, anchorX: 0.5, anchorY: 0.5 }); menuBg.x = 2048 / 2; menuBg.y = 2732 / 2 + 50; upgradeMenu.addChild(menuBg); var titleText = new Text2('Prestige Shop', { size: 60, fill: 0xFFFFFF, align: 'center' }); titleText.anchor.set(0.5); titleText.x = menuBg.x; titleText.y = menuBg.y - 1000; upgradeMenu.addChild(titleText); var shardText = new Text2('Prestige Shards: ' + gameState.prestigeCurrency, { size: 50, fill: 0xFFFF00, align: 'center' }); shardText.anchor.set(0.5); shardText.x = menuBg.x; shardText.y = menuBg.y - 900; upgradeMenu.addChild(shardText); var combinedUpgrades = prestigeUpgrades.concat(prestigeDrones); var colSpacing = 400, rowSpacing = 250; var startX = menuBg.x - colSpacing; for (var i = 0; i < combinedUpgrades.length; i++) { var col = i % 2; var row = Math.floor(i / 2); var btn = LK.getAsset('buy_button', { anchorX: 0.5, anchorY: 0.5 }); btn.x = startX + col * colSpacing; btn.y = menuBg.y - 600 + row * rowSpacing; upgradeMenu.addChild(btn); var txtStr = combinedUpgrades[i].name; var txt = new Text2(txtStr, { size: 45, fill: 0x000000, align: 'center' }); txt.anchor.set(0.5); txt.x = btn.x; txt.y = btn.y; upgradeMenu.addChild(txt); btn.down = function (upg, btn) { return function (event) { event.stopPropagation && event.stopPropagation(); if (currentUpgradeDesc && currentUpgradeDesc === upg) { if (gameState.prestigeCurrency >= upg.cost) { gameState.prestigeCurrency -= upg.cost; upg.action(); updateUI(); hideUpgradeDesc(); createPrestigeShopMenu(); } } else { showUpgradeDesc(upg, btn); } }; }(combinedUpgrades[i], btn); } var backBtn = LK.getAsset('cancelButton', { anchorX: 0.5, anchorY: 0.5 }); backBtn.x = menuBg.x + 700; backBtn.y = menuBg.y - 1000; backBtn.down = function () { game.removeChild(upgradeMenu); }; upgradeMenu.addChild(backBtn); upgradeMenu.down = function (event) { hideUpgradeDesc(); }; } /**** * Achievements Menu – two columns of badges and text ****/ function createAchievementsMenu() { upgradeMenu.removeChildren(); var menuBg = LK.getAsset('rectangle', { width: 1800, height: 2200, color: 0x333333, anchorX: 0.5, anchorY: 0.5 }); menuBg.x = 2048 / 2; menuBg.y = 2732 / 2 + 50; upgradeMenu.addChild(menuBg); var titleText = new Text2('Achievements', { size: 60, fill: 0xFFFFFF, align: 'center' }); titleText.anchor.set(0.5); titleText.x = menuBg.x; titleText.y = menuBg.y - 1000; upgradeMenu.addChild(titleText); var colSpacing = 400, rowSpacing = 200; var startX = menuBg.x - colSpacing / 2; for (var i = 0; i < achievements.length; i++) { var col = i % 2; var row = Math.floor(i / 2); var badge = LK.getAsset('rectangle', { width: 100, height: 100, color: achievements[i].achieved ? 0x00FF00 : 0x555555, anchorX: 0.5, anchorY: 0.5 }); badge.x = col === 0 ? startX : startX + colSpacing; badge.y = menuBg.y - 600 + row * rowSpacing; upgradeMenu.addChild(badge); var text = new Text2(achievements[i].name + "\n" + achievements[i].description, { size: 35, fill: achievements[i].achieved ? 0xFFFFFF : 0x999999, align: 'left' }); text.x = badge.x + 120; text.y = badge.y - 30; upgradeMenu.addChild(text); } var backBtn = LK.getAsset('cancelButton', { anchorX: 0.5, anchorY: 0.5 }); backBtn.x = menuBg.x + 700; backBtn.y = menuBg.y - 1000; backBtn.down = function () { createMainUpgradeMenu(); }; upgradeMenu.addChild(backBtn); upgradeMenu.down = function (event) { hideUpgradeDesc(); }; } /**** * GAME LOOP ****/ var quantumSelectTimer = 0; var quantumSelectionActive = false; game.update = function () { if (miner) { miner.update(); } for (var i = 0; i < droneObjects.length; i++) { droneObjects[i].updateDrone(); } if (typeof LK.time !== 'undefined' && LK.time.elapsed % 60 === 0) { droneDamageTick(); } clusters.forEach(function (cluster) { cluster.oreList.forEach(function (ore) { if (ore.health > 0) { var fraction = ore.health / ore.maxHealth; ore.healthBar.width = 120 * fraction; ore.healthBar.fill = interpolateColor(0xFF0000, 0x00FF00, fraction); ore.alpha = fraction; } }); }); if (upgradeMenu.parent) { subUpgradeItemRefs.forEach(function (ref) { var upg = ref.upgrade; var canBuy = canPurchaseUpgrade(ref.upgList, upg); if (ref.textObj && ref.textObj.style) { ref.textObj.style.fill = canBuy ? 0xFFFFFF : 0x666666; } }); } if (quantumSelectionActive) { quantumSelectTimer++; if (quantumSelectTimer > 15 * 60) { quantumSelectionActive = false; miner.quantumPathActive = false; } } // Check achievements and pop up if newly unlocked achievements.forEach(function (ach) { if (!ach.achieved && ach.condition()) { ach.achieved = true; var achText = new Text2("Achievement Unlocked: " + ach.name, { size: 40, fill: 0xFFFF00 }); achText.x = 2048 / 2; achText.y = 100; game.addChild(achText); tween(achText, { alpha: 0 }, { duration: 2000, onFinish: function onFinish() { achText.destroy(); } }); } }); // Hide the prestige shop button until money >= $1B if (gameState.money < 1e9) { prestigeShopButton.visible = false; } else { prestigeShopButton.visible = true; } }; /**** * UI Refresh & SAVE/LOAD ****/ function updateUI() { moneyDisplay.setText("$" + Math.floor(gameState.money).toLocaleString()); moneyDisplay.x = 2048 / 2 - moneyDisplay.width / 2; prestigeDisplay.setText("Prestige: " + gameState.prestigeCount); } LK.saveGame = function () { return gameState; }; LK.loadGame = function (data) { gameState = data; updateUI(); }; /**** * START GAME ****/ function startGame() { currentBackground = LK.getAsset('background', { anchorX: 0.5, anchorY: 0.5 }); currentBackground.x = 2048 / 2; currentBackground.y = 2732 / 2; // Add background at index 0 so all UI elements are above game.addChildAt(currentBackground, 0); miner = new Miner(); miner.x = 2048 / 2; miner.y = 2732 / 2; game.addChild(miner); initialSpawn(); updateUI(); } startGame(); game.pauseForQuantumSelection = function () { quantumSelectionActive = true; quantumSelectTimer = 0; // (Stub: darken screen, highlight ores, etc.) };
===================================================================
--- original.js
+++ change.js
@@ -6,18 +6,84 @@
/****
* Classes
****/
/****
+* Prestige and Background Helpers
+****
+// New prestige requirement: 1e9, 2e9, 4e9, etc.
+function getPrestigeRequirement() {
+ return 1e9 * Math.pow(2, gameState.prestigeCount);
+}
+function canPrestige() {
+ return gameState.money >= getPrestigeRequirement();
+}
+function calculatePrestigeShards() {
+ // For now, simply give 1 shard per prestige.
+ return 1;
+}
+function doPrestige() {
+ // Clear clusters
+ for (var i = clusters.length - 1; i >= 0; i--) {
+ var c = clusters[i];
+ c.removeChildren();
+ if (c.parent) { c.parent.removeChild(c); }
+ clusters.splice(i, 1);
+ }
+ var shards = calculatePrestigeShards();
+ gameState.prestigeCurrency += shards;
+ gameState.prestigeCount++;
+ gameState.money = 0;
+ gameState.currentTier = 1;
+ for (var key in gameState.clusterCount) { gameState.clusterCount[key] = 0; }
+ handleBackgroundTransition();
+ initialSpawn();
+ updateUI();
+}
+function handleBackgroundTransition() {
+ if (nextBackground && nextBackground.parent) { nextBackground.parent.removeChild(nextBackground); }
+ var newBg = null;
+ if (gameState.prestigeCount >= 8) {
+ newBg = LK.getAsset('background_tier8', { anchorX: 0.5, anchorY: 0.5 });
+ } else if (gameState.prestigeCount >= 5) {
+ newBg = LK.getAsset('background_tier5', { anchorX: 0.5, anchorY: 0.5 });
+ } else if (gameState.prestigeCount >= 3) {
+ newBg = LK.getAsset('background_tier3', { anchorX: 0.5, anchorY: 0.5 });
+ } else {
+ newBg = LK.getAsset('background', { anchorX: 0.5, anchorY: 0.5 });
+ }
+ newBg.x = 2048 / 2;
+ newBg.y = 2732 + 2732 / 2;
+ // Add new background at index 0 so all UI elements remain on top
+ game.addChildAt(newBg, 0);
+ nextBackground = newBg;
+ var oldBg = currentBackground;
+ if (!oldBg) {
+ oldBg = LK.getAsset('background', { anchorX: 0.5, anchorY: 0.5 });
+ oldBg.x = 2048 / 2;
+ oldBg.y = 2732 / 2;
+ game.addChildAt(oldBg, 0);
+ }
+ if (oldBg === newBg) { currentBackground = newBg; return; }
+ var dur = 3000;
+ tween(oldBg, { y: oldBg.y - 2732 }, {
+ duration: dur,
+ onFinish: function () { if (oldBg && oldBg.parent) { oldBg.parent.removeChild(oldBg); } }
+ });
+ tween(newBg, { y: 2732 / 2 }, {
+ duration: dur,
+ onFinish: function () { currentBackground = newBg; }
+ });
+}
+/****
* CLASSES
****/
/**
-* Cluster – spawns multiple Ore objects of a given type.
+* Cluster – spawns multiple ore objects of a given type.
*/
var Cluster = Container.expand(function (type) {
var self = Container.call(this);
self.type = type;
self.oreList = [];
- // Random center position
var centerX = 100 + Math.random() * (2048 - 200);
var centerY = 100 + Math.random() * (2732 - 200);
self.x = centerX;
self.y = centerY;
@@ -56,20 +122,19 @@
};
return self;
});
/**
-* Drone – moves around and zaps nearby ores.
-* (Added slight random deviation for natural movement.)
+* Drone – moves around and zaps nearby ores (with slight random deviations).
*/
var Drone = Container.expand(function () {
var self = Container.call(this);
self.droneSprite = LK.getAsset('drone_asset', {
anchorX: 0.5,
anchorY: 0.5
});
self.addChild(self.droneSprite);
- var SPEED = 8;
- var MIN_X = 50,
+ var SPEED = 8,
+ MIN_X = 50,
MAX_X = 2000,
MIN_Y = 50,
MAX_Y = 2682;
self.vx = Math.random() < 0.5 ? SPEED : -SPEED;
@@ -86,9 +151,8 @@
}
if (self.y < MIN_Y || self.y > MAX_Y) {
self.vy = -self.vy;
}
- // Random slight deviation
if (Math.random() < 0.01) {
self.vx += (Math.random() - 0.5) * 2;
self.vy += (Math.random() - 0.5) * 2;
var speed = Math.sqrt(self.vx * self.vx + self.vy * self.vy);
@@ -109,10 +173,10 @@
cluster.oreList.forEach(function (ore) {
if (ore.health > 0) {
var oreGlobalX = cluster.x + ore.x;
var oreGlobalY = cluster.y + ore.y;
- var dx = self.x - oreGlobalX;
- var dy = self.y - oreGlobalY;
+ var dx = self.x - oreGlobalX,
+ dy = self.y - oreGlobalY;
var dist = Math.sqrt(dx * dx + dy * dy);
if (dist < self.AOE_RANGE) {
ore.health -= self.droneDamage;
hitSomething = true;
@@ -127,17 +191,18 @@
}
});
});
if (hitSomething) {
+ // Play drone shot sound once per zap
+ LK.getSound('drone_shot').play();
self.cooldown = self.COOLDOWN_MAX;
}
};
return self;
});
/**
-* Miner – moves to and mines the nearest ore.
-* (Includes Chronostone speed boost, Soul Ember value boost, Quantum Shard chain mode,
-* and the new Hyper Mining Mode.)
+* Miner – moves toward and mines the nearest ore.
+* Includes Chronostone, Soul Ember, Quantum Shard, and the new Hyper Mining Mode.
*/
var Miner = Container.expand(function () {
var self = Container.call(this);
self.attachAsset('miner', {
@@ -149,26 +214,26 @@
self.miningRange = 25;
self.miningCooldown = 0;
self.miningRate = 30;
self.miningDamage = 1;
- // Save original values for hyper mode resets:
+ // Save originals for hyper mode
self.originalMiningRate = self.miningRate;
self.originalMiningDamage = self.miningDamage;
// Chronostone boost
self.speedBoostMultiplier = 1;
self.speedBoostTimer = 0;
// Soul Ember boost
self.soulEmberStacks = 0;
- // Quantum Shard
+ // Quantum Shard mode
self.quantumPathActive = false;
self.quantumPath = [];
self.quantumShardValueBonus = false;
// New Hyper Mining Mode
self.hyperMiningActive = false;
self.hyperMiningTimer = 0;
self.activateHyperMining = function () {
self.hyperMiningActive = true;
- self.hyperMiningTimer = 10 * 60; // 10 seconds at 60fps
+ self.hyperMiningTimer = 10 * 60;
self.miningDamage *= 2;
self.miningRate = Math.max(1, Math.floor(self.miningRate / 2));
};
self.findNewTarget = function () {
@@ -255,8 +320,13 @@
}
var damageDealt = self.miningDamage * gameState.pickaxeLevel * (gameState.pickaxeBaseMultiplier || 1);
ore.health -= damageDealt;
self.miningCooldown = self.miningRate;
+ // Play mining sound for this ore type
+ var mineSound = LK.getSound('mine_' + ore.type);
+ if (mineSound) {
+ mineSound.play();
+ }
if (ore.health <= 0) {
var baseValue = ore.getValue();
var finalValue = baseValue;
if (self.soulEmberStacks > 0) {
@@ -269,9 +339,13 @@
gameState.money += finalValue;
updateUI();
ore.cluster.notifyOreDestroyed(ore);
spawnMiningParticles(ore, 5);
- // If ore is explosive, trigger chain reaction and screen shake.
+ // Play ore-destroy sound
+ var destroySound = LK.getSound('ore_destroy_' + ore.type);
+ if (destroySound) {
+ destroySound.play();
+ }
if (ore.type === "explosive" && ore.explode) {
ore.explode();
}
} else {
@@ -299,16 +373,15 @@
};
return self;
});
/**
-* Ore – represents a single ore object.
-* This version integrates the health bar, special ore glow, and explosive ore behavior.
+* Ore – represents a single ore.
+* Includes a health bar, pulsing glow for special ores, and explosive behavior.
*/
var Ore = Container.expand(function (type, cluster) {
var self = Container.call(this);
self.type = type;
self.cluster = cluster;
- // Determine tier: standard ores get a tier 1-7, others (like special) are set high.
var typeList = ['coal', 'iron', 'gold', 'diamond', 'sapphire', 'emerald', 'ruby'];
if (typeList.indexOf(type) >= 0) {
self.tier = typeList.indexOf(type) + 1;
} else {
@@ -316,14 +389,12 @@
}
self.baseValue = oreData[type].baseValue;
self.maxHealth = oreData[type].baseHealth;
self.health = self.maxHealth;
- // Attach sprite for the ore
self.attachAsset(oreData[type].assetId, {
anchorX: 0.5,
anchorY: 0.5
});
- // Health bar
self.healthBar = LK.getAsset('rectangle', {
width: 120,
height: 20,
fill: 0x00FF00,
@@ -332,9 +403,8 @@
});
self.healthBar.x = 0;
self.healthBar.y = -70;
self.addChild(self.healthBar);
- // For special ores, add a pulsing glow effect (if applicable)
if (["chronostone", "soulember", "quantumshard"].indexOf(type) >= 0) {
var _pulseGlow = function pulseGlow() {
tween(glow, {
alpha: 1
@@ -357,9 +427,8 @@
glow.alpha = 0.5;
self.addChildAt(glow, 0);
_pulseGlow();
}
- // For explosive ore, add an explosion method
if (type === "explosive") {
self.explode = function () {
var explosionRadius = 100;
clusters.forEach(function (cluster) {
@@ -397,9 +466,9 @@
/****
* Initialize Game
****/
/****
-* Game Initialization and Helper Functions
+* GAME INITIALIZATION AND HELPER FUNCTIONS
****/
var game = new LK.Game({
backgroundColor: 0x1a1a1a
});
@@ -408,29 +477,37 @@
* Game Code
****/
// Returns a random integer between min and max (inclusive)
/****
-* Helper Functions
+* HELPER FUNCTIONS
****/
+/****
+* PLUGINS
+****/
+/****
+* SOUND INITIALIZATION
+****/
+// Shapes and Images
+/****
+* ASSETS
+****/
function randomInt(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}
-// Enhanced mining particles – if ore is special, tint accordingly
+// Enhanced mining particles – tint special ores if needed
function spawnMiningParticles(ore, num) {
for (var i = 0; i < num; i++) {
var p = LK.getAsset('mining_particle', {
anchorX: 0.5,
anchorY: 0.5
});
- // Position at ore's global coordinates
if (ore.parent) {
p.x = ore.parent.x + ore.x;
p.y = ore.parent.y + ore.y;
} else {
p.x = ore.x;
p.y = ore.y;
}
- // If ore is special, try to tint the particle (if supported)
if (["chronostone", "soulember", "quantumshard"].indexOf(ore.type) >= 0) {
p.tint = oreData[ore.type].color || 0xffffff;
}
p.vx = (Math.random() - 0.5) * 10;
@@ -460,13 +537,13 @@
var g = Math.round(g1 + f * (g2 - g1));
var b = Math.round(b1 + f * (b2 - b1));
return r << 16 | g << 8 | b;
}
-// Simple screen shake effect for explosions
+// Simple screen shake for explosions
function screenShake(duration, magnitude) {
- var originalX = game.x;
- var originalY = game.y;
- var shakeInterval = 50; // ms
+ var originalX = game.x,
+ originalY = game.y;
+ var shakeInterval = 50;
var elapsed = 0;
var shake = setInterval(function () {
elapsed += shakeInterval;
game.x = originalX + (Math.random() - 0.5) * magnitude;
@@ -477,9 +554,11 @@
game.y = originalY;
}
}, shakeInterval);
}
-// Achievement system – add more as needed
+/****
+* ACHIEVEMENT SYSTEM
+****/
var achievements = [{
id: 'first_mine',
name: 'First Mine',
description: 'Mine your first ore',
@@ -496,9 +575,9 @@
return gameState.money >= 1e9;
}
}];
/****
-* Ore Data
+* ORE DATA
****/
var oreData = {
coal: {
baseValue: 5,
@@ -608,125 +687,19 @@
min: 2,
max: 3
};
},
- // Prestige
+ // Prestige (with new requirements)
prestigeCount: 0,
prestigeCurrency: 0
};
-/****
-* Helper Functions for Prestige & Background Transitions
-****/
-function getPrestigeRequirement() {
- var base = 1e12;
- var multiplier = Math.pow(1000, gameState.prestigeCount);
- return base * multiplier;
-}
-function canPrestige() {
- return gameState.money >= getPrestigeRequirement();
-}
-function calculatePrestigeShards() {
- var threshold = getPrestigeRequirement();
- if (gameState.money < threshold) {
- return 0;
- }
- var ratio = gameState.money / threshold;
- var shards = Math.floor(Math.log10(ratio) * 2);
- return Math.max(shards, 1);
-}
-function doPrestige() {
- // Clear all clusters
- for (var i = clusters.length - 1; i >= 0; i--) {
- var c = clusters[i];
- c.removeChildren();
- if (c.parent) {
- c.parent.removeChild(c);
- }
- clusters.splice(i, 1);
- }
- var shards = calculatePrestigeShards();
- gameState.prestigeCurrency += shards;
- gameState.prestigeCount++;
- gameState.money = 0;
- gameState.currentTier = 1;
- for (var key in gameState.clusterCount) {
- gameState.clusterCount[key] = 0;
- }
- handleBackgroundTransition();
- initialSpawn();
- updateUI();
-}
-function handleBackgroundTransition() {
- if (nextBackground && nextBackground.parent) {
- nextBackground.parent.removeChild(nextBackground);
- }
- var newBg = null;
- if (gameState.prestigeCount >= 8) {
- newBg = LK.getAsset('background_tier8', {
- anchorX: 0.5,
- anchorY: 0.5
- });
- } else if (gameState.prestigeCount >= 5) {
- newBg = LK.getAsset('background_tier5', {
- anchorX: 0.5,
- anchorY: 0.5
- });
- } else if (gameState.prestigeCount >= 3) {
- newBg = LK.getAsset('background_tier3', {
- anchorX: 0.5,
- anchorY: 0.5
- });
- } else {
- newBg = LK.getAsset('background', {
- anchorX: 0.5,
- anchorY: 0.5
- });
- }
- newBg.x = 2048 / 2;
- newBg.y = 2732 + 2732 / 2; // start off-screen (bottom)
- game.addChild(newBg);
- nextBackground = newBg;
- var oldBg = currentBackground;
- if (!oldBg) {
- oldBg = LK.getAsset('background', {
- anchorX: 0.5,
- anchorY: 0.5
- });
- oldBg.x = 2048 / 2;
- oldBg.y = 2732 / 2;
- game.addChildAt(oldBg, 0);
- }
- if (oldBg === newBg) {
- currentBackground = newBg;
- return;
- }
- var dur = 3000;
- tween(oldBg, {
- y: oldBg.y - 2732
- }, {
- duration: dur,
- onFinish: function onFinish() {
- if (oldBg && oldBg.parent) {
- oldBg.parent.removeChild(oldBg);
- }
- }
- });
- tween(newBg, {
- y: 2732 / 2
- }, {
- duration: dur,
- onFinish: function onFinish() {
- currentBackground = newBg;
- }
- });
-}
var clusters = [];
var currentBackground = null;
var nextBackground = null;
var miner = null;
var droneObjects = [];
var droneSprites = [];
-// Initial spawn of clusters for each ore type
+// Initial spawn of clusters
function initialSpawn() {
var allTypes = ['coal', 'iron', 'gold', 'diamond', 'sapphire', 'emerald', 'ruby'];
allTypes.forEach(function (type, idx) {
var t = idx + 1;
@@ -735,12 +708,11 @@
maybeSpawnCluster(type);
}
}
});
- // Attempt to spawn special ores
maybeSpawnSpecialOres();
}
-// Create new drones up to gameState.droneLevel
+// Create drones up to droneLevel
function updateDroneObjects() {
while (droneObjects.length < gameState.droneLevel) {
var d = new Drone();
d.x = 200 + Math.random() * (2048 - 400);
@@ -748,9 +720,8 @@
droneObjects.push(d);
game.addChild(d);
}
}
-// Position drone sprites in the UI after upgrades (if desired)
function updateDroneSprites() {
while (droneSprites.length < gameState.droneLevel) {
var drone = LK.getAsset('drone_asset', {
anchorX: 0.5,
@@ -761,9 +732,9 @@
droneSprites.push(drone);
game.addChild(drone);
}
}
-// Standard helper function to spawn a cluster of a given ore type
+// Spawn a cluster of a given ore type
function maybeSpawnCluster(type) {
var typeList = ['coal', 'iron', 'gold', 'diamond', 'sapphire', 'emerald', 'ruby'];
if (typeList.indexOf(type) >= 0) {
var tIndex = typeList.indexOf(type) + 1;
@@ -778,9 +749,9 @@
game.addChild(cluster);
clusters.push(cluster);
gameState.clusterCount[type]++;
}
-// Attempt to spawn special ores if prestige level is high enough
+// Attempt to spawn special ores based on prestige level
function maybeSpawnSpecialOres() {
var spawnChances = [];
if (gameState.prestigeCount >= 3) {
spawnChances.push({
@@ -822,9 +793,9 @@
}
});
}
/****
-* Drone DPS – standard and tick functions.
+* Drone DPS Functions
****/
function getDroneDPS() {
return 10 * gameState.droneLevel;
}
@@ -1075,22 +1046,22 @@
gameState.pickaxeBaseMultiplier *= 1.2;
this.cost = Math.floor(this.cost * 2);
}
}];
-// Prestige shop upgrades for pickaxe artifacts
+// Prestige shop upgrades (lower costs and some new high‐value rewards)
var prestigeUpgrades = [{
id: 'pickaxe_plus_1',
name: 'Pickaxe Level +1',
- cost: 5,
+ cost: 3,
effect: 'Increases pickaxe damage by 1',
purchased: false,
action: function action() {
gameState.pickaxeLevel++;
}
}, {
id: 'pickaxe_plus_2',
name: 'Pickaxe Speed +10%',
- cost: 8,
+ cost: 4,
effect: 'Reduces mining cooldown by 10%',
purchased: false,
action: function action() {
miner.miningRate = Math.floor(miner.miningRate * 0.90);
@@ -1100,30 +1071,46 @@
}
}, {
id: 'pickaxe_plus_3',
name: 'Pickaxe Bonus DMG +2',
- cost: 10,
+ cost: 6,
effect: 'Increases pickaxe damage by an additional 2',
purchased: false,
action: function action() {
gameState.pickaxeLevel += 2;
}
+}, {
+ id: 'pickaxe_plus_4',
+ name: 'Mega Pickaxe',
+ cost: 15,
+ effect: 'Increases pickaxe damage by an additional 5',
+ purchased: false,
+ action: function action() {
+ gameState.pickaxeLevel += 5;
+ }
}];
-// Prestige shop upgrades for drones
var prestigeDrones = [{
id: 'drone_speedup',
name: 'Drone Technology +1',
- cost: 10,
+ cost: 8,
effect: 'Increases Drone DPS by 50',
purchased: false,
action: function action() {
if (!gameState.droneLevel) {
gameState.droneLevel = 0;
}
gameState.droneLevel += 5;
}
+}, {
+ id: 'drone_overclock',
+ name: 'Drone Overclock',
+ cost: 12,
+ effect: 'Increases Drone DPS by 100',
+ purchased: false,
+ action: function action() {
+ gameState.droneLevel += 10;
+ }
}];
-// Standard drone upgrades
var droneUpgrades = [{
id: 'drone_level_1',
name: 'Buy Drones (Lv +1)',
cost: 5000,
@@ -1159,16 +1146,17 @@
});
moneyDisplay.x = 2048 / 2 - moneyDisplay.width / 2;
moneyDisplay.y = 50;
game.addChild(moneyDisplay);
+// Position prestige display so as not to conflict with pause button (avoid upper-left 200×200)
var prestigeDisplay = new Text2('Prestige: 0', {
size: 50,
fill: 0xFFFFFF,
fontWeight: 'bold',
stroke: 0x000000,
strokeThickness: 4
});
-prestigeDisplay.x = 50;
+prestigeDisplay.x = 250;
prestigeDisplay.y = 50;
game.addChild(prestigeDisplay);
var shopOpenButton = LK.getAsset('shop_icon', {
anchorX: 0.5,
@@ -1180,13 +1168,14 @@
createMainUpgradeMenu();
game.addChild(upgradeMenu);
};
game.addChild(shopOpenButton);
+// Move prestige shop button to avoid the upper left corner
var prestigeShopButton = LK.getAsset('prestige_shop_icon', {
anchorX: 0.5,
anchorY: 0.5
});
-prestigeShopButton.x = 150;
+prestigeShopButton.x = 250;
prestigeShopButton.y = 2732 - 150;
prestigeShopButton.down = function () {
if (canPrestige()) {
doPrestige();
@@ -1195,8 +1184,9 @@
game.addChild(upgradeMenu);
}
};
game.addChild(prestigeShopButton);
+// Debug: Add money button
var addMoneyButton = LK.getAsset('buy_button', {
anchorX: 0.5,
anchorY: 0.5
});
@@ -1206,8 +1196,35 @@
gameState.money += 5000000000;
updateUI();
};
game.addChild(addMoneyButton);
+/****
+* Upgrade Interaction Helpers (for showing/hiding descriptions)
+****/
+var currentUpgradeDesc = null;
+var currentUpgradeDescText = null;
+function showUpgradeDesc(upg, btn) {
+ hideUpgradeDesc();
+ currentUpgradeDesc = upg;
+ currentUpgradeDescText = new Text2(upg.effect, {
+ size: 35,
+ fill: 0xFFFFFF,
+ align: 'center'
+ });
+ currentUpgradeDescText.x = btn.x;
+ currentUpgradeDescText.y = btn.y - 120;
+ upgradeMenu.addChild(currentUpgradeDescText);
+}
+function hideUpgradeDesc() {
+ currentUpgradeDesc = null;
+ if (currentUpgradeDescText) {
+ currentUpgradeDescText.destroy();
+ currentUpgradeDescText = null;
+ }
+}
+/****
+* Main Upgrade Menu – arranged in two columns
+****/
function createMainUpgradeMenu() {
upgradeMenu.removeChildren();
subUpgradeItemRefs = [];
var menuBg = LK.getAsset('rectangle', {
@@ -1221,70 +1238,77 @@
menuBg.y = 2732 / 2 + 50;
upgradeMenu.addChild(menuBg);
var categories = [{
name: 'Coal Upgrades',
- yOff: -800,
type: 'coal'
}, {
name: 'Iron Upgrades',
- yOff: -600,
type: 'iron'
}, {
name: 'Gold Upgrades',
- yOff: -400,
type: 'gold'
}, {
name: 'Diamond Upgrades',
- yOff: -200,
type: 'diamond'
}, {
name: 'Sapphire Upgrades',
- yOff: 0,
type: 'sapphire'
}, {
name: 'Emerald Upgrades',
- yOff: 200,
type: 'emerald'
}, {
name: 'Ruby Upgrades',
- yOff: 400,
type: 'ruby'
}, {
name: 'General Upgrades',
- yOff: 600,
type: 'general'
}, {
name: 'Drones',
- yOff: 800,
type: 'drones'
+ }, {
+ name: 'Achievements',
+ type: 'achievements'
}];
- categories.forEach(function (cat) {
+ var colSpacing = 400,
+ rowSpacing = 300;
+ for (var i = 0; i < categories.length; i++) {
+ var col = i % 2;
+ var row = Math.floor(i / 2);
+ var x = menuBg.x + (col === 0 ? -colSpacing : colSpacing);
+ var y = menuBg.y - 600 + row * rowSpacing;
var btn = LK.getAsset('buy_button', {
anchorX: 0.5,
anchorY: 0.5
});
- btn.x = menuBg.x;
- btn.y = menuBg.y + cat.yOff;
+ btn.x = x;
+ btn.y = y;
upgradeMenu.addChild(btn);
- var txt = new Text2(cat.name, {
+ var txt = new Text2(categories[i].name, {
size: 50,
fill: 0x000000,
align: 'center'
});
txt.anchor.set(0.5);
txt.x = btn.x;
txt.y = btn.y;
upgradeMenu.addChild(txt);
- btn.down = function () {
- if (cat.type === 'general') {
- createSubUpgradeMenu('General Upgrades', generalUpgrades);
- } else if (cat.type === 'drones') {
- createSubUpgradeMenu('Drone Upgrades', droneUpgrades);
- } else {
- createSubUpgradeMenu(cat.name, oreUpgrades[cat.type]);
- }
- };
- });
+ // When button is tapped, check category type:
+ btn.down = function (cat) {
+ return function (event) {
+ event.stopPropagation && event.stopPropagation();
+ hideUpgradeDesc();
+ if (cat.type === 'general') {
+ createSubUpgradeMenu('General Upgrades', generalUpgrades);
+ } else if (cat.type === 'drones') {
+ createSubUpgradeMenu('Drone Upgrades', droneUpgrades);
+ } else if (cat.type === 'achievements') {
+ createAchievementsMenu();
+ } else {
+ createSubUpgradeMenu(cat.name, oreUpgrades[cat.type]);
+ }
+ };
+ }(categories[i]);
+ }
var closeBtn = LK.getAsset('cancelButton', {
anchorX: 0.5,
anchorY: 0.5
});
@@ -1293,8 +1317,12 @@
closeBtn.down = function () {
game.removeChild(upgradeMenu);
};
upgradeMenu.addChild(closeBtn);
+ // Allow tapping on background to hide any open description
+ upgradeMenu.down = function (event) {
+ hideUpgradeDesc();
+ };
}
var subUpgradeItemRefs = [];
function createSubUpgradeMenu(title, upgList) {
upgradeMenu.removeChildren();
@@ -1318,48 +1346,58 @@
titleText.x = menuBg.x;
titleText.y = menuBg.y - 1000;
upgradeMenu.addChild(titleText);
var startY = menuBg.y - 800;
- upgList.forEach(function (upg, i) {
- var itemContainer = new Container();
- upgradeMenu.addChild(itemContainer);
+ // Arrange upgrade items in two columns
+ var colSpacing = 400;
+ for (var i = 0; i < upgList.length; i++) {
+ var col = i % 2;
+ var row = Math.floor(i / 2);
var btn = LK.getAsset('buy_button', {
anchorX: 0.5,
anchorY: 0.5
});
- btn.x = menuBg.x;
- btn.y = startY + i * 250;
- itemContainer.addChild(btn);
- var displayName = upg.name;
- if (typeof upg.level === 'number' && upg.level > 0) {
- displayName += " (Lv " + upg.level + ")";
+ btn.x = menuBg.x + (col === 0 ? -colSpacing : colSpacing);
+ btn.y = startY + row * 250;
+ upgradeMenu.addChild(btn);
+ var displayName = upgList[i].name;
+ if (typeof upgList[i].level === 'number' && upgList[i].level > 0) {
+ displayName += " (Lv " + upgList[i].level + ")";
}
- var costStr = upg.multi ? "$" + upg.cost : "$" + upg.cost;
- var txtStr = displayName + "\n" + upg.effect + "\n" + costStr;
- var txt = new Text2(txtStr, {
- size: 40,
- fill: 0x666666,
+ var costStr = upgList[i].multi ? "$" + upgList[i].cost : "$" + upgList[i].cost;
+ var txt = new Text2(displayName, {
+ size: 45,
+ fill: 0x000000,
align: 'center'
});
txt.anchor.set(0.5);
txt.x = btn.x;
txt.y = btn.y;
- itemContainer.addChild(txt);
- btn.down = function () {
- if (canPurchaseUpgrade(upgList, upg)) {
- gameState.money -= upg.cost;
- upg.purchased = true;
- upg.action();
- updateUI();
- createSubUpgradeMenu(title, upgList);
- }
- };
+ upgradeMenu.addChild(txt);
+ // Each upgrade button – first tap shows description; second tap purchases.
+ btn.down = function (upg, btn) {
+ return function (event) {
+ event.stopPropagation && event.stopPropagation();
+ if (currentUpgradeDesc && currentUpgradeDesc === upg) {
+ if (canPurchaseUpgrade(upgList, upg)) {
+ gameState.money -= upg.cost;
+ upg.purchased = true;
+ upg.action();
+ updateUI();
+ hideUpgradeDesc();
+ createSubUpgradeMenu(title, upgList);
+ }
+ } else {
+ showUpgradeDesc(upg, btn);
+ }
+ };
+ }(upgList[i], btn);
subUpgradeItemRefs.push({
upgList: upgList,
- upgrade: upg,
+ upgrade: upgList[i],
textObj: txt
});
- });
+ }
var backBtn = LK.getAsset('cancelButton', {
anchorX: 0.5,
anchorY: 0.5
});
@@ -1368,8 +1406,11 @@
backBtn.down = function () {
createMainUpgradeMenu();
};
upgradeMenu.addChild(backBtn);
+ upgradeMenu.down = function (event) {
+ hideUpgradeDesc();
+ };
}
function canPurchaseUpgrade(upgList, upg) {
if (upg.requires) {
var needed = upgList.find(function (u) {
@@ -1386,9 +1427,9 @@
return false;
}
return true;
}
-// Prestige Shop Menu
+// Prestige Shop Menu – similar interaction for prestige upgrades
function createPrestigeShopMenu() {
upgradeMenu.removeChildren();
var menuBg = LK.getAsset('rectangle', {
width: 1800,
@@ -1418,38 +1459,48 @@
shardText.x = menuBg.x;
shardText.y = menuBg.y - 900;
upgradeMenu.addChild(shardText);
var combinedUpgrades = prestigeUpgrades.concat(prestigeDrones);
- var startY = menuBg.y - 700;
- combinedUpgrades.forEach(function (upg, i) {
- var itemContainer = new Container();
- upgradeMenu.addChild(itemContainer);
+ var colSpacing = 400,
+ rowSpacing = 250;
+ var startX = menuBg.x - colSpacing;
+ for (var i = 0; i < combinedUpgrades.length; i++) {
+ var col = i % 2;
+ var row = Math.floor(i / 2);
var btn = LK.getAsset('buy_button', {
anchorX: 0.5,
anchorY: 0.5
});
- btn.x = menuBg.x;
- btn.y = startY + i * 250;
- itemContainer.addChild(btn);
- var txtStr = upg.name + "\n" + upg.effect + "\nCost: " + upg.cost + " Shards";
+ btn.x = startX + col * colSpacing;
+ btn.y = menuBg.y - 600 + row * rowSpacing;
+ upgradeMenu.addChild(btn);
+ var txtStr = combinedUpgrades[i].name;
var txt = new Text2(txtStr, {
- size: 40,
- fill: 0x666666,
+ size: 45,
+ fill: 0x000000,
align: 'center'
});
txt.anchor.set(0.5);
txt.x = btn.x;
txt.y = btn.y;
- itemContainer.addChild(txt);
- btn.down = function () {
- if (gameState.prestigeCurrency >= upg.cost) {
- gameState.prestigeCurrency -= upg.cost;
- upg.action();
- updateUI();
- createPrestigeShopMenu();
- }
- };
- });
+ upgradeMenu.addChild(txt);
+ btn.down = function (upg, btn) {
+ return function (event) {
+ event.stopPropagation && event.stopPropagation();
+ if (currentUpgradeDesc && currentUpgradeDesc === upg) {
+ if (gameState.prestigeCurrency >= upg.cost) {
+ gameState.prestigeCurrency -= upg.cost;
+ upg.action();
+ updateUI();
+ hideUpgradeDesc();
+ createPrestigeShopMenu();
+ }
+ } else {
+ showUpgradeDesc(upg, btn);
+ }
+ };
+ }(combinedUpgrades[i], btn);
+ }
var backBtn = LK.getAsset('cancelButton', {
anchorX: 0.5,
anchorY: 0.5
});
@@ -1458,10 +1509,76 @@
backBtn.down = function () {
game.removeChild(upgradeMenu);
};
upgradeMenu.addChild(backBtn);
+ upgradeMenu.down = function (event) {
+ hideUpgradeDesc();
+ };
}
/****
+* Achievements Menu – two columns of badges and text
+****/
+function createAchievementsMenu() {
+ upgradeMenu.removeChildren();
+ var menuBg = LK.getAsset('rectangle', {
+ width: 1800,
+ height: 2200,
+ color: 0x333333,
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ menuBg.x = 2048 / 2;
+ menuBg.y = 2732 / 2 + 50;
+ upgradeMenu.addChild(menuBg);
+ var titleText = new Text2('Achievements', {
+ size: 60,
+ fill: 0xFFFFFF,
+ align: 'center'
+ });
+ titleText.anchor.set(0.5);
+ titleText.x = menuBg.x;
+ titleText.y = menuBg.y - 1000;
+ upgradeMenu.addChild(titleText);
+ var colSpacing = 400,
+ rowSpacing = 200;
+ var startX = menuBg.x - colSpacing / 2;
+ for (var i = 0; i < achievements.length; i++) {
+ var col = i % 2;
+ var row = Math.floor(i / 2);
+ var badge = LK.getAsset('rectangle', {
+ width: 100,
+ height: 100,
+ color: achievements[i].achieved ? 0x00FF00 : 0x555555,
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ badge.x = col === 0 ? startX : startX + colSpacing;
+ badge.y = menuBg.y - 600 + row * rowSpacing;
+ upgradeMenu.addChild(badge);
+ var text = new Text2(achievements[i].name + "\n" + achievements[i].description, {
+ size: 35,
+ fill: achievements[i].achieved ? 0xFFFFFF : 0x999999,
+ align: 'left'
+ });
+ text.x = badge.x + 120;
+ text.y = badge.y - 30;
+ upgradeMenu.addChild(text);
+ }
+ var backBtn = LK.getAsset('cancelButton', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ backBtn.x = menuBg.x + 700;
+ backBtn.y = menuBg.y - 1000;
+ backBtn.down = function () {
+ createMainUpgradeMenu();
+ };
+ upgradeMenu.addChild(backBtn);
+ upgradeMenu.down = function (event) {
+ hideUpgradeDesc();
+ };
+}
+/****
* GAME LOOP
****/
var quantumSelectTimer = 0;
var quantumSelectionActive = false;
@@ -1500,9 +1617,9 @@
quantumSelectionActive = false;
miner.quantumPathActive = false;
}
}
- // Achievement check:
+ // Check achievements and pop up if newly unlocked
achievements.forEach(function (ach) {
if (!ach.achieved && ach.condition()) {
ach.achieved = true;
var achText = new Text2("Achievement Unlocked: " + ach.name, {
@@ -1521,11 +1638,17 @@
}
});
}
});
+ // Hide the prestige shop button until money >= $1B
+ if (gameState.money < 1e9) {
+ prestigeShopButton.visible = false;
+ } else {
+ prestigeShopButton.visible = true;
+ }
};
/****
-* UI REFRESH & SAVE/LOAD
+* UI Refresh & SAVE/LOAD
****/
function updateUI() {
moneyDisplay.setText("$" + Math.floor(gameState.money).toLocaleString());
moneyDisplay.x = 2048 / 2 - moneyDisplay.width / 2;
@@ -1547,8 +1670,9 @@
anchorY: 0.5
});
currentBackground.x = 2048 / 2;
currentBackground.y = 2732 / 2;
+ // Add background at index 0 so all UI elements are above
game.addChildAt(currentBackground, 0);
miner = new Miner();
miner.x = 2048 / 2;
miner.y = 2732 / 2;
@@ -1559,6 +1683,6 @@
startGame();
game.pauseForQuantumSelection = function () {
quantumSelectionActive = true;
quantumSelectTimer = 0;
- // (Stub: Darken screen and highlight ores if desired)
+ // (Stub: darken screen, highlight ores, etc.)
};
\ No newline at end of file
drone_shot
Sound effect
mine_coal
Sound effect
mine_iron
Sound effect
mine_gold
Sound effect
mine_diamond
Sound effect
mine_sapphire
Sound effect
mine_emerald
Sound effect
mine_ruby
Sound effect
mine_chronostone
Sound effect
mine_quantumshard
Sound effect
ore_destroy_coal
Sound effect
ore_destroy_iron
Sound effect
ore_destroy_gold
Sound effect
ore_destroy_diamond
Sound effect
ore_destroy_sapphire
Sound effect
ore_destroy_emerald
Sound effect
ore_destroy_ruby
Sound effect
mine_coal_1
Sound effect
mine_coal_2
Sound effect
mine_coal_3
Sound effect
mine_diamond1
Sound effect
mine_diamond2
Sound effect
mine_diamond3
Sound effect
mine_emerald1
Sound effect
mine_emerald2
Sound effect
mine_emerald3
Sound effect
mine_gold1
Sound effect
mine_gold2
Sound effect
mine_gold3
Sound effect
mine_iron1
Sound effect
mine_iron2
Sound effect
mine_iron3
Sound effect
mine_ruby1
Sound effect
mine_ruby2
Sound effect
mine_ruby3
Sound effect
mine_sapphire1
Sound effect
mine_sapphire2
Sound effect
mine_sapphire3
Sound effect
song1
Music
song2
Music
song3
Music
song4
Music
song5
Music
song6
Music
song7
Music
song8
Music
song9
Music
song10
Music
song11
Music
song12
Music
song1a
Music
song1b
Music
song2a
Music
song2b
Music
song3a
Music
song3b
Music
song4a
Music
song4b
Music
song5a
Music
song5b
Music
song6a
Music
song6b
Music
song7a
Music
song7b
Music
song8a
Music
song8b
Music
song9a
Music
song9b
Music
song10a
Music
song10b
Music
song11a
Music
song11b
Music
song12a
Music
song12b
Music