User prompt
Gold Rush Claw
Initial prompt
Create Gold Miner-style game where each player controls a claw that swings back and forth to grab gold and rocks underground. Players must time their grabs to collect valuable items before the time runs out. Each item has different weight and value. There are rocks, gold nuggets, diamonds, and power-ups. Add a timer, score counter, and shop between levels where players can buy power-ups like dynamite or stronger claws. Use colorful cartoon graphics, a western mining theme, and simple controls (click or tap to grab). The game should support local multiplayer or solo mode, and levels should get harder over time with moving obstacles or limited vision.
/**** * 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