/****
* Plugins
****/
var storage = LK.import("@upit/storage.v1");
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var Cash = Container.expand(function () {
var self = Container.call(this);
var cashGraphics = self.attachAsset('cash', {
anchorX: 0.5,
anchorY: 0.5
});
self.isBlinking = true;
self.canCollect = false;
self.blinkTimer = 0;
// Start blinking animation
tween(cashGraphics, {
alpha: 0
}, {
duration: 250,
easing: tween.linear,
onFinish: function onFinish() {
tween(cashGraphics, {
alpha: 1
}, {
duration: 250,
easing: tween.linear
});
}
});
self.update = function () {
if (self.isBlinking) {
self.blinkTimer++;
if (self.blinkTimer >= 120) {
// 2 seconds at 60fps
self.isBlinking = false;
self.canCollect = true;
tween.stop(cashGraphics, {
alpha: true
});
cashGraphics.alpha = 1;
} else if (self.blinkTimer % 30 === 0) {
// Blink every 0.5 seconds
if (cashGraphics.alpha === 1) {
tween(cashGraphics, {
alpha: 0
}, {
duration: 250,
easing: tween.linear
});
} else {
tween(cashGraphics, {
alpha: 1
}, {
duration: 250,
easing: tween.linear
});
}
}
}
};
});
// Guard class
var Guard = Container.expand(function () {
var self = Container.call(this);
var guardGraphics = self.attachAsset('guard', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 5 + Math.floor(score / 200);
self.lastX = 0;
self.lastY = 0;
self.update = function () {
// Guard movement logic will be handled in the game update loop
};
});
var PowerUp = Container.expand(function () {
var self = Container.call(this);
var powerUpGraphics = self.attachAsset('powerUp', {
anchorX: 0.5,
anchorY: 0.5
});
self.isBlinking = true;
self.canCollect = false;
self.blinkTimer = 0;
// Start blinking animation
tween(powerUpGraphics, {
alpha: 0
}, {
duration: 250,
easing: tween.linear,
onFinish: function onFinish() {
tween(powerUpGraphics, {
alpha: 1
}, {
duration: 250,
easing: tween.linear
});
}
});
self.update = function () {
if (self.isBlinking) {
self.blinkTimer++;
if (self.blinkTimer >= 120) {
// 2 seconds at 60fps
self.isBlinking = false;
self.canCollect = true;
tween.stop(powerUpGraphics, {
alpha: true
});
powerUpGraphics.alpha = 1;
} else if (self.blinkTimer % 30 === 0) {
// Blink every 0.5 seconds
if (powerUpGraphics.alpha === 1) {
tween(powerUpGraphics, {
alpha: 0
}, {
duration: 250,
easing: tween.linear
});
} else {
tween(powerUpGraphics, {
alpha: 1
}, {
duration: 250,
easing: tween.linear
});
}
}
}
};
});
//<Assets used in the game will automatically appear here>
// Thief class
var Thief = Container.expand(function () {
var self = Container.call(this);
var thiefGraphics = self.attachAsset('thief', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 9;
self.lastX = 0;
self.lastY = 0;
self.update = function () {
// Thief movement logic will be handled in the game update loop
};
});
// Trap class
var Trap = Container.expand(function () {
var self = Container.call(this);
var trapGraphics = self.attachAsset('trap', {
anchorX: 0.5,
anchorY: 0.5
});
self.update = function () {
// Trap logic if needed
};
});
var UpgradeScreen = Container.expand(function () {
var self = Container.call(this);
// Background
var bg = LK.getAsset('upgradeBackground', {
width: 2048,
height: 2732,
color: 0x000000,
shape: 'box',
anchorX: 0,
anchorY: 0,
alpha: 1.0
});
self.addChild(bg);
// Main Play button - large, centered
var playButton = self.attachAsset('continueButton', {
anchorX: 0.5,
anchorY: 0.5
});
playButton.x = 1024;
playButton.y = 1366;
// Money display with icon
var moneyIcon = self.attachAsset('moneyIcon', {
anchorX: 0.5,
anchorY: 0.5
});
moneyIcon.x = 1024;
moneyIcon.y = 800;
var moneyText = new Text2('Money: $0', {
size: 80,
fill: 0xFFFFFF
});
moneyText.anchor.set(0.5, 0.5);
moneyText.x = 1024;
moneyText.y = 850;
self.addChild(moneyText);
// Left upgrade button - Speed
var speedButton = self.attachAsset('speedButton', {
anchorX: 0.5,
anchorY: 0.5
});
speedButton.x = 600;
speedButton.y = 1800;
var speedCostText = new Text2('$100', {
size: 40,
fill: 0xFFFFFF
});
speedCostText.anchor.set(1, 1);
speedCostText.x = speedButton.x + speedButton.width / 2 - 120;
speedCostText.y = speedButton.y + speedButton.height / 2 - 90;
self.addChild(speedCostText);
// Right upgrade button - Coin Value upgrade
var coinValueButton = self.attachAsset('coinValueButton', {
anchorX: 0.5,
anchorY: 0.5
});
coinValueButton.x = 1448;
coinValueButton.y = 1800;
var coinValueCostText = new Text2('$200', {
size: 40,
fill: 0xFFFFFF
});
coinValueCostText.anchor.set(1, 1);
coinValueCostText.x = coinValueButton.x + coinValueButton.width / 2 - 120;
coinValueCostText.y = coinValueButton.y + coinValueButton.height / 2 - 90;
self.addChild(coinValueCostText);
self.updateDisplay = function () {
var totalMoney = storage.totalMoney || 0;
var speedLevel = storage.speedLevel || 1;
var coinValueLevel = storage.coinValueLevel || 1;
var speedCost = 100 * Math.pow(2, speedLevel - 1);
var coinValueCost = 200 * Math.pow(2, coinValueLevel - 1);
moneyText.setText('Money: $' + totalMoney);
speedCostText.setText('$' + speedCost);
coinValueCostText.setText('$' + coinValueCost);
if (totalMoney >= speedCost) {
speedCostText.fill = 0x00FF00;
} else {
speedCostText.fill = 0xFF0000;
}
if (totalMoney >= coinValueCost) {
coinValueCostText.fill = 0x00FF00;
} else {
coinValueCostText.fill = 0xFF0000;
}
};
speedButton.down = function (x, y, obj) {
var totalMoney = storage.totalMoney || 0;
var speedLevel = storage.speedLevel || 1;
var speedCost = 100 * Math.pow(2, speedLevel - 1);
if (totalMoney >= speedCost) {
storage.totalMoney = totalMoney - speedCost;
storage.speedLevel = speedLevel + 1;
// Update thief speed immediately if thief exists
if (thief) {
thief.speed = 9 + (storage.speedLevel - 1) * 2;
}
self.updateDisplay();
}
};
coinValueButton.down = function (x, y, obj) {
var totalMoney = storage.totalMoney || 0;
var coinValueLevel = storage.coinValueLevel || 1;
var coinValueCost = 200 * Math.pow(2, coinValueLevel - 1);
if (totalMoney >= coinValueCost) {
storage.totalMoney = totalMoney - coinValueCost;
storage.coinValueLevel = coinValueLevel + 1;
// Update money multiplier immediately
moneyMultiplier = storage.coinValueLevel;
self.updateDisplay();
}
};
playButton.down = function (x, y, obj) {
self.destroy();
// Restart the game without creating new LK.Game instance
startGame();
// Spawn police immediately at top-center
var police = new Guard();
police.x = 1024; // Center of screen horizontally
police.y = 100; // Top of screen
guards.push(police);
game.addChild(police);
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x808080 //Init game with grey background
});
/****
* Game Code
****/
// Reset all persistent storage values to initial state
storage.totalMoney = 0;
storage.speedLevel = 1;
storage.coinValueLevel = 1;
// Initialize game variables and UI elements
var thief;
var cashItems = [];
var traps = [];
var guards = [];
var powerUps = [];
var score = 0;
var scoreMultiplier = 1;
var coinValue = 10; // Base coin value
var moneyMultiplier = 1; // Initialize money multiplier
var gameRunning = false;
var guardSoundCooldown = 0; // Cooldown timer for guard sounds
var scoreTxt = new Text2('0', {
size: 150,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
// Hold-to-move mechanics
var isHolding = false;
var holdX = 0;
var holdY = 0;
function spawnPowerUp() {
var powerUp = new PowerUp();
powerUp.x = Math.random() * 2048;
powerUp.y = Math.random() * 2732;
powerUps.push(powerUp);
game.addChild(powerUp);
}
function startGame() {
// Clear existing game objects from screen
if (thief) {
thief.destroy();
thief = null;
}
cashItems.forEach(function (cash) {
cash.destroy();
});
traps.forEach(function (trap) {
trap.destroy();
});
guards.forEach(function (guard) {
guard.destroy();
});
powerUps.forEach(function (powerUp) {
powerUp.destroy();
});
// Clear existing arrays
cashItems = [];
traps = [];
guards = [];
powerUps = [];
score = 0;
scoreMultiplier = 1; // Reset powerup multiplier on new game
// Initialize money multiplier from storage (starts at 1, increases by 1 each upgrade)
moneyMultiplier = storage.coinValueLevel || 1;
coinValue = 10; // Base coin value stays constant for scoring
// Create thief with upgraded speed
thief = game.addChild(new Thief());
thief.x = 1024;
thief.y = 1366;
thief.speed = 9 + (storage.speedLevel - 1) * 2;
// Reset score display
scoreTxt.setText('0');
LK.setScore(0);
// Reset hold state
isHolding = false;
gameRunning = true;
// Reset spawn tracking for guards
game.lastSpawnScore = 0;
// Reset cash collection counter for guard speed increases
game.cashCollected = 0;
// Spawn initial police at score 0
var initialGuard = new Guard();
initialGuard.x = 1024; // Center of screen horizontally
initialGuard.y = 100; // Top of screen
guards.push(initialGuard);
game.addChild(initialGuard);
}
// Start the game
startGame();
game.move = function (x, y, obj) {
if (isHolding) {
holdX = x;
holdY = y;
}
// Decrease guard sound cooldown
if (guardSoundCooldown > 0) {
guardSoundCooldown--;
}
};
game.up = function (x, y, obj) {
isHolding = false;
};
function spawnCash() {
var cash = new Cash();
cash.x = Math.random() * 2048;
cash.y = Math.random() * 2732;
cashItems.push(cash);
game.addChild(cash);
}
function spawnTrap() {
var trap = new Trap();
trap.x = Math.random() * 2048;
trap.y = Math.random() * 2732;
traps.push(trap);
game.addChild(trap);
}
function spawnGuard() {
var guard = new Guard();
// Spawn at one of the four corners randomly
var corners = [{
x: 0,
y: 0
},
// Top-left
{
x: 2048,
y: 0
},
// Top-right
{
x: 0,
y: 2732
},
// Bottom-left
{
x: 2048,
y: 2732
} // Bottom-right
];
var randomCorner = corners[Math.floor(Math.random() * corners.length)];
guard.x = randomCorner.x;
guard.y = randomCorner.y;
guards.push(guard);
game.addChild(guard);
}
game.down = function (x, y, obj) {
// Start holding movement
isHolding = true;
holdX = x;
holdY = y;
};
game.update = function () {
for (var i = cashItems.length - 1; i >= 0; i--) {
if (thief && cashItems[i].canCollect && thief.intersects(cashItems[i])) {
// Score uses base coin value
score += coinValue * scoreMultiplier;
LK.setScore(score);
scoreTxt.setText(score);
// Money earned uses both coin value, money multiplier, and score multiplier from powerups
// Ensure minimum 1:1 ratio of points to money with upgrade scaling
var baseMoneyEarned = coinValue * moneyMultiplier * scoreMultiplier;
var minimumMoneyEarned = coinValue * moneyMultiplier * scoreMultiplier; // Ensure at least 1:1 ratio with upgrades
var moneyEarned = Math.max(baseMoneyEarned, minimumMoneyEarned);
storage.totalMoney = (storage.totalMoney || 0) + moneyEarned;
cashItems[i].destroy();
cashItems.splice(i, 1);
LK.getSound('CashCollect').play();
// Increase guard speed every 3 cash collections
if (!game.cashCollected) game.cashCollected = 0;
game.cashCollected++;
if (game.cashCollected % 3 === 0) {
// Increase speed of all existing guards
guards.forEach(function (guard) {
guard.speed += 0.2;
});
}
}
}
for (var i = traps.length - 1; i >= 0; i--) {
if (thief && thief.intersects(traps[i])) {
// Clear game state before showing upgrade screen
thief.destroy();
thief = null;
cashItems.forEach(function (cash) {
cash.destroy();
});
traps.forEach(function (trap) {
trap.destroy();
});
guards.forEach(function (guard) {
guard.destroy();
});
powerUps.forEach(function (powerUp) {
powerUp.destroy();
});
cashItems = [];
traps = [];
guards = [];
powerUps = [];
// Show upgrade screen instead of game over
gameRunning = false;
var upgradeScreen = new UpgradeScreen();
game.addChild(upgradeScreen);
upgradeScreen.updateDisplay();
return;
}
}
for (var i = guards.length - 1; i >= 0; i--) {
// Check guard collision with thief
if (thief && thief.intersects(guards[i])) {
// Clear game state before showing upgrade screen
thief.destroy();
thief = null;
cashItems.forEach(function (cash) {
cash.destroy();
});
traps.forEach(function (trap) {
trap.destroy();
});
guards.forEach(function (guard) {
guard.destroy();
});
powerUps.forEach(function (powerUp) {
powerUp.destroy();
});
cashItems = [];
traps = [];
guards = [];
powerUps = [];
// Show upgrade screen instead of game over
gameRunning = false;
var upgradeScreen = new UpgradeScreen();
game.addChild(upgradeScreen);
upgradeScreen.updateDisplay();
return;
}
// Check guard collision with traps
for (var j = traps.length - 1; j >= 0; j--) {
if (guards[i] && guards[i].intersects(traps[j])) {
// Destroy both guard and trap
guards[i].destroy();
traps[j].destroy();
guards.splice(i, 1);
traps.splice(j, 1);
break; // Exit trap loop since guard is destroyed
}
}
}
if (gameRunning && LK.ticks % 120 == 0) {
spawnCash();
}
if (gameRunning && LK.ticks % 300 == 0 && traps.length < 7) {
spawnTrap();
}
// Spawn guards every 100 points
if (gameRunning) {
// Check if we just reached this 100 point milestone
if (!game.lastSpawnScore) game.lastSpawnScore = 0;
if (Math.floor(score / 100) > Math.floor(game.lastSpawnScore / 100)) {
spawnGuard();
LK.getSound('Spawn').play();
game.lastSpawnScore = score;
}
}
if (gameRunning && LK.ticks % 900 == 0) {
spawnPowerUp();
}
for (var i = powerUps.length - 1; i >= 0; i--) {
if (thief && powerUps[i].canCollect && thief.intersects(powerUps[i])) {
scoreMultiplier += 1;
LK.getSound('PowerUpCollect').play();
powerUps[i].destroy();
powerUps.splice(i, 1);
}
}
// Move thief based on hold position
if (isHolding && thief) {
var dx = holdX - thief.x;
var dy = holdY - thief.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance > thief.speed) {
// Normalize direction and apply thief speed
var moveX = dx / distance * thief.speed;
var moveY = dy / distance * thief.speed;
thief.x += moveX;
thief.y += moveY;
// Calculate rotation angle based on movement direction
var angle = Math.atan2(moveY, moveX);
// Smoothly rotate to face movement direction
tween(thief, {
rotation: angle
}, {
duration: 100,
easing: tween.easeOut
});
} else {
// Close enough to hold position, snap to position
thief.x = holdX;
thief.y = holdY;
}
}
if (thief) {
guards.forEach(function (guard) {
// Calculate distance to thief before moving
var dx = thief.x - guard.x;
var dy = thief.y - guard.y;
var distance = Math.sqrt(dx * dx + dy * dy);
// Check if guard is getting close to thief and wasn't close before
if (!guard.lastWasClose) guard.lastWasClose = false;
var isCloseNow = distance < 400; // Close distance threshold
if (!guard.lastWasClose && isCloseNow && guardSoundCooldown <= 0) {
// Guard just got close to player, play spawn sound with cooldown
LK.getSound('Spawn').play();
guardSoundCooldown = 120; // Set 2 second cooldown (120 ticks at 60fps)
}
// Update last close state
guard.lastWasClose = isCloseNow;
// Smooth directional movement toward thief
if (distance > 0) {
// Normalize direction vector
var moveX = dx / distance * guard.speed;
var moveY = dy / distance * guard.speed;
// Move guard toward thief
guard.x += moveX;
guard.y += moveY;
// Calculate rotation angle based on movement direction
var angle = Math.atan2(moveY, moveX);
// Smoothly rotate to face movement direction
tween(guard, {
rotation: angle
}, {
duration: 50,
easing: tween.easeOut
});
}
});
}
}; /****
* Plugins
****/
var storage = LK.import("@upit/storage.v1");
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var Cash = Container.expand(function () {
var self = Container.call(this);
var cashGraphics = self.attachAsset('cash', {
anchorX: 0.5,
anchorY: 0.5
});
self.isBlinking = true;
self.canCollect = false;
self.blinkTimer = 0;
// Start blinking animation
tween(cashGraphics, {
alpha: 0
}, {
duration: 250,
easing: tween.linear,
onFinish: function onFinish() {
tween(cashGraphics, {
alpha: 1
}, {
duration: 250,
easing: tween.linear
});
}
});
self.update = function () {
if (self.isBlinking) {
self.blinkTimer++;
if (self.blinkTimer >= 120) {
// 2 seconds at 60fps
self.isBlinking = false;
self.canCollect = true;
tween.stop(cashGraphics, {
alpha: true
});
cashGraphics.alpha = 1;
} else if (self.blinkTimer % 30 === 0) {
// Blink every 0.5 seconds
if (cashGraphics.alpha === 1) {
tween(cashGraphics, {
alpha: 0
}, {
duration: 250,
easing: tween.linear
});
} else {
tween(cashGraphics, {
alpha: 1
}, {
duration: 250,
easing: tween.linear
});
}
}
}
};
});
// Guard class
var Guard = Container.expand(function () {
var self = Container.call(this);
var guardGraphics = self.attachAsset('guard', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 5 + Math.floor(score / 200);
self.lastX = 0;
self.lastY = 0;
self.update = function () {
// Guard movement logic will be handled in the game update loop
};
});
var PowerUp = Container.expand(function () {
var self = Container.call(this);
var powerUpGraphics = self.attachAsset('powerUp', {
anchorX: 0.5,
anchorY: 0.5
});
self.isBlinking = true;
self.canCollect = false;
self.blinkTimer = 0;
// Start blinking animation
tween(powerUpGraphics, {
alpha: 0
}, {
duration: 250,
easing: tween.linear,
onFinish: function onFinish() {
tween(powerUpGraphics, {
alpha: 1
}, {
duration: 250,
easing: tween.linear
});
}
});
self.update = function () {
if (self.isBlinking) {
self.blinkTimer++;
if (self.blinkTimer >= 120) {
// 2 seconds at 60fps
self.isBlinking = false;
self.canCollect = true;
tween.stop(powerUpGraphics, {
alpha: true
});
powerUpGraphics.alpha = 1;
} else if (self.blinkTimer % 30 === 0) {
// Blink every 0.5 seconds
if (powerUpGraphics.alpha === 1) {
tween(powerUpGraphics, {
alpha: 0
}, {
duration: 250,
easing: tween.linear
});
} else {
tween(powerUpGraphics, {
alpha: 1
}, {
duration: 250,
easing: tween.linear
});
}
}
}
};
});
//<Assets used in the game will automatically appear here>
// Thief class
var Thief = Container.expand(function () {
var self = Container.call(this);
var thiefGraphics = self.attachAsset('thief', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 9;
self.lastX = 0;
self.lastY = 0;
self.update = function () {
// Thief movement logic will be handled in the game update loop
};
});
// Trap class
var Trap = Container.expand(function () {
var self = Container.call(this);
var trapGraphics = self.attachAsset('trap', {
anchorX: 0.5,
anchorY: 0.5
});
self.update = function () {
// Trap logic if needed
};
});
var UpgradeScreen = Container.expand(function () {
var self = Container.call(this);
// Background
var bg = LK.getAsset('upgradeBackground', {
width: 2048,
height: 2732,
color: 0x000000,
shape: 'box',
anchorX: 0,
anchorY: 0,
alpha: 1.0
});
self.addChild(bg);
// Main Play button - large, centered
var playButton = self.attachAsset('continueButton', {
anchorX: 0.5,
anchorY: 0.5
});
playButton.x = 1024;
playButton.y = 1366;
// Money display with icon
var moneyIcon = self.attachAsset('moneyIcon', {
anchorX: 0.5,
anchorY: 0.5
});
moneyIcon.x = 1024;
moneyIcon.y = 800;
var moneyText = new Text2('Money: $0', {
size: 80,
fill: 0xFFFFFF
});
moneyText.anchor.set(0.5, 0.5);
moneyText.x = 1024;
moneyText.y = 850;
self.addChild(moneyText);
// Left upgrade button - Speed
var speedButton = self.attachAsset('speedButton', {
anchorX: 0.5,
anchorY: 0.5
});
speedButton.x = 600;
speedButton.y = 1800;
var speedCostText = new Text2('$100', {
size: 40,
fill: 0xFFFFFF
});
speedCostText.anchor.set(1, 1);
speedCostText.x = speedButton.x + speedButton.width / 2 - 120;
speedCostText.y = speedButton.y + speedButton.height / 2 - 90;
self.addChild(speedCostText);
// Right upgrade button - Coin Value upgrade
var coinValueButton = self.attachAsset('coinValueButton', {
anchorX: 0.5,
anchorY: 0.5
});
coinValueButton.x = 1448;
coinValueButton.y = 1800;
var coinValueCostText = new Text2('$200', {
size: 40,
fill: 0xFFFFFF
});
coinValueCostText.anchor.set(1, 1);
coinValueCostText.x = coinValueButton.x + coinValueButton.width / 2 - 120;
coinValueCostText.y = coinValueButton.y + coinValueButton.height / 2 - 90;
self.addChild(coinValueCostText);
self.updateDisplay = function () {
var totalMoney = storage.totalMoney || 0;
var speedLevel = storage.speedLevel || 1;
var coinValueLevel = storage.coinValueLevel || 1;
var speedCost = 100 * Math.pow(2, speedLevel - 1);
var coinValueCost = 200 * Math.pow(2, coinValueLevel - 1);
moneyText.setText('Money: $' + totalMoney);
speedCostText.setText('$' + speedCost);
coinValueCostText.setText('$' + coinValueCost);
if (totalMoney >= speedCost) {
speedCostText.fill = 0x00FF00;
} else {
speedCostText.fill = 0xFF0000;
}
if (totalMoney >= coinValueCost) {
coinValueCostText.fill = 0x00FF00;
} else {
coinValueCostText.fill = 0xFF0000;
}
};
speedButton.down = function (x, y, obj) {
var totalMoney = storage.totalMoney || 0;
var speedLevel = storage.speedLevel || 1;
var speedCost = 100 * Math.pow(2, speedLevel - 1);
if (totalMoney >= speedCost) {
storage.totalMoney = totalMoney - speedCost;
storage.speedLevel = speedLevel + 1;
// Update thief speed immediately if thief exists
if (thief) {
thief.speed = 9 + (storage.speedLevel - 1) * 2;
}
self.updateDisplay();
}
};
coinValueButton.down = function (x, y, obj) {
var totalMoney = storage.totalMoney || 0;
var coinValueLevel = storage.coinValueLevel || 1;
var coinValueCost = 200 * Math.pow(2, coinValueLevel - 1);
if (totalMoney >= coinValueCost) {
storage.totalMoney = totalMoney - coinValueCost;
storage.coinValueLevel = coinValueLevel + 1;
// Update money multiplier immediately
moneyMultiplier = storage.coinValueLevel;
self.updateDisplay();
}
};
playButton.down = function (x, y, obj) {
self.destroy();
// Restart the game without creating new LK.Game instance
startGame();
// Spawn police immediately at top-center
var police = new Guard();
police.x = 1024; // Center of screen horizontally
police.y = 100; // Top of screen
guards.push(police);
game.addChild(police);
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x808080 //Init game with grey background
});
/****
* Game Code
****/
// Reset all persistent storage values to initial state
storage.totalMoney = 0;
storage.speedLevel = 1;
storage.coinValueLevel = 1;
// Initialize game variables and UI elements
var thief;
var cashItems = [];
var traps = [];
var guards = [];
var powerUps = [];
var score = 0;
var scoreMultiplier = 1;
var coinValue = 10; // Base coin value
var moneyMultiplier = 1; // Initialize money multiplier
var gameRunning = false;
var guardSoundCooldown = 0; // Cooldown timer for guard sounds
var scoreTxt = new Text2('0', {
size: 150,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
// Hold-to-move mechanics
var isHolding = false;
var holdX = 0;
var holdY = 0;
function spawnPowerUp() {
var powerUp = new PowerUp();
powerUp.x = Math.random() * 2048;
powerUp.y = Math.random() * 2732;
powerUps.push(powerUp);
game.addChild(powerUp);
}
function startGame() {
// Clear existing game objects from screen
if (thief) {
thief.destroy();
thief = null;
}
cashItems.forEach(function (cash) {
cash.destroy();
});
traps.forEach(function (trap) {
trap.destroy();
});
guards.forEach(function (guard) {
guard.destroy();
});
powerUps.forEach(function (powerUp) {
powerUp.destroy();
});
// Clear existing arrays
cashItems = [];
traps = [];
guards = [];
powerUps = [];
score = 0;
scoreMultiplier = 1; // Reset powerup multiplier on new game
// Initialize money multiplier from storage (starts at 1, increases by 1 each upgrade)
moneyMultiplier = storage.coinValueLevel || 1;
coinValue = 10; // Base coin value stays constant for scoring
// Create thief with upgraded speed
thief = game.addChild(new Thief());
thief.x = 1024;
thief.y = 1366;
thief.speed = 9 + (storage.speedLevel - 1) * 2;
// Reset score display
scoreTxt.setText('0');
LK.setScore(0);
// Reset hold state
isHolding = false;
gameRunning = true;
// Reset spawn tracking for guards
game.lastSpawnScore = 0;
// Reset cash collection counter for guard speed increases
game.cashCollected = 0;
// Spawn initial police at score 0
var initialGuard = new Guard();
initialGuard.x = 1024; // Center of screen horizontally
initialGuard.y = 100; // Top of screen
guards.push(initialGuard);
game.addChild(initialGuard);
}
// Start the game
startGame();
game.move = function (x, y, obj) {
if (isHolding) {
holdX = x;
holdY = y;
}
// Decrease guard sound cooldown
if (guardSoundCooldown > 0) {
guardSoundCooldown--;
}
};
game.up = function (x, y, obj) {
isHolding = false;
};
function spawnCash() {
var cash = new Cash();
cash.x = Math.random() * 2048;
cash.y = Math.random() * 2732;
cashItems.push(cash);
game.addChild(cash);
}
function spawnTrap() {
var trap = new Trap();
trap.x = Math.random() * 2048;
trap.y = Math.random() * 2732;
traps.push(trap);
game.addChild(trap);
}
function spawnGuard() {
var guard = new Guard();
// Spawn at one of the four corners randomly
var corners = [{
x: 0,
y: 0
},
// Top-left
{
x: 2048,
y: 0
},
// Top-right
{
x: 0,
y: 2732
},
// Bottom-left
{
x: 2048,
y: 2732
} // Bottom-right
];
var randomCorner = corners[Math.floor(Math.random() * corners.length)];
guard.x = randomCorner.x;
guard.y = randomCorner.y;
guards.push(guard);
game.addChild(guard);
}
game.down = function (x, y, obj) {
// Start holding movement
isHolding = true;
holdX = x;
holdY = y;
};
game.update = function () {
for (var i = cashItems.length - 1; i >= 0; i--) {
if (thief && cashItems[i].canCollect && thief.intersects(cashItems[i])) {
// Score uses base coin value
score += coinValue * scoreMultiplier;
LK.setScore(score);
scoreTxt.setText(score);
// Money earned uses both coin value, money multiplier, and score multiplier from powerups
// Ensure minimum 1:1 ratio of points to money with upgrade scaling
var baseMoneyEarned = coinValue * moneyMultiplier * scoreMultiplier;
var minimumMoneyEarned = coinValue * moneyMultiplier * scoreMultiplier; // Ensure at least 1:1 ratio with upgrades
var moneyEarned = Math.max(baseMoneyEarned, minimumMoneyEarned);
storage.totalMoney = (storage.totalMoney || 0) + moneyEarned;
cashItems[i].destroy();
cashItems.splice(i, 1);
LK.getSound('CashCollect').play();
// Increase guard speed every 3 cash collections
if (!game.cashCollected) game.cashCollected = 0;
game.cashCollected++;
if (game.cashCollected % 3 === 0) {
// Increase speed of all existing guards
guards.forEach(function (guard) {
guard.speed += 0.2;
});
}
}
}
for (var i = traps.length - 1; i >= 0; i--) {
if (thief && thief.intersects(traps[i])) {
// Clear game state before showing upgrade screen
thief.destroy();
thief = null;
cashItems.forEach(function (cash) {
cash.destroy();
});
traps.forEach(function (trap) {
trap.destroy();
});
guards.forEach(function (guard) {
guard.destroy();
});
powerUps.forEach(function (powerUp) {
powerUp.destroy();
});
cashItems = [];
traps = [];
guards = [];
powerUps = [];
// Show upgrade screen instead of game over
gameRunning = false;
var upgradeScreen = new UpgradeScreen();
game.addChild(upgradeScreen);
upgradeScreen.updateDisplay();
return;
}
}
for (var i = guards.length - 1; i >= 0; i--) {
// Check guard collision with thief
if (thief && thief.intersects(guards[i])) {
// Clear game state before showing upgrade screen
thief.destroy();
thief = null;
cashItems.forEach(function (cash) {
cash.destroy();
});
traps.forEach(function (trap) {
trap.destroy();
});
guards.forEach(function (guard) {
guard.destroy();
});
powerUps.forEach(function (powerUp) {
powerUp.destroy();
});
cashItems = [];
traps = [];
guards = [];
powerUps = [];
// Show upgrade screen instead of game over
gameRunning = false;
var upgradeScreen = new UpgradeScreen();
game.addChild(upgradeScreen);
upgradeScreen.updateDisplay();
return;
}
// Check guard collision with traps
for (var j = traps.length - 1; j >= 0; j--) {
if (guards[i] && guards[i].intersects(traps[j])) {
// Destroy both guard and trap
guards[i].destroy();
traps[j].destroy();
guards.splice(i, 1);
traps.splice(j, 1);
break; // Exit trap loop since guard is destroyed
}
}
}
if (gameRunning && LK.ticks % 120 == 0) {
spawnCash();
}
if (gameRunning && LK.ticks % 300 == 0 && traps.length < 7) {
spawnTrap();
}
// Spawn guards every 100 points
if (gameRunning) {
// Check if we just reached this 100 point milestone
if (!game.lastSpawnScore) game.lastSpawnScore = 0;
if (Math.floor(score / 100) > Math.floor(game.lastSpawnScore / 100)) {
spawnGuard();
LK.getSound('Spawn').play();
game.lastSpawnScore = score;
}
}
if (gameRunning && LK.ticks % 900 == 0) {
spawnPowerUp();
}
for (var i = powerUps.length - 1; i >= 0; i--) {
if (thief && powerUps[i].canCollect && thief.intersects(powerUps[i])) {
scoreMultiplier += 1;
LK.getSound('PowerUpCollect').play();
powerUps[i].destroy();
powerUps.splice(i, 1);
}
}
// Move thief based on hold position
if (isHolding && thief) {
var dx = holdX - thief.x;
var dy = holdY - thief.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance > thief.speed) {
// Normalize direction and apply thief speed
var moveX = dx / distance * thief.speed;
var moveY = dy / distance * thief.speed;
thief.x += moveX;
thief.y += moveY;
// Calculate rotation angle based on movement direction
var angle = Math.atan2(moveY, moveX);
// Smoothly rotate to face movement direction
tween(thief, {
rotation: angle
}, {
duration: 100,
easing: tween.easeOut
});
} else {
// Close enough to hold position, snap to position
thief.x = holdX;
thief.y = holdY;
}
}
if (thief) {
guards.forEach(function (guard) {
// Calculate distance to thief before moving
var dx = thief.x - guard.x;
var dy = thief.y - guard.y;
var distance = Math.sqrt(dx * dx + dy * dy);
// Check if guard is getting close to thief and wasn't close before
if (!guard.lastWasClose) guard.lastWasClose = false;
var isCloseNow = distance < 400; // Close distance threshold
if (!guard.lastWasClose && isCloseNow && guardSoundCooldown <= 0) {
// Guard just got close to player, play spawn sound with cooldown
LK.getSound('Spawn').play();
guardSoundCooldown = 120; // Set 2 second cooldown (120 ticks at 60fps)
}
// Update last close state
guard.lastWasClose = isCloseNow;
// Smooth directional movement toward thief
if (distance > 0) {
// Normalize direction vector
var moveX = dx / distance * guard.speed;
var moveY = dy / distance * guard.speed;
// Move guard toward thief
guard.x += moveX;
guard.y += moveY;
// Calculate rotation angle based on movement direction
var angle = Math.atan2(moveY, moveX);
// Smoothly rotate to face movement direction
tween(guard, {
rotation: angle
}, {
duration: 50,
easing: tween.easeOut
});
}
});
}
};
A stack of money. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
A trap. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
Powerup about cash. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
UΜst tarafta incarse speed yazacak alt tarafta cost: uΜst taraf koyu beyaz alt taraf acΜ§Δ±k pastel yesΜ§il olacak. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat bu bir kutu icΜ§i dolu
UΜzerinde Play Gain yazan ve geri doΜnme isΜ§areti olan icΜ§i dolu buton, koyu pastel yesΜ§il renkte yazΔ±lar beyaz renkte . No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
IΜncarse speed yazΔ±sΔ± Incarse money olsun
IΜcΜ§inde yazΔ± olmasΔ±n. duΜz beyaz renk ile dolu olsun cΜ§ercΜ§evenin icΜ§i
Bu bir oyun menuΜsuΜ arkaplanΔ±, elinde para cΜ§antasΔ± tutan 2d bir hΔ±rsΔ±z altΔ±nlar ve paralarΔ±n oldugΜu bir odada ekrana bakΔ±yor. canlΔ± renkler. In-Game asset. 2d. High contrast. No shadows
Arkadaki sΜ§ey para cΜ§antasΔ±, ortadaki sΜ§ey hΔ±rsΔ±zΔ±n siyah beresi. yanlara dogΜru cΜ§Δ±kanlar hΔ±rsΔ±nΔ±z omuzlarΔ±. . No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
KΔ±zgΔ±n bakΔ±sΜ§lΔ± olsun