/****
* 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