/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var storage = LK.import("@upit/storage.v1"); /**** * Classes ****/ var Claw = Container.expand(function () { var self = Container.call(this); var clawGraphics = self.attachAsset('claw', { anchorX: 0.5, anchorY: 0.5 }); // Cable removed - no longer visible self.swingAngle = 0; self.swingSpeed = 0.02; self.swingRadius = 300; self.centerX = 1024; // Center position self.startX = 1024; // Starting X position - same as center self.isDropping = false; self.isRetracting = false; self.dropSpeed = 8; self.retractSpeed = 6; self.startY = 350; self.grabbedItem = null; self.weight = 1; self.isRetractingStarted = false; self.update = function () { if (!self.isDropping && !self.isRetracting) { // Swing back and forth by rotating the claw self.swingAngle += self.swingSpeed; self.rotation = Math.sin(self.swingAngle) * 2.0; // Rotate between -2.0 and 2.0 radians for much wider swing, better matching visual angle } // Dropping is now handled by tween animation in drop() method if (self.isRetracting && !self.isRetractingStarted) { self.isRetractingStarted = true; // Calculate distance back to start position var distanceBack = Math.sqrt(Math.pow(self.startX - self.x, 2) + Math.pow(self.startY - self.y, 2)); // Base retraction speed (pixels per second) - slower when carrying items var baseRetractSpeed = 600; // pixels per second when empty var weightedRetractSpeed = baseRetractSpeed / self.weight; // Slower for heavier items var retractDuration = distanceBack / weightedRetractSpeed * 1000; // Convert to milliseconds // Use tween to move claw back to start position tween(self, { x: self.startX, y: self.startY }, { duration: retractDuration, easing: tween.linear, onFinish: function onFinish() { self.isRetracting = false; self.isRetractingStarted = false; // Use a small delay to ensure item collection happens cleanly if (self.grabbedItem) { LK.setTimeout(function () { if (self.grabbedItem) { // Double check item still exists self.collectItem(); } }, 50); } } }); } // Move grabbed item with claw if (self.grabbedItem) { self.grabbedItem.x = self.x; self.grabbedItem.y = self.y + 40; } // Cable positioning removed - cable is now invisible }; self.drop = function () { if (!self.isDropping && !self.isRetracting) { self.isDropping = true; // Calculate target position based on current rotation var targetDistance = 2400; // How far the claw should extend - increased to reach bottom of screen // Use the actual rotation of the claw to determine direction var angle = self.rotation + Math.PI / 2; // Adjust so 0 is straight down, and positive rotation is to the right var targetX = self.centerX + Math.cos(angle) * targetDistance; var targetY = self.startY + Math.sin(angle) * targetDistance; // Ensure claw stays within screen bounds if (targetX < 50) targetX = 50; if (targetX > 1998) targetX = 1998; // Calculate distance to target var distance = Math.sqrt(Math.pow(targetX - self.x, 2) + Math.pow(targetY - self.y, 2)); // Use constant speed for dropping (pixels per second) var dropSpeed = 800; // pixels per second var dropDuration = distance / dropSpeed * 1000; // Convert to milliseconds // Use tween to move claw directly to target position tween(self, { x: targetX, y: targetY }, { duration: dropDuration, easing: tween.linear, onFinish: function onFinish() { self.isDropping = false; self.isRetracting = true; } }); LK.getSound('clawMove').play(); } }; self.collectItem = function () { if (self.grabbedItem) { var itemToCollect = self.grabbedItem; // Store reference before clearing self.grabbedItem = null; // Clear reference immediately to prevent double collection self.weight = 1; // Reset weight immediately // Add to score based on item type var points = 0; if (itemToCollect.itemType === 'gold') { points = 50; // Fixed value for gold } else if (itemToCollect.itemType === 'ruby') { points = 70; // Fixed value for ruby } else if (itemToCollect.itemType === 'emerald') { points = 85; // Fixed value for emerald } else if (itemToCollect.itemType === 'diamond') { points = 100; } else if (itemToCollect.itemType === 'rock') { // If we have dynamite, use it to destroy rock if (dynamiteCount > 0) { dynamiteCount--; dynamiteText.setText('Dynamite: ' + dynamiteCount); // Flash screen yellow for dynamite use LK.effects.flashScreen(0xFFFF00, 500); points = 20; // Small reward for blowing up rock // Auto-reset claw self.isRetracting = false; self.isRetractingStarted = false; self.x = self.startX; self.y = self.startY; } else { points = 10; } } else if (itemToCollect.itemType === 'pig') { points = 150; // Higher value for pig with diamond } else if (itemToCollect.itemType === 'tnt') { // If we have dynamite, use it to destroy TNT if (dynamiteCount > 0) { dynamiteCount--; dynamiteText.setText('Dynamite: ' + dynamiteCount); // Flash screen yellow for dynamite use LK.effects.flashScreen(0xFFFF00, 500); points = 0; // Auto-reset claw self.isRetracting = false; self.isRetractingStarted = false; self.x = self.startX; self.y = self.startY; } else { // TNT explodes and resets score to 0 LK.setScore(0); scoreText.setText('Score: 0'); // Flash screen red for explosion effect LK.effects.flashScreen(0xFF0000, 1000); points = 0; } } else if (itemToCollect.itemType === 'mysteryBag') { // Open mystery bag if (itemToCollect.contents === 'dynamite') { dynamiteCount++; dynamiteText.setText('Dynamite: ' + dynamiteCount); // Flash screen green for dynamite pickup LK.effects.flashScreen(0x00FF00, 500); points = 0; } else if (itemToCollect.contents === 'diamond') { points = 100; } else if (itemToCollect.contents === 'gold') { points = itemToCollect.goldValue; } } if (itemToCollect.itemType !== 'tnt') { LK.setScore(LK.getScore() + points); scoreText.setText('Score: ' + LK.getScore()); } // Remove item from items array for (var i = items.length - 1; i >= 0; i--) { if (items[i] === itemToCollect) { items[i].destroy(); items.splice(i, 1); break; } } LK.getSound('collect').play(); } }; return self; }); var Miner = Container.expand(function () { var self = Container.call(this); // Create miner character using miner asset var minerGraphics = self.attachAsset('miner', { anchorX: 0.5, anchorY: 1 }); // Add a "reel" arm/hand asset to simulate winding the claw // We'll use the 'clawCable' asset as a makeshift reel handle for animation var reelHandle = self.attachAsset('clawCable', { anchorX: 0.5, anchorY: 1 }); reelHandle.x = 0; reelHandle.y = -80; reelHandle.scaleX = 2.5; reelHandle.scaleY = 0.5; reelHandle.rotation = 0; // Animate the reel handle when the claw is retracting self.update = function () { // If the global 'claw' is retracting, animate the reel handle if (typeof claw !== "undefined" && claw.isRetracting) { // Spin the handle reelHandle.rotation += 0.3; // Optionally, add a little up/down movement for fun reelHandle.y = -80 + Math.sin(Date.now() / 120) * 8; } else { // Reset to default position reelHandle.rotation = 0; reelHandle.y = -80; } }; return self; }); var MiningItem = Container.expand(function (itemType) { var self = Container.call(this); self.itemType = itemType; var assetName = ''; var scale = 1; if (itemType === 'gold') { assetName = 'goldNugget'; self.weight = 1.5; // Random scale between 0.5 and 1.8 for more variety scale = 0.5 + Math.random() * 1.3; self.weight *= scale; // Adjust weight based on size } else if (itemType === 'diamond') { assetName = 'diamond'; self.weight = 1; } else if (itemType === 'ruby') { assetName = 'ruby'; self.weight = 1.2; } else if (itemType === 'emerald') { assetName = 'emerald'; self.weight = 1.3; } else if (itemType === 'rock') { assetName = 'rock'; self.weight = 3; // Random scale between 0.6 and 1.4 scale = 0.6 + Math.random() * 0.8; self.weight *= scale; // Adjust weight based on size } else if (itemType === 'tnt') { assetName = 'tnt'; self.weight = 2; } // Create shadow first so it appears behind the item var shadowGraphics = self.attachAsset(assetName, { anchorX: 0.5, anchorY: 0.5 }); shadowGraphics.tint = 0x000000; // Black shadow shadowGraphics.alpha = 0.3; // Semi-transparent shadowGraphics.scaleX = scale * 1.1; // Slightly larger than item shadowGraphics.scaleY = scale * 0.6; // Flattened for shadow effect shadowGraphics.x = 15; // Offset to the right shadowGraphics.y = 20; // Offset down var itemGraphics = self.attachAsset(assetName, { anchorX: 0.5, anchorY: 0.5 }); // Apply random scale itemGraphics.scaleX = scale; itemGraphics.scaleY = scale; return self; }); var MysteryBag = Container.expand(function () { var self = Container.call(this); // Create shadow first var shadowGraphics = self.attachAsset('tnt', { anchorX: 0.5, anchorY: 0.5 }); shadowGraphics.tint = 0x000000; // Black shadow shadowGraphics.alpha = 0.3; // Semi-transparent shadowGraphics.scaleX = 1.3; // Slightly larger shadowGraphics.scaleY = 0.8; // Flattened shadowGraphics.x = 15; // Offset shadowGraphics.y = 20; // Create a mystery bag visual using a scaled TNT asset with different tint var bagGraphics = self.attachAsset('tnt', { anchorX: 0.5, anchorY: 0.5 }); bagGraphics.tint = 0x8B4513; // Brown color for bag bagGraphics.scaleX = 1.2; bagGraphics.scaleY = 1.2; // Add a question mark using text var questionMark = new Text2('?', { size: 60, fill: 0xFFFFFF }); questionMark.anchor.set(0.5, 0.5); self.addChild(questionMark); self.itemType = 'mysteryBag'; self.weight = 1.5; // Randomly determine contents var rand = Math.random(); if (rand < 0.3) { // 30% chance for dynamite self.contents = 'dynamite'; } else if (rand < 0.5) { // 20% chance for diamond self.contents = 'diamond'; } else { // 50% chance for gold self.contents = 'gold'; // Random gold value between 50-200 self.goldValue = Math.floor(Math.random() * 150) + 50; } return self; }); var Pig = Container.expand(function () { var self = Container.call(this); // Create shadow first var shadowGraphics = self.attachAsset('pig', { anchorX: 0.5, anchorY: 0.5 }); shadowGraphics.tint = 0x000000; // Black shadow shadowGraphics.alpha = 0.3; // Semi-transparent shadowGraphics.scaleX = 1.1; // Slightly larger shadowGraphics.scaleY = 0.6; // Flattened shadowGraphics.x = 15; // Offset shadowGraphics.y = 20; var pigGraphics = self.attachAsset('pig', { anchorX: 0.5, anchorY: 0.5 }); var diamond = self.attachAsset('diamond', { anchorX: 0.5, anchorY: 0.5 }); diamond.x = 0; diamond.y = -10; // Position diamond in pig's "mouth" diamond.scaleX = 0.6; diamond.scaleY = 0.6; // Random movement speed between 0.5 and 2.5 self.moveSpeed = 0.5 + Math.random() * 2; // Random initial direction self.direction = Math.random() < 0.5 ? -1 : 1; // Random movement range between 150 and 350 self.moveRange = 150 + Math.random() * 200; self.startX = 0; self.itemType = 'pig'; self.weight = 2; self.update = function () { // Move pig back and forth self.x += self.moveSpeed * self.direction; if (self.x > self.startX + self.moveRange || self.x < self.startX - self.moveRange) { self.direction *= -1; } }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x87CEEB }); /**** * Game Code ****/ // Game variables // Game assets will be created dynamically var claw; var items = []; var gameTime = 60; // 60 seconds per level var timeLeft = gameTime; var gameActive = true; var scoreText; var timeText; var gameTimer; var dynamiteCount = 0; // Track dynamite inventory var dynamiteText; // UI for dynamite count // Level system variables var currentLevel = storage.currentLevel || 1; var levelText; // UI for level display var targetScoreText; // UI for target score var inMarket = false; // Track if we're in market phase // Calculate target score for current level function getTargetScore(level) { return 300 + (level - 1) * 150; // Level 1: 300, Level 2: 450, Level 3: 600, etc. } // Market prices var marketPrices = { time5: 100, time10: 180, time15: 250, dynamite1: 80, dynamite2: 150, dynamite3: 200 }; // Create sky background var sky = game.attachAsset('sky', { x: 0, y: 0 }); // Create ground var ground = game.attachAsset('ground', { x: 0, y: 300 }); // Create miner character var miner = game.addChild(new Miner()); miner.x = 1024; miner.y = 300; // Create claw claw = game.addChild(new Claw()); claw.x = 1024; claw.y = 350; // Create UI elements scoreText = new Text2('Score: 0', { size: 80, fill: 0xFFFFFF }); scoreText.anchor.set(0, 0); LK.gui.topLeft.addChild(scoreText); scoreText.x = 120; // Avoid top-left menu area timeText = new Text2('Time: 60', { size: 80, fill: 0xFFFFFF }); timeText.anchor.set(1, 0); LK.gui.topRight.addChild(timeText); // Add dynamite counter UI dynamiteText = new Text2('Dynamite: 0', { size: 60, fill: 0xFFFF00 }); dynamiteText.anchor.set(0.5, 0); LK.gui.top.addChild(dynamiteText); // Add level display levelText = new Text2('Level: ' + currentLevel, { size: 70, fill: 0xFFFFFF }); levelText.anchor.set(0, 0); LK.gui.topLeft.addChild(levelText); levelText.x = 120; levelText.y = 90; // Add target score display targetScoreText = new Text2('Target: ' + getTargetScore(currentLevel), { size: 60, fill: 0x00FF00 }); targetScoreText.anchor.set(0, 0); LK.gui.topLeft.addChild(targetScoreText); targetScoreText.x = 120; targetScoreText.y = 170; // Generate random items underground function generateItems() { var occupiedPositions = []; // Track positions to prevent overlap var minDistance = 120; // Minimum distance between items // 1. Place gold nuggets (e.g. 8) var goldCount = 8; for (var i = 0; i < goldCount; i++) { var gold = new MiningItem('gold'); // Find a position that doesn't overlap with existing items var validPosition = false; var attempts = 0; var maxAttempts = 50; while (!validPosition && attempts < maxAttempts) { gold.x = Math.random() * 1800 + 124; gold.y = Math.random() * 1200 + 800; validPosition = true; for (var j = 0; j < occupiedPositions.length; j++) { var distance = Math.sqrt(Math.pow(gold.x - occupiedPositions[j].x, 2) + Math.pow(gold.y - occupiedPositions[j].y, 2)); if (distance < minDistance) { validPosition = false; break; } } attempts++; } occupiedPositions.push({ x: gold.x, y: gold.y }); items.push(gold); game.addChild(gold); } // 2. Place rubies (3) var rubyCount = 3; for (var i = 0; i < rubyCount; i++) { var ruby = new MiningItem('ruby'); var validPosition = false; var attempts = 0; var maxAttempts = 50; while (!validPosition && attempts < maxAttempts) { ruby.x = Math.random() * 1800 + 124; ruby.y = Math.random() * 1200 + 800; validPosition = true; for (var j = 0; j < occupiedPositions.length; j++) { var distance = Math.sqrt(Math.pow(ruby.x - occupiedPositions[j].x, 2) + Math.pow(ruby.y - occupiedPositions[j].y, 2)); if (distance < minDistance) { validPosition = false; break; } } attempts++; } occupiedPositions.push({ x: ruby.x, y: ruby.y }); items.push(ruby); game.addChild(ruby); } // 3. Place emeralds (2) var emeraldCount = 2; for (var i = 0; i < emeraldCount; i++) { var emerald = new MiningItem('emerald'); var validPosition = false; var attempts = 0; var maxAttempts = 50; while (!validPosition && attempts < maxAttempts) { emerald.x = Math.random() * 1800 + 124; emerald.y = Math.random() * 1200 + 800; validPosition = true; for (var j = 0; j < occupiedPositions.length; j++) { var distance = Math.sqrt(Math.pow(emerald.x - occupiedPositions[j].x, 2) + Math.pow(emerald.y - occupiedPositions[j].y, 2)); if (distance < minDistance) { validPosition = false; break; } } attempts++; } occupiedPositions.push({ x: emerald.x, y: emerald.y }); items.push(emerald); game.addChild(emerald); } // 4. Place diamonds (exactly 2) var diamondCount = 2; for (var i = 0; i < diamondCount; i++) { var diamond = new MiningItem('diamond'); var validPosition = false; var attempts = 0; var maxAttempts = 50; while (!validPosition && attempts < maxAttempts) { diamond.x = Math.random() * 1800 + 124; diamond.y = Math.random() * 1200 + 800; validPosition = true; for (var j = 0; j < occupiedPositions.length; j++) { var distance = Math.sqrt(Math.pow(diamond.x - occupiedPositions[j].x, 2) + Math.pow(diamond.y - occupiedPositions[j].y, 2)); if (distance < minDistance) { validPosition = false; break; } } attempts++; } occupiedPositions.push({ x: diamond.x, y: diamond.y }); items.push(diamond); game.addChild(diamond); } // 5. Place rocks (e.g. 6) var rockCount = 6; for (var i = 0; i < rockCount; i++) { var rock = new MiningItem('rock'); var validPosition = false; var attempts = 0; var maxAttempts = 50; while (!validPosition && attempts < maxAttempts) { rock.x = Math.random() * 1800 + 124; rock.y = Math.random() * 1200 + 800; validPosition = true; for (var j = 0; j < occupiedPositions.length; j++) { var distance = Math.sqrt(Math.pow(rock.x - occupiedPositions[j].x, 2) + Math.pow(rock.y - occupiedPositions[j].y, 2)); if (distance < minDistance) { validPosition = false; break; } } attempts++; } occupiedPositions.push({ x: rock.x, y: rock.y }); items.push(rock); game.addChild(rock); } // 6. Place TNT (up to 3) var tntCount = 0; var maxTnt = 3; for (var i = 0; i < maxTnt; i++) { var tnt = new MiningItem('tnt'); var validPosition = false; var attempts = 0; var maxAttempts = 50; while (!validPosition && attempts < maxAttempts) { tnt.x = Math.random() * 1800 + 124; tnt.y = Math.random() * 1200 + 800; validPosition = true; for (var j = 0; j < occupiedPositions.length; j++) { var distance = Math.sqrt(Math.pow(tnt.x - occupiedPositions[j].x, 2) + Math.pow(tnt.y - occupiedPositions[j].y, 2)); if (distance < minDistance) { validPosition = false; break; } } attempts++; } occupiedPositions.push({ x: tnt.x, y: tnt.y }); items.push(tnt); game.addChild(tnt); } // 7. Add mystery bags (maximum 2 per level) var mysteryBagCount = Math.floor(Math.random() * 2) + 1; // 1 or 2 mystery bags for (var i = 0; i < mysteryBagCount; i++) { var mysteryBag = new MysteryBag(); var validPosition = false; var attempts = 0; var maxAttempts = 50; while (!validPosition && attempts < maxAttempts) { mysteryBag.x = Math.random() * 1800 + 124; mysteryBag.y = Math.random() * 1200 + 800; validPosition = true; for (var j = 0; j < occupiedPositions.length; j++) { var distance = Math.sqrt(Math.pow(mysteryBag.x - occupiedPositions[j].x, 2) + Math.pow(mysteryBag.y - occupiedPositions[j].y, 2)); if (distance < minDistance) { validPosition = false; break; } } attempts++; } occupiedPositions.push({ x: mysteryBag.x, y: mysteryBag.y }); items.push(mysteryBag); game.addChild(mysteryBag); } // 8. Add moving pigs with diamonds - exactly 3 var pigCount = 3; for (var i = 0; i < pigCount; i++) { var pig = new Pig(); // Find position that doesn't overlap with items var validPosition = false; var attempts = 0; var maxAttempts = 50; while (!validPosition && attempts < maxAttempts) { pig.x = Math.random() * 1600 + 200; pig.y = Math.random() * 600 + 1000; validPosition = true; for (var j = 0; j < occupiedPositions.length; j++) { var distance = Math.sqrt(Math.pow(pig.x - occupiedPositions[j].x, 2) + Math.pow(pig.y - occupiedPositions[j].y, 2)); if (distance < minDistance) { validPosition = false; break; } } attempts++; } pig.startX = pig.x; occupiedPositions.push({ x: pig.x, y: pig.y }); items.push(pig); game.addChild(pig); } } // Initialize items generateItems(); // Create market UI function showMarket() { inMarket = true; gameActive = false; // Halve the current score when entering market LK.setScore(Math.floor(LK.getScore() / 2)); // Clear current game items for (var i = items.length - 1; i >= 0; i--) { items[i].destroy(); } items = []; // Create market background var marketBg = new Container(); marketBg.x = 1024; marketBg.y = 1366; game.addChild(marketBg); // Market title var marketTitle = new Text2('MARKET', { size: 120, fill: 0xFFD700 }); marketTitle.anchor.set(0.5, 0.5); marketTitle.y = -900; marketBg.addChild(marketTitle); // Level complete text var levelCompleteText = new Text2('Level ' + currentLevel + ' Complete!', { size: 80, fill: 0x00FF00 }); levelCompleteText.anchor.set(0.5, 0.5); levelCompleteText.y = -750; marketBg.addChild(levelCompleteText); // Score text (showing halved score) var scoreInfo = new Text2('Your Score: ' + LK.getScore() + ' (50% deducted)', { size: 60, fill: 0xFFFFFF }); scoreInfo.anchor.set(0.5, 0.5); scoreInfo.y = -630; marketBg.addChild(scoreInfo); // Time upgrades var timeTitle = new Text2('Time Upgrades:', { size: 60, fill: 0xFFFFFF }); timeTitle.anchor.set(0.5, 0.5); timeTitle.y = -480; marketBg.addChild(timeTitle); // +5 seconds button var time5Button = createMarketButton('+5 Seconds - ' + marketPrices.time5 + ' pts', -400, -350, function () { if (LK.getScore() >= marketPrices.time5) { LK.setScore(LK.getScore() - marketPrices.time5); gameTime += 5; scoreInfo.setText('Your Score: ' + LK.getScore()); LK.getSound('collect').play(); } }); marketBg.addChild(time5Button); // +10 seconds button var time10Button = createMarketButton('+10 Seconds - ' + marketPrices.time10 + ' pts', 0, -350, function () { if (LK.getScore() >= marketPrices.time10) { LK.setScore(LK.getScore() - marketPrices.time10); gameTime += 10; scoreInfo.setText('Your Score: ' + LK.getScore()); LK.getSound('collect').play(); } }); marketBg.addChild(time10Button); // +15 seconds button var time15Button = createMarketButton('+15 Seconds - ' + marketPrices.time15 + ' pts', 400, -350, function () { if (LK.getScore() >= marketPrices.time15) { LK.setScore(LK.getScore() - marketPrices.time15); gameTime += 15; scoreInfo.setText('Your Score: ' + LK.getScore()); LK.getSound('collect').play(); } }); marketBg.addChild(time15Button); // Dynamite upgrades var dynamiteTitle = new Text2('Dynamite Upgrades:', { size: 60, fill: 0xFFFFFF }); dynamiteTitle.anchor.set(0.5, 0.5); dynamiteTitle.y = -200; marketBg.addChild(dynamiteTitle); // +1 dynamite button var dyn1Button = createMarketButton('+1 Dynamite - ' + marketPrices.dynamite1 + ' pts', -400, -70, function () { if (LK.getScore() >= marketPrices.dynamite1) { LK.setScore(LK.getScore() - marketPrices.dynamite1); dynamiteCount += 1; dynamiteText.setText('Dynamite: ' + dynamiteCount); scoreInfo.setText('Your Score: ' + LK.getScore()); LK.getSound('collect').play(); } }); marketBg.addChild(dyn1Button); // +2 dynamite button var dyn2Button = createMarketButton('+2 Dynamite - ' + marketPrices.dynamite2 + ' pts', 0, -70, function () { if (LK.getScore() >= marketPrices.dynamite2) { LK.setScore(LK.getScore() - marketPrices.dynamite2); dynamiteCount += 2; dynamiteText.setText('Dynamite: ' + dynamiteCount); scoreInfo.setText('Your Score: ' + LK.getScore()); LK.getSound('collect').play(); } }); marketBg.addChild(dyn2Button); // +3 dynamite button var dyn3Button = createMarketButton('+3 Dynamite - ' + marketPrices.dynamite3 + ' pts', 400, -70, function () { if (LK.getScore() >= marketPrices.dynamite3) { LK.setScore(LK.getScore() - marketPrices.dynamite3); dynamiteCount += 3; dynamiteText.setText('Dynamite: ' + dynamiteCount); scoreInfo.setText('Your Score: ' + LK.getScore()); LK.getSound('collect').play(); } }); marketBg.addChild(dyn3Button); // Continue button var continueButton = createMarketButton('Continue to Level ' + (currentLevel + 1), 0, 100, function () { // Check if we've reached level 10 if (currentLevel >= 10) { // Game completed! LK.showYouWin(); return; } // Start next level currentLevel++; storage.currentLevel = currentLevel; timeLeft = gameTime; levelText.setText('Level: ' + currentLevel); targetScoreText.setText('Target: ' + getTargetScore(currentLevel)); scoreText.setText('Score: ' + LK.getScore()); timeText.setText('Time: ' + timeLeft); // Remove market UI marketBg.destroy(); // Reset game state inMarket = false; gameActive = true; // Generate new items generateItems(); // Reset claw position claw.x = 1024; claw.y = 350; claw.isDropping = false; claw.isRetracting = false; claw.grabbedItem = null; // Restart the game timer LK.clearInterval(gameTimer); gameTimer = LK.setInterval(function () { if (gameActive && !inMarket) { timeLeft--; timeText.setText('Time: ' + timeLeft); if (timeLeft <= 0) { gameActive = false; LK.clearInterval(gameTimer); // Check if player reached target score if (LK.getScore() >= getTargetScore(currentLevel)) { // Check if this was level 10 if (currentLevel >= 10) { // Game completed! LK.setTimeout(function () { LK.showYouWin(); }, 500); } else { // Level complete - show market LK.setTimeout(function () { showMarket(); }, 500); } } else { // Game over - didn't reach target LK.setTimeout(function () { // Reset level to 1 for next game currentLevel = 1; storage.currentLevel = 1; LK.showGameOver(); }, 500); } } } }, 1000); LK.getSound('collect').play(); }); continueButton.y = 200; marketBg.addChild(continueButton); } // Helper function to create market buttons function createMarketButton(text, x, y, onClick) { var button = new Container(); button.x = x; button.y = y; // Button background var bg = LK.getAsset('marketButtonBg', { anchorX: 0.5, anchorY: 0.5 }); button.addChild(bg); // Button text var buttonText = new Text2(text, { size: 40, fill: 0xFFFFFF }); buttonText.anchor.set(0.5, 0.5); button.addChild(buttonText); // Make button interactive button.down = function () { bg.tint = 0x6666CC; onClick(); }; button.up = function () { bg.tint = 0x4444AA; }; return button; } // Game timer gameTimer = LK.setInterval(function () { if (gameActive && !inMarket) { timeLeft--; timeText.setText('Time: ' + timeLeft); if (timeLeft <= 0) { gameActive = false; LK.clearInterval(gameTimer); // Check if player reached target score if (LK.getScore() >= getTargetScore(currentLevel)) { // Level complete - show market LK.setTimeout(function () { showMarket(); }, 500); } else { // Game over - didn't reach target LK.setTimeout(function () { // Reset level to 1 for next game currentLevel = 1; storage.currentLevel = 1; LK.showGameOver(); }, 500); } } } }, 1000); // Touch/click handler for dropping claw game.down = function (x, y, obj) { if (gameActive && !inMarket) { claw.drop(); } }; // Main game update loop game.update = function () { if (!gameActive || inMarket) return; // Check for item collection - only when claw (not cable) touches items if (claw.isDropping && !claw.grabbedItem) { for (var i = 0; i < items.length; i++) { var item = items[i]; // Check collision using distance-based detection focused on claw position // This ensures only the claw itself (not the cable) triggers collection var clawCenterX = claw.x; var clawCenterY = claw.y; var itemCenterX = item.x; var itemCenterY = item.y; var distance = Math.sqrt(Math.pow(clawCenterX - itemCenterX, 2) + Math.pow(clawCenterY - itemCenterY, 2)); var clawRadius = 40; // Approximate claw size var itemRadius = 50; // Approximate item size var clawTouchesItem = distance < clawRadius + itemRadius; if (clawTouchesItem) { claw.grabbedItem = item; claw.weight = item.weight; claw.isDropping = false; claw.isRetracting = true; break; } } } // Update score display scoreText.setText('Score: ' + LK.getScore()); }; // Play background music LK.playMusic('bgmusic');
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/****
* Classes
****/
var Claw = Container.expand(function () {
var self = Container.call(this);
var clawGraphics = self.attachAsset('claw', {
anchorX: 0.5,
anchorY: 0.5
});
// Cable removed - no longer visible
self.swingAngle = 0;
self.swingSpeed = 0.02;
self.swingRadius = 300;
self.centerX = 1024; // Center position
self.startX = 1024; // Starting X position - same as center
self.isDropping = false;
self.isRetracting = false;
self.dropSpeed = 8;
self.retractSpeed = 6;
self.startY = 350;
self.grabbedItem = null;
self.weight = 1;
self.isRetractingStarted = false;
self.update = function () {
if (!self.isDropping && !self.isRetracting) {
// Swing back and forth by rotating the claw
self.swingAngle += self.swingSpeed;
self.rotation = Math.sin(self.swingAngle) * 2.0; // Rotate between -2.0 and 2.0 radians for much wider swing, better matching visual angle
}
// Dropping is now handled by tween animation in drop() method
if (self.isRetracting && !self.isRetractingStarted) {
self.isRetractingStarted = true;
// Calculate distance back to start position
var distanceBack = Math.sqrt(Math.pow(self.startX - self.x, 2) + Math.pow(self.startY - self.y, 2));
// Base retraction speed (pixels per second) - slower when carrying items
var baseRetractSpeed = 600; // pixels per second when empty
var weightedRetractSpeed = baseRetractSpeed / self.weight; // Slower for heavier items
var retractDuration = distanceBack / weightedRetractSpeed * 1000; // Convert to milliseconds
// Use tween to move claw back to start position
tween(self, {
x: self.startX,
y: self.startY
}, {
duration: retractDuration,
easing: tween.linear,
onFinish: function onFinish() {
self.isRetracting = false;
self.isRetractingStarted = false;
// Use a small delay to ensure item collection happens cleanly
if (self.grabbedItem) {
LK.setTimeout(function () {
if (self.grabbedItem) {
// Double check item still exists
self.collectItem();
}
}, 50);
}
}
});
}
// Move grabbed item with claw
if (self.grabbedItem) {
self.grabbedItem.x = self.x;
self.grabbedItem.y = self.y + 40;
}
// Cable positioning removed - cable is now invisible
};
self.drop = function () {
if (!self.isDropping && !self.isRetracting) {
self.isDropping = true;
// Calculate target position based on current rotation
var targetDistance = 2400; // How far the claw should extend - increased to reach bottom of screen
// Use the actual rotation of the claw to determine direction
var angle = self.rotation + Math.PI / 2; // Adjust so 0 is straight down, and positive rotation is to the right
var targetX = self.centerX + Math.cos(angle) * targetDistance;
var targetY = self.startY + Math.sin(angle) * targetDistance;
// Ensure claw stays within screen bounds
if (targetX < 50) targetX = 50;
if (targetX > 1998) targetX = 1998;
// Calculate distance to target
var distance = Math.sqrt(Math.pow(targetX - self.x, 2) + Math.pow(targetY - self.y, 2));
// Use constant speed for dropping (pixels per second)
var dropSpeed = 800; // pixels per second
var dropDuration = distance / dropSpeed * 1000; // Convert to milliseconds
// Use tween to move claw directly to target position
tween(self, {
x: targetX,
y: targetY
}, {
duration: dropDuration,
easing: tween.linear,
onFinish: function onFinish() {
self.isDropping = false;
self.isRetracting = true;
}
});
LK.getSound('clawMove').play();
}
};
self.collectItem = function () {
if (self.grabbedItem) {
var itemToCollect = self.grabbedItem; // Store reference before clearing
self.grabbedItem = null; // Clear reference immediately to prevent double collection
self.weight = 1; // Reset weight immediately
// Add to score based on item type
var points = 0;
if (itemToCollect.itemType === 'gold') {
points = 50; // Fixed value for gold
} else if (itemToCollect.itemType === 'ruby') {
points = 70; // Fixed value for ruby
} else if (itemToCollect.itemType === 'emerald') {
points = 85; // Fixed value for emerald
} else if (itemToCollect.itemType === 'diamond') {
points = 100;
} else if (itemToCollect.itemType === 'rock') {
// If we have dynamite, use it to destroy rock
if (dynamiteCount > 0) {
dynamiteCount--;
dynamiteText.setText('Dynamite: ' + dynamiteCount);
// Flash screen yellow for dynamite use
LK.effects.flashScreen(0xFFFF00, 500);
points = 20; // Small reward for blowing up rock
// Auto-reset claw
self.isRetracting = false;
self.isRetractingStarted = false;
self.x = self.startX;
self.y = self.startY;
} else {
points = 10;
}
} else if (itemToCollect.itemType === 'pig') {
points = 150; // Higher value for pig with diamond
} else if (itemToCollect.itemType === 'tnt') {
// If we have dynamite, use it to destroy TNT
if (dynamiteCount > 0) {
dynamiteCount--;
dynamiteText.setText('Dynamite: ' + dynamiteCount);
// Flash screen yellow for dynamite use
LK.effects.flashScreen(0xFFFF00, 500);
points = 0;
// Auto-reset claw
self.isRetracting = false;
self.isRetractingStarted = false;
self.x = self.startX;
self.y = self.startY;
} else {
// TNT explodes and resets score to 0
LK.setScore(0);
scoreText.setText('Score: 0');
// Flash screen red for explosion effect
LK.effects.flashScreen(0xFF0000, 1000);
points = 0;
}
} else if (itemToCollect.itemType === 'mysteryBag') {
// Open mystery bag
if (itemToCollect.contents === 'dynamite') {
dynamiteCount++;
dynamiteText.setText('Dynamite: ' + dynamiteCount);
// Flash screen green for dynamite pickup
LK.effects.flashScreen(0x00FF00, 500);
points = 0;
} else if (itemToCollect.contents === 'diamond') {
points = 100;
} else if (itemToCollect.contents === 'gold') {
points = itemToCollect.goldValue;
}
}
if (itemToCollect.itemType !== 'tnt') {
LK.setScore(LK.getScore() + points);
scoreText.setText('Score: ' + LK.getScore());
}
// Remove item from items array
for (var i = items.length - 1; i >= 0; i--) {
if (items[i] === itemToCollect) {
items[i].destroy();
items.splice(i, 1);
break;
}
}
LK.getSound('collect').play();
}
};
return self;
});
var Miner = Container.expand(function () {
var self = Container.call(this);
// Create miner character using miner asset
var minerGraphics = self.attachAsset('miner', {
anchorX: 0.5,
anchorY: 1
});
// Add a "reel" arm/hand asset to simulate winding the claw
// We'll use the 'clawCable' asset as a makeshift reel handle for animation
var reelHandle = self.attachAsset('clawCable', {
anchorX: 0.5,
anchorY: 1
});
reelHandle.x = 0;
reelHandle.y = -80;
reelHandle.scaleX = 2.5;
reelHandle.scaleY = 0.5;
reelHandle.rotation = 0;
// Animate the reel handle when the claw is retracting
self.update = function () {
// If the global 'claw' is retracting, animate the reel handle
if (typeof claw !== "undefined" && claw.isRetracting) {
// Spin the handle
reelHandle.rotation += 0.3;
// Optionally, add a little up/down movement for fun
reelHandle.y = -80 + Math.sin(Date.now() / 120) * 8;
} else {
// Reset to default position
reelHandle.rotation = 0;
reelHandle.y = -80;
}
};
return self;
});
var MiningItem = Container.expand(function (itemType) {
var self = Container.call(this);
self.itemType = itemType;
var assetName = '';
var scale = 1;
if (itemType === 'gold') {
assetName = 'goldNugget';
self.weight = 1.5;
// Random scale between 0.5 and 1.8 for more variety
scale = 0.5 + Math.random() * 1.3;
self.weight *= scale; // Adjust weight based on size
} else if (itemType === 'diamond') {
assetName = 'diamond';
self.weight = 1;
} else if (itemType === 'ruby') {
assetName = 'ruby';
self.weight = 1.2;
} else if (itemType === 'emerald') {
assetName = 'emerald';
self.weight = 1.3;
} else if (itemType === 'rock') {
assetName = 'rock';
self.weight = 3;
// Random scale between 0.6 and 1.4
scale = 0.6 + Math.random() * 0.8;
self.weight *= scale; // Adjust weight based on size
} else if (itemType === 'tnt') {
assetName = 'tnt';
self.weight = 2;
}
// Create shadow first so it appears behind the item
var shadowGraphics = self.attachAsset(assetName, {
anchorX: 0.5,
anchorY: 0.5
});
shadowGraphics.tint = 0x000000; // Black shadow
shadowGraphics.alpha = 0.3; // Semi-transparent
shadowGraphics.scaleX = scale * 1.1; // Slightly larger than item
shadowGraphics.scaleY = scale * 0.6; // Flattened for shadow effect
shadowGraphics.x = 15; // Offset to the right
shadowGraphics.y = 20; // Offset down
var itemGraphics = self.attachAsset(assetName, {
anchorX: 0.5,
anchorY: 0.5
});
// Apply random scale
itemGraphics.scaleX = scale;
itemGraphics.scaleY = scale;
return self;
});
var MysteryBag = Container.expand(function () {
var self = Container.call(this);
// Create shadow first
var shadowGraphics = self.attachAsset('tnt', {
anchorX: 0.5,
anchorY: 0.5
});
shadowGraphics.tint = 0x000000; // Black shadow
shadowGraphics.alpha = 0.3; // Semi-transparent
shadowGraphics.scaleX = 1.3; // Slightly larger
shadowGraphics.scaleY = 0.8; // Flattened
shadowGraphics.x = 15; // Offset
shadowGraphics.y = 20;
// Create a mystery bag visual using a scaled TNT asset with different tint
var bagGraphics = self.attachAsset('tnt', {
anchorX: 0.5,
anchorY: 0.5
});
bagGraphics.tint = 0x8B4513; // Brown color for bag
bagGraphics.scaleX = 1.2;
bagGraphics.scaleY = 1.2;
// Add a question mark using text
var questionMark = new Text2('?', {
size: 60,
fill: 0xFFFFFF
});
questionMark.anchor.set(0.5, 0.5);
self.addChild(questionMark);
self.itemType = 'mysteryBag';
self.weight = 1.5;
// Randomly determine contents
var rand = Math.random();
if (rand < 0.3) {
// 30% chance for dynamite
self.contents = 'dynamite';
} else if (rand < 0.5) {
// 20% chance for diamond
self.contents = 'diamond';
} else {
// 50% chance for gold
self.contents = 'gold';
// Random gold value between 50-200
self.goldValue = Math.floor(Math.random() * 150) + 50;
}
return self;
});
var Pig = Container.expand(function () {
var self = Container.call(this);
// Create shadow first
var shadowGraphics = self.attachAsset('pig', {
anchorX: 0.5,
anchorY: 0.5
});
shadowGraphics.tint = 0x000000; // Black shadow
shadowGraphics.alpha = 0.3; // Semi-transparent
shadowGraphics.scaleX = 1.1; // Slightly larger
shadowGraphics.scaleY = 0.6; // Flattened
shadowGraphics.x = 15; // Offset
shadowGraphics.y = 20;
var pigGraphics = self.attachAsset('pig', {
anchorX: 0.5,
anchorY: 0.5
});
var diamond = self.attachAsset('diamond', {
anchorX: 0.5,
anchorY: 0.5
});
diamond.x = 0;
diamond.y = -10; // Position diamond in pig's "mouth"
diamond.scaleX = 0.6;
diamond.scaleY = 0.6;
// Random movement speed between 0.5 and 2.5
self.moveSpeed = 0.5 + Math.random() * 2;
// Random initial direction
self.direction = Math.random() < 0.5 ? -1 : 1;
// Random movement range between 150 and 350
self.moveRange = 150 + Math.random() * 200;
self.startX = 0;
self.itemType = 'pig';
self.weight = 2;
self.update = function () {
// Move pig back and forth
self.x += self.moveSpeed * self.direction;
if (self.x > self.startX + self.moveRange || self.x < self.startX - self.moveRange) {
self.direction *= -1;
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x87CEEB
});
/****
* Game Code
****/
// Game variables
// Game assets will be created dynamically
var claw;
var items = [];
var gameTime = 60; // 60 seconds per level
var timeLeft = gameTime;
var gameActive = true;
var scoreText;
var timeText;
var gameTimer;
var dynamiteCount = 0; // Track dynamite inventory
var dynamiteText; // UI for dynamite count
// Level system variables
var currentLevel = storage.currentLevel || 1;
var levelText; // UI for level display
var targetScoreText; // UI for target score
var inMarket = false; // Track if we're in market phase
// Calculate target score for current level
function getTargetScore(level) {
return 300 + (level - 1) * 150; // Level 1: 300, Level 2: 450, Level 3: 600, etc.
}
// Market prices
var marketPrices = {
time5: 100,
time10: 180,
time15: 250,
dynamite1: 80,
dynamite2: 150,
dynamite3: 200
};
// Create sky background
var sky = game.attachAsset('sky', {
x: 0,
y: 0
});
// Create ground
var ground = game.attachAsset('ground', {
x: 0,
y: 300
});
// Create miner character
var miner = game.addChild(new Miner());
miner.x = 1024;
miner.y = 300;
// Create claw
claw = game.addChild(new Claw());
claw.x = 1024;
claw.y = 350;
// Create UI elements
scoreText = new Text2('Score: 0', {
size: 80,
fill: 0xFFFFFF
});
scoreText.anchor.set(0, 0);
LK.gui.topLeft.addChild(scoreText);
scoreText.x = 120; // Avoid top-left menu area
timeText = new Text2('Time: 60', {
size: 80,
fill: 0xFFFFFF
});
timeText.anchor.set(1, 0);
LK.gui.topRight.addChild(timeText);
// Add dynamite counter UI
dynamiteText = new Text2('Dynamite: 0', {
size: 60,
fill: 0xFFFF00
});
dynamiteText.anchor.set(0.5, 0);
LK.gui.top.addChild(dynamiteText);
// Add level display
levelText = new Text2('Level: ' + currentLevel, {
size: 70,
fill: 0xFFFFFF
});
levelText.anchor.set(0, 0);
LK.gui.topLeft.addChild(levelText);
levelText.x = 120;
levelText.y = 90;
// Add target score display
targetScoreText = new Text2('Target: ' + getTargetScore(currentLevel), {
size: 60,
fill: 0x00FF00
});
targetScoreText.anchor.set(0, 0);
LK.gui.topLeft.addChild(targetScoreText);
targetScoreText.x = 120;
targetScoreText.y = 170;
// Generate random items underground
function generateItems() {
var occupiedPositions = []; // Track positions to prevent overlap
var minDistance = 120; // Minimum distance between items
// 1. Place gold nuggets (e.g. 8)
var goldCount = 8;
for (var i = 0; i < goldCount; i++) {
var gold = new MiningItem('gold');
// Find a position that doesn't overlap with existing items
var validPosition = false;
var attempts = 0;
var maxAttempts = 50;
while (!validPosition && attempts < maxAttempts) {
gold.x = Math.random() * 1800 + 124;
gold.y = Math.random() * 1200 + 800;
validPosition = true;
for (var j = 0; j < occupiedPositions.length; j++) {
var distance = Math.sqrt(Math.pow(gold.x - occupiedPositions[j].x, 2) + Math.pow(gold.y - occupiedPositions[j].y, 2));
if (distance < minDistance) {
validPosition = false;
break;
}
}
attempts++;
}
occupiedPositions.push({
x: gold.x,
y: gold.y
});
items.push(gold);
game.addChild(gold);
}
// 2. Place rubies (3)
var rubyCount = 3;
for (var i = 0; i < rubyCount; i++) {
var ruby = new MiningItem('ruby');
var validPosition = false;
var attempts = 0;
var maxAttempts = 50;
while (!validPosition && attempts < maxAttempts) {
ruby.x = Math.random() * 1800 + 124;
ruby.y = Math.random() * 1200 + 800;
validPosition = true;
for (var j = 0; j < occupiedPositions.length; j++) {
var distance = Math.sqrt(Math.pow(ruby.x - occupiedPositions[j].x, 2) + Math.pow(ruby.y - occupiedPositions[j].y, 2));
if (distance < minDistance) {
validPosition = false;
break;
}
}
attempts++;
}
occupiedPositions.push({
x: ruby.x,
y: ruby.y
});
items.push(ruby);
game.addChild(ruby);
}
// 3. Place emeralds (2)
var emeraldCount = 2;
for (var i = 0; i < emeraldCount; i++) {
var emerald = new MiningItem('emerald');
var validPosition = false;
var attempts = 0;
var maxAttempts = 50;
while (!validPosition && attempts < maxAttempts) {
emerald.x = Math.random() * 1800 + 124;
emerald.y = Math.random() * 1200 + 800;
validPosition = true;
for (var j = 0; j < occupiedPositions.length; j++) {
var distance = Math.sqrt(Math.pow(emerald.x - occupiedPositions[j].x, 2) + Math.pow(emerald.y - occupiedPositions[j].y, 2));
if (distance < minDistance) {
validPosition = false;
break;
}
}
attempts++;
}
occupiedPositions.push({
x: emerald.x,
y: emerald.y
});
items.push(emerald);
game.addChild(emerald);
}
// 4. Place diamonds (exactly 2)
var diamondCount = 2;
for (var i = 0; i < diamondCount; i++) {
var diamond = new MiningItem('diamond');
var validPosition = false;
var attempts = 0;
var maxAttempts = 50;
while (!validPosition && attempts < maxAttempts) {
diamond.x = Math.random() * 1800 + 124;
diamond.y = Math.random() * 1200 + 800;
validPosition = true;
for (var j = 0; j < occupiedPositions.length; j++) {
var distance = Math.sqrt(Math.pow(diamond.x - occupiedPositions[j].x, 2) + Math.pow(diamond.y - occupiedPositions[j].y, 2));
if (distance < minDistance) {
validPosition = false;
break;
}
}
attempts++;
}
occupiedPositions.push({
x: diamond.x,
y: diamond.y
});
items.push(diamond);
game.addChild(diamond);
}
// 5. Place rocks (e.g. 6)
var rockCount = 6;
for (var i = 0; i < rockCount; i++) {
var rock = new MiningItem('rock');
var validPosition = false;
var attempts = 0;
var maxAttempts = 50;
while (!validPosition && attempts < maxAttempts) {
rock.x = Math.random() * 1800 + 124;
rock.y = Math.random() * 1200 + 800;
validPosition = true;
for (var j = 0; j < occupiedPositions.length; j++) {
var distance = Math.sqrt(Math.pow(rock.x - occupiedPositions[j].x, 2) + Math.pow(rock.y - occupiedPositions[j].y, 2));
if (distance < minDistance) {
validPosition = false;
break;
}
}
attempts++;
}
occupiedPositions.push({
x: rock.x,
y: rock.y
});
items.push(rock);
game.addChild(rock);
}
// 6. Place TNT (up to 3)
var tntCount = 0;
var maxTnt = 3;
for (var i = 0; i < maxTnt; i++) {
var tnt = new MiningItem('tnt');
var validPosition = false;
var attempts = 0;
var maxAttempts = 50;
while (!validPosition && attempts < maxAttempts) {
tnt.x = Math.random() * 1800 + 124;
tnt.y = Math.random() * 1200 + 800;
validPosition = true;
for (var j = 0; j < occupiedPositions.length; j++) {
var distance = Math.sqrt(Math.pow(tnt.x - occupiedPositions[j].x, 2) + Math.pow(tnt.y - occupiedPositions[j].y, 2));
if (distance < minDistance) {
validPosition = false;
break;
}
}
attempts++;
}
occupiedPositions.push({
x: tnt.x,
y: tnt.y
});
items.push(tnt);
game.addChild(tnt);
}
// 7. Add mystery bags (maximum 2 per level)
var mysteryBagCount = Math.floor(Math.random() * 2) + 1; // 1 or 2 mystery bags
for (var i = 0; i < mysteryBagCount; i++) {
var mysteryBag = new MysteryBag();
var validPosition = false;
var attempts = 0;
var maxAttempts = 50;
while (!validPosition && attempts < maxAttempts) {
mysteryBag.x = Math.random() * 1800 + 124;
mysteryBag.y = Math.random() * 1200 + 800;
validPosition = true;
for (var j = 0; j < occupiedPositions.length; j++) {
var distance = Math.sqrt(Math.pow(mysteryBag.x - occupiedPositions[j].x, 2) + Math.pow(mysteryBag.y - occupiedPositions[j].y, 2));
if (distance < minDistance) {
validPosition = false;
break;
}
}
attempts++;
}
occupiedPositions.push({
x: mysteryBag.x,
y: mysteryBag.y
});
items.push(mysteryBag);
game.addChild(mysteryBag);
}
// 8. Add moving pigs with diamonds - exactly 3
var pigCount = 3;
for (var i = 0; i < pigCount; i++) {
var pig = new Pig();
// Find position that doesn't overlap with items
var validPosition = false;
var attempts = 0;
var maxAttempts = 50;
while (!validPosition && attempts < maxAttempts) {
pig.x = Math.random() * 1600 + 200;
pig.y = Math.random() * 600 + 1000;
validPosition = true;
for (var j = 0; j < occupiedPositions.length; j++) {
var distance = Math.sqrt(Math.pow(pig.x - occupiedPositions[j].x, 2) + Math.pow(pig.y - occupiedPositions[j].y, 2));
if (distance < minDistance) {
validPosition = false;
break;
}
}
attempts++;
}
pig.startX = pig.x;
occupiedPositions.push({
x: pig.x,
y: pig.y
});
items.push(pig);
game.addChild(pig);
}
}
// Initialize items
generateItems();
// Create market UI
function showMarket() {
inMarket = true;
gameActive = false;
// Halve the current score when entering market
LK.setScore(Math.floor(LK.getScore() / 2));
// Clear current game items
for (var i = items.length - 1; i >= 0; i--) {
items[i].destroy();
}
items = [];
// Create market background
var marketBg = new Container();
marketBg.x = 1024;
marketBg.y = 1366;
game.addChild(marketBg);
// Market title
var marketTitle = new Text2('MARKET', {
size: 120,
fill: 0xFFD700
});
marketTitle.anchor.set(0.5, 0.5);
marketTitle.y = -900;
marketBg.addChild(marketTitle);
// Level complete text
var levelCompleteText = new Text2('Level ' + currentLevel + ' Complete!', {
size: 80,
fill: 0x00FF00
});
levelCompleteText.anchor.set(0.5, 0.5);
levelCompleteText.y = -750;
marketBg.addChild(levelCompleteText);
// Score text (showing halved score)
var scoreInfo = new Text2('Your Score: ' + LK.getScore() + ' (50% deducted)', {
size: 60,
fill: 0xFFFFFF
});
scoreInfo.anchor.set(0.5, 0.5);
scoreInfo.y = -630;
marketBg.addChild(scoreInfo);
// Time upgrades
var timeTitle = new Text2('Time Upgrades:', {
size: 60,
fill: 0xFFFFFF
});
timeTitle.anchor.set(0.5, 0.5);
timeTitle.y = -480;
marketBg.addChild(timeTitle);
// +5 seconds button
var time5Button = createMarketButton('+5 Seconds - ' + marketPrices.time5 + ' pts', -400, -350, function () {
if (LK.getScore() >= marketPrices.time5) {
LK.setScore(LK.getScore() - marketPrices.time5);
gameTime += 5;
scoreInfo.setText('Your Score: ' + LK.getScore());
LK.getSound('collect').play();
}
});
marketBg.addChild(time5Button);
// +10 seconds button
var time10Button = createMarketButton('+10 Seconds - ' + marketPrices.time10 + ' pts', 0, -350, function () {
if (LK.getScore() >= marketPrices.time10) {
LK.setScore(LK.getScore() - marketPrices.time10);
gameTime += 10;
scoreInfo.setText('Your Score: ' + LK.getScore());
LK.getSound('collect').play();
}
});
marketBg.addChild(time10Button);
// +15 seconds button
var time15Button = createMarketButton('+15 Seconds - ' + marketPrices.time15 + ' pts', 400, -350, function () {
if (LK.getScore() >= marketPrices.time15) {
LK.setScore(LK.getScore() - marketPrices.time15);
gameTime += 15;
scoreInfo.setText('Your Score: ' + LK.getScore());
LK.getSound('collect').play();
}
});
marketBg.addChild(time15Button);
// Dynamite upgrades
var dynamiteTitle = new Text2('Dynamite Upgrades:', {
size: 60,
fill: 0xFFFFFF
});
dynamiteTitle.anchor.set(0.5, 0.5);
dynamiteTitle.y = -200;
marketBg.addChild(dynamiteTitle);
// +1 dynamite button
var dyn1Button = createMarketButton('+1 Dynamite - ' + marketPrices.dynamite1 + ' pts', -400, -70, function () {
if (LK.getScore() >= marketPrices.dynamite1) {
LK.setScore(LK.getScore() - marketPrices.dynamite1);
dynamiteCount += 1;
dynamiteText.setText('Dynamite: ' + dynamiteCount);
scoreInfo.setText('Your Score: ' + LK.getScore());
LK.getSound('collect').play();
}
});
marketBg.addChild(dyn1Button);
// +2 dynamite button
var dyn2Button = createMarketButton('+2 Dynamite - ' + marketPrices.dynamite2 + ' pts', 0, -70, function () {
if (LK.getScore() >= marketPrices.dynamite2) {
LK.setScore(LK.getScore() - marketPrices.dynamite2);
dynamiteCount += 2;
dynamiteText.setText('Dynamite: ' + dynamiteCount);
scoreInfo.setText('Your Score: ' + LK.getScore());
LK.getSound('collect').play();
}
});
marketBg.addChild(dyn2Button);
// +3 dynamite button
var dyn3Button = createMarketButton('+3 Dynamite - ' + marketPrices.dynamite3 + ' pts', 400, -70, function () {
if (LK.getScore() >= marketPrices.dynamite3) {
LK.setScore(LK.getScore() - marketPrices.dynamite3);
dynamiteCount += 3;
dynamiteText.setText('Dynamite: ' + dynamiteCount);
scoreInfo.setText('Your Score: ' + LK.getScore());
LK.getSound('collect').play();
}
});
marketBg.addChild(dyn3Button);
// Continue button
var continueButton = createMarketButton('Continue to Level ' + (currentLevel + 1), 0, 100, function () {
// Check if we've reached level 10
if (currentLevel >= 10) {
// Game completed!
LK.showYouWin();
return;
}
// Start next level
currentLevel++;
storage.currentLevel = currentLevel;
timeLeft = gameTime;
levelText.setText('Level: ' + currentLevel);
targetScoreText.setText('Target: ' + getTargetScore(currentLevel));
scoreText.setText('Score: ' + LK.getScore());
timeText.setText('Time: ' + timeLeft);
// Remove market UI
marketBg.destroy();
// Reset game state
inMarket = false;
gameActive = true;
// Generate new items
generateItems();
// Reset claw position
claw.x = 1024;
claw.y = 350;
claw.isDropping = false;
claw.isRetracting = false;
claw.grabbedItem = null;
// Restart the game timer
LK.clearInterval(gameTimer);
gameTimer = LK.setInterval(function () {
if (gameActive && !inMarket) {
timeLeft--;
timeText.setText('Time: ' + timeLeft);
if (timeLeft <= 0) {
gameActive = false;
LK.clearInterval(gameTimer);
// Check if player reached target score
if (LK.getScore() >= getTargetScore(currentLevel)) {
// Check if this was level 10
if (currentLevel >= 10) {
// Game completed!
LK.setTimeout(function () {
LK.showYouWin();
}, 500);
} else {
// Level complete - show market
LK.setTimeout(function () {
showMarket();
}, 500);
}
} else {
// Game over - didn't reach target
LK.setTimeout(function () {
// Reset level to 1 for next game
currentLevel = 1;
storage.currentLevel = 1;
LK.showGameOver();
}, 500);
}
}
}
}, 1000);
LK.getSound('collect').play();
});
continueButton.y = 200;
marketBg.addChild(continueButton);
}
// Helper function to create market buttons
function createMarketButton(text, x, y, onClick) {
var button = new Container();
button.x = x;
button.y = y;
// Button background
var bg = LK.getAsset('marketButtonBg', {
anchorX: 0.5,
anchorY: 0.5
});
button.addChild(bg);
// Button text
var buttonText = new Text2(text, {
size: 40,
fill: 0xFFFFFF
});
buttonText.anchor.set(0.5, 0.5);
button.addChild(buttonText);
// Make button interactive
button.down = function () {
bg.tint = 0x6666CC;
onClick();
};
button.up = function () {
bg.tint = 0x4444AA;
};
return button;
}
// Game timer
gameTimer = LK.setInterval(function () {
if (gameActive && !inMarket) {
timeLeft--;
timeText.setText('Time: ' + timeLeft);
if (timeLeft <= 0) {
gameActive = false;
LK.clearInterval(gameTimer);
// Check if player reached target score
if (LK.getScore() >= getTargetScore(currentLevel)) {
// Level complete - show market
LK.setTimeout(function () {
showMarket();
}, 500);
} else {
// Game over - didn't reach target
LK.setTimeout(function () {
// Reset level to 1 for next game
currentLevel = 1;
storage.currentLevel = 1;
LK.showGameOver();
}, 500);
}
}
}
}, 1000);
// Touch/click handler for dropping claw
game.down = function (x, y, obj) {
if (gameActive && !inMarket) {
claw.drop();
}
};
// Main game update loop
game.update = function () {
if (!gameActive || inMarket) return;
// Check for item collection - only when claw (not cable) touches items
if (claw.isDropping && !claw.grabbedItem) {
for (var i = 0; i < items.length; i++) {
var item = items[i];
// Check collision using distance-based detection focused on claw position
// This ensures only the claw itself (not the cable) triggers collection
var clawCenterX = claw.x;
var clawCenterY = claw.y;
var itemCenterX = item.x;
var itemCenterY = item.y;
var distance = Math.sqrt(Math.pow(clawCenterX - itemCenterX, 2) + Math.pow(clawCenterY - itemCenterY, 2));
var clawRadius = 40; // Approximate claw size
var itemRadius = 50; // Approximate item size
var clawTouchesItem = distance < clawRadius + itemRadius;
if (clawTouchesItem) {
claw.grabbedItem = item;
claw.weight = item.weight;
claw.isDropping = false;
claw.isRetracting = true;
break;
}
}
}
// Update score display
scoreText.setText('Score: ' + LK.getScore());
};
// Play background music
LK.playMusic('bgmusic');
claw for machine. In-Game asset. 2d. High contrast. No shadows
metal cable. In-Game asset. 2d. High contrast. No shadows
diamond. In-Game asset. 2d. High contrast. No shadows
gold nugget. In-Game asset. 2d. High contrast. No shadows
rock. In-Game asset. 2d. High contrast. No shadows
domuzcuk. In-Game asset. 2d. High contrast. No shadows
tnt box. In-Game asset. 2d. High contrast. No shadows
woman miner cartoon. In-Game asset. 2d. High contrast. No shadows
emerald. In-Game asset. 2d. High contrast. No shadows
ruby. In-Game asset. 2d. High contrast. No shadows
ground background side wiew. In-Game asset. 2d. High contrast. No shadows
blue sky wiew large scale. In-Game asset. 2d. High contrast. No shadows