/****
* Classes
****/
// Box class: represents a clickable box that appears randomly on the screen
var Box = Container.expand(function () {
var self = Container.call(this);
// Attach a box asset, centered
var boxAsset = self.attachAsset('box', {
anchorX: 0.5,
anchorY: 0.5
});
// Track lastX, lastY for event transitions
self.lastX = 0;
self.lastY = 0;
self.lastWasDown = false;
// Called when the box is pressed/touched
self.down = function (x, y, obj) {
if (!self.lastWasDown) {
self.lastWasDown = true;
// Notify game that this box was clicked
if (typeof onBoxClicked === "function") {
onBoxClicked(self);
}
}
};
// Called when the box is released
self.up = function (x, y, obj) {
self.lastWasDown = false;
};
// Called every tick
self.update = function () {
// No movement, but could add animations here
};
return self;
});
// DecoyBox class: a misleading box that penalizes the player if tapped
var DecoyBox = Container.expand(function () {
var self = Container.call(this);
// Attach a box asset, but with a different color to distinguish (e.g. red)
var decoyAsset = self.attachAsset('box', {
anchorX: 0.5,
anchorY: 0.5,
tint: 0xD83318 // Red tint for decoy
});
self.lastX = 0;
self.lastY = 0;
self.lastWasDown = false;
// Called when the decoy box is pressed/touched
self.down = function (x, y, obj) {
if (!self.lastWasDown) {
self.lastWasDown = true;
if (typeof onDecoyBoxClicked === "function") {
onDecoyBoxClicked(self);
}
}
};
self.up = function (x, y, obj) {
self.lastWasDown = false;
};
self.update = function () {};
return self;
});
/****
* Initialize Game
****/
// Core game variables
var game = new LK.Game({
backgroundColor: 0x000000
});
/****
* Game Code
****/
// Core game variables
var currentBox = null; // The currently visible box
var currentDecoy = null; // The currently visible decoy box
var score = 0; // Player's score
var misses = 0; // Number of missed boxes
var boxLifetime = 1200; // ms, how long a box stays visible (decreases with difficulty)
var minBoxLifetime = 500; // ms, minimum box lifetime
var boxTimer = null; // Timer for box disappearance
var decoyTimer = null; // Timer for decoy disappearance
var scoreTxt = null; // Score display
var missLimit = 3; // Number of misses before game over
// Function to handle box click (defined in Game Code)
var onBoxClicked = null;
var onDecoyBoxClicked = null;
// Utility: get a random position for the box, avoiding the top-left 100x100 area
function getRandomBoxPosition(boxWidth, boxHeight) {
var margin = 100;
var minX = margin + boxWidth / 2;
var maxX = 2048 - boxWidth / 2;
var minY = margin + boxHeight / 2;
var maxY = 2732 - boxHeight / 2;
var x = minX + Math.random() * (maxX - minX);
var y = minY + Math.random() * (maxY - minY);
return {
x: x,
y: y
};
}
// Show a new box at a random position
function spawnBox() {
// Remove previous box if exists
if (currentBox) {
currentBox.destroy();
currentBox = null;
}
// Remove previous decoy if exists
if (currentDecoy) {
currentDecoy.destroy();
currentDecoy = null;
}
// Create new box
var box = new Box();
var boxW = box.width;
var boxH = box.height;
var pos = getRandomBoxPosition(boxW, boxH);
box.x = pos.x;
box.y = pos.y;
game.addChild(box);
currentBox = box;
// Set up timer for box disappearance
if (boxTimer) {
LK.clearTimeout(boxTimer);
}
boxTimer = LK.setTimeout(function () {
// Missed the box
if (currentBox === box) {
handleBoxMiss();
}
}, boxLifetime);
// Randomly decide to spawn a decoy box (30% chance)
if (Math.random() < 0.3) {
var decoy = new DecoyBox();
var decoyW = decoy.width;
var decoyH = decoy.height;
// Make sure decoy doesn't overlap with the real box
var tries = 0;
var decoyPos;
do {
decoyPos = getRandomBoxPosition(decoyW, decoyH);
tries++;
} while (Math.abs(decoyPos.x - box.x) < (boxW + decoyW) / 1.5 && Math.abs(decoyPos.y - box.y) < (boxH + decoyH) / 1.5 && tries < 10);
decoy.x = decoyPos.x;
decoy.y = decoyPos.y;
game.addChild(decoy);
currentDecoy = decoy;
// Decoy disappears after the same time as the box
if (decoyTimer) {
LK.clearTimeout(decoyTimer);
}
decoyTimer = LK.setTimeout(function () {
if (currentDecoy === decoy) {
currentDecoy.destroy();
currentDecoy = null;
}
}, boxLifetime);
}
}
// Handle when a box is clicked
onBoxClicked = function onBoxClicked(box) {
if (currentBox !== box) return; // Only count if it's the current box
score += 1;
updateScoreText();
// Increase difficulty: decrease box lifetime, but not below minimum
boxLifetime = Math.max(minBoxLifetime, boxLifetime - 30);
// Remove box and spawn a new one
if (boxTimer) {
LK.clearTimeout(boxTimer);
boxTimer = null;
}
if (currentBox) {
currentBox.destroy();
currentBox = null;
}
// Remove decoy if present
if (currentDecoy) {
currentDecoy.destroy();
currentDecoy = null;
}
if (decoyTimer) {
LK.clearTimeout(decoyTimer);
decoyTimer = null;
}
spawnBox();
};
// Handle when a decoy box is clicked
onDecoyBoxClicked = function onDecoyBoxClicked(decoy) {
if (currentDecoy !== decoy) return; // Only count if it's the current decoy
// Penalize: decrease score (min 0), and count as a miss
score = Math.max(0, score - 1);
misses += 1;
updateScoreText();
// Flash screen to indicate penalty
LK.effects.flashScreen(0xff0000, 400);
// Remove decoy and box
if (currentDecoy) {
currentDecoy.destroy();
currentDecoy = null;
}
if (decoyTimer) {
LK.clearTimeout(decoyTimer);
decoyTimer = null;
}
if (currentBox) {
currentBox.destroy();
currentBox = null;
}
if (boxTimer) {
LK.clearTimeout(boxTimer);
boxTimer = null;
}
// Check for game over
if (misses >= missLimit) {
LK.showGameOver();
return;
}
// Spawn next box
spawnBox();
};
// Handle when a box is missed (not clicked in time)
function handleBoxMiss() {
misses += 1;
if (currentBox) {
currentBox.destroy();
currentBox = null;
}
if (boxTimer) {
LK.clearTimeout(boxTimer);
boxTimer = null;
}
if (currentDecoy) {
currentDecoy.destroy();
currentDecoy = null;
}
if (decoyTimer) {
LK.clearTimeout(decoyTimer);
decoyTimer = null;
}
if (misses >= missLimit) {
// Game over
LK.showGameOver();
return;
}
// Show next box
spawnBox();
}
// Update the score display
function updateScoreText() {
if (scoreTxt) {
scoreTxt.setText(score + "");
}
}
// Initialize score text UI
scoreTxt = new Text2("0", {
size: 150,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
// Start the game by spawning the first box
if (currentDecoy) {
currentDecoy.destroy();
currentDecoy = null;
}
if (decoyTimer) {
LK.clearTimeout(decoyTimer);
decoyTimer = null;
}
spawnBox(); ===================================================================
--- original.js
+++ change.js
@@ -32,8 +32,35 @@
// No movement, but could add animations here
};
return self;
});
+// DecoyBox class: a misleading box that penalizes the player if tapped
+var DecoyBox = Container.expand(function () {
+ var self = Container.call(this);
+ // Attach a box asset, but with a different color to distinguish (e.g. red)
+ var decoyAsset = self.attachAsset('box', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ tint: 0xD83318 // Red tint for decoy
+ });
+ self.lastX = 0;
+ self.lastY = 0;
+ self.lastWasDown = false;
+ // Called when the decoy box is pressed/touched
+ self.down = function (x, y, obj) {
+ if (!self.lastWasDown) {
+ self.lastWasDown = true;
+ if (typeof onDecoyBoxClicked === "function") {
+ onDecoyBoxClicked(self);
+ }
+ }
+ };
+ self.up = function (x, y, obj) {
+ self.lastWasDown = false;
+ };
+ self.update = function () {};
+ return self;
+});
/****
* Initialize Game
****/
@@ -46,17 +73,20 @@
* Game Code
****/
// Core game variables
var currentBox = null; // The currently visible box
+var currentDecoy = null; // The currently visible decoy box
var score = 0; // Player's score
var misses = 0; // Number of missed boxes
var boxLifetime = 1200; // ms, how long a box stays visible (decreases with difficulty)
var minBoxLifetime = 500; // ms, minimum box lifetime
var boxTimer = null; // Timer for box disappearance
+var decoyTimer = null; // Timer for decoy disappearance
var scoreTxt = null; // Score display
var missLimit = 3; // Number of misses before game over
// Function to handle box click (defined in Game Code)
var onBoxClicked = null;
+var onDecoyBoxClicked = null;
// Utility: get a random position for the box, avoiding the top-left 100x100 area
function getRandomBoxPosition(boxWidth, boxHeight) {
var margin = 100;
var minX = margin + boxWidth / 2;
@@ -76,8 +106,13 @@
if (currentBox) {
currentBox.destroy();
currentBox = null;
}
+ // Remove previous decoy if exists
+ if (currentDecoy) {
+ currentDecoy.destroy();
+ currentDecoy = null;
+ }
// Create new box
var box = new Box();
var boxW = box.width;
var boxH = box.height;
@@ -95,8 +130,35 @@
if (currentBox === box) {
handleBoxMiss();
}
}, boxLifetime);
+ // Randomly decide to spawn a decoy box (30% chance)
+ if (Math.random() < 0.3) {
+ var decoy = new DecoyBox();
+ var decoyW = decoy.width;
+ var decoyH = decoy.height;
+ // Make sure decoy doesn't overlap with the real box
+ var tries = 0;
+ var decoyPos;
+ do {
+ decoyPos = getRandomBoxPosition(decoyW, decoyH);
+ tries++;
+ } while (Math.abs(decoyPos.x - box.x) < (boxW + decoyW) / 1.5 && Math.abs(decoyPos.y - box.y) < (boxH + decoyH) / 1.5 && tries < 10);
+ decoy.x = decoyPos.x;
+ decoy.y = decoyPos.y;
+ game.addChild(decoy);
+ currentDecoy = decoy;
+ // Decoy disappears after the same time as the box
+ if (decoyTimer) {
+ LK.clearTimeout(decoyTimer);
+ }
+ decoyTimer = LK.setTimeout(function () {
+ if (currentDecoy === decoy) {
+ currentDecoy.destroy();
+ currentDecoy = null;
+ }
+ }, boxLifetime);
+ }
}
// Handle when a box is clicked
onBoxClicked = function onBoxClicked(box) {
if (currentBox !== box) return; // Only count if it's the current box
@@ -112,10 +174,53 @@
if (currentBox) {
currentBox.destroy();
currentBox = null;
}
+ // Remove decoy if present
+ if (currentDecoy) {
+ currentDecoy.destroy();
+ currentDecoy = null;
+ }
+ if (decoyTimer) {
+ LK.clearTimeout(decoyTimer);
+ decoyTimer = null;
+ }
spawnBox();
};
+// Handle when a decoy box is clicked
+onDecoyBoxClicked = function onDecoyBoxClicked(decoy) {
+ if (currentDecoy !== decoy) return; // Only count if it's the current decoy
+ // Penalize: decrease score (min 0), and count as a miss
+ score = Math.max(0, score - 1);
+ misses += 1;
+ updateScoreText();
+ // Flash screen to indicate penalty
+ LK.effects.flashScreen(0xff0000, 400);
+ // Remove decoy and box
+ if (currentDecoy) {
+ currentDecoy.destroy();
+ currentDecoy = null;
+ }
+ if (decoyTimer) {
+ LK.clearTimeout(decoyTimer);
+ decoyTimer = null;
+ }
+ if (currentBox) {
+ currentBox.destroy();
+ currentBox = null;
+ }
+ if (boxTimer) {
+ LK.clearTimeout(boxTimer);
+ boxTimer = null;
+ }
+ // Check for game over
+ if (misses >= missLimit) {
+ LK.showGameOver();
+ return;
+ }
+ // Spawn next box
+ spawnBox();
+};
// Handle when a box is missed (not clicked in time)
function handleBoxMiss() {
misses += 1;
if (currentBox) {
@@ -125,8 +230,16 @@
if (boxTimer) {
LK.clearTimeout(boxTimer);
boxTimer = null;
}
+ if (currentDecoy) {
+ currentDecoy.destroy();
+ currentDecoy = null;
+ }
+ if (decoyTimer) {
+ LK.clearTimeout(decoyTimer);
+ decoyTimer = null;
+ }
if (misses >= missLimit) {
// Game over
LK.showGameOver();
return;
@@ -147,5 +260,13 @@
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
// Start the game by spawning the first box
+if (currentDecoy) {
+ currentDecoy.destroy();
+ currentDecoy = null;
+}
+if (decoyTimer) {
+ LK.clearTimeout(decoyTimer);
+ decoyTimer = null;
+}
spawnBox();
\ No newline at end of file