/****
* Classes
****/
// Barrier class: represents a horizontal barrier at the bottom of the screen
var Barrier = Container.expand(function () {
var self = Container.call(this);
// Create a wide, short rectangle as the barrier
var barrierHeight = 120;
var barrierWidth = 2048;
var barrierAsset = self.attachAsset('box', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: barrierWidth / 200,
scaleY: barrierHeight / 200,
tint: 0x222222 // dark gray for visibility
});
self.width = barrierWidth;
self.height = barrierHeight;
return self;
});
// 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 barrier = null; // The bottom barrier
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 and the barrier at the bottom
function getRandomBoxPosition(boxWidth, boxHeight) {
var margin = 100;
var minX = margin + boxWidth / 2;
var maxX = 2048 - boxWidth / 2;
var minY = margin + boxHeight / 2;
// If barrier exists, keep boxes above it
var barrierHeight = barrier ? barrier.height : 120;
var barrierY = 2732 - barrierHeight / 2;
var maxY = barrierY - boxHeight / 2 - 10; // 10px gap above barrier
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 + "");
}
}
// Create and add the barrier at the bottom of the screen
barrier = new Barrier();
barrier.x = 2048 / 2;
barrier.y = 2732 - barrier.height / 2;
game.addChild(barrier);
// 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
@@ -1,7 +1,24 @@
/****
* Classes
****/
+// Barrier class: represents a horizontal barrier at the bottom of the screen
+var Barrier = Container.expand(function () {
+ var self = Container.call(this);
+ // Create a wide, short rectangle as the barrier
+ var barrierHeight = 120;
+ var barrierWidth = 2048;
+ var barrierAsset = self.attachAsset('box', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ scaleX: barrierWidth / 200,
+ scaleY: barrierHeight / 200,
+ tint: 0x222222 // dark gray for visibility
+ });
+ self.width = barrierWidth;
+ self.height = barrierHeight;
+ return self;
+});
// 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
@@ -72,8 +89,9 @@
/****
* Game Code
****/
// Core game variables
+var barrier = null; // The bottom barrier
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
@@ -85,15 +103,18 @@
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
+// Utility: get a random position for the box, avoiding the top-left 100x100 area and the barrier at the bottom
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;
+ // If barrier exists, keep boxes above it
+ var barrierHeight = barrier ? barrier.height : 120;
+ var barrierY = 2732 - barrierHeight / 2;
+ var maxY = barrierY - boxHeight / 2 - 10; // 10px gap above barrier
var x = minX + Math.random() * (maxX - minX);
var y = minY + Math.random() * (maxY - minY);
return {
x: x,
@@ -252,8 +273,13 @@
if (scoreTxt) {
scoreTxt.setText(score + "");
}
}
+// Create and add the barrier at the bottom of the screen
+barrier = new Barrier();
+barrier.x = 2048 / 2;
+barrier.y = 2732 - barrier.height / 2;
+game.addChild(barrier);
// Initialize score text UI
scoreTxt = new Text2("0", {
size: 150,
fill: 0xFFFFFF