/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ // Target class: a tappable, animated target var Target = Container.expand(function () { var self = Container.call(this); // Pick a random color for the target var colorIds = ['targetRed', 'targetBlue', 'targetGreen', 'targetYellow']; var colorId = colorIds[Math.floor(Math.random() * colorIds.length)]; // Attach the asset, anchor at center var targetAsset = self.attachAsset(colorId, { anchorX: 0.5, anchorY: 0.5 }); // For animation (pop in) targetAsset.scaleX = 0.7; targetAsset.scaleY = 0.7; tween(targetAsset, { scaleX: 1, scaleY: 1 }, { duration: 120, easing: tween.easeOut }); // Mark as not yet tapped self.tapped = false; // Called when the target is tapped self.down = function (x, y, obj) { if (self.tapped) return; self.tapped = true; // Animate: shrink and fade out tween(targetAsset, { scaleX: 1.3, scaleY: 1.3, alpha: 0 }, { duration: 120, easing: tween.easeIn, onFinish: function onFinish() { self.destroy(); } }); // Play pop sound LK.getSound('pop').play(); // Increase score LK.setScore(LK.getScore() + 1); scoreTxt.setText(LK.getScore()); // Spawn next target immediately spawnNextTarget(); }; // For missed detection self.missed = false; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x181818 }); /**** * Game Code ****/ // Targets: Large, colorful circles // Score display var scoreTxt = new Text2('0', { size: 150, fill: 0xFFFFFF }); scoreTxt.anchor.set(0.5, 0); LK.gui.top.addChild(scoreTxt); // Timer display var timerTxt = new Text2('30', { size: 90, fill: 0xFFF700 }); timerTxt.anchor.set(0.5, 0); LK.gui.top.addChild(timerTxt); timerTxt.y = 160; // Misses display (hearts) var missesTxt = new Text2('❤❤❤', { size: 90, fill: 0xFF3B30 }); missesTxt.anchor.set(0.5, 0); LK.gui.top.addChild(missesTxt); missesTxt.y = 260; // Game state variables var currentTarget = null; var misses = 0; var maxMisses = 3; var timeLeft = 30.0; // seconds var targetTimeout = null; var timerInterval = null; var targetMinTime = 0.7; // seconds var targetMaxTime = 1.3; // seconds var minTargetTime = 0.4; // seconds (minimum as game speeds up) var speedupEvery = 5; // every 5 points, speed up var speedupAmount = 0.08; // decrease max/min time by this much // Helper: spawn a new target at a random position function spawnNextTarget() { // If game is over, do not spawn if (misses >= maxMisses || timeLeft <= 0) return; // Remove previous target if still present if (currentTarget && !currentTarget.tapped) { // Missed! currentTarget.missed = true; currentTarget.destroy(); misses += 1; updateMissesDisplay(); // Flash screen red LK.effects.flashScreen(0xff3b30, 200); if (misses >= maxMisses) { LK.showGameOver(); return; } } // Calculate speedup var score = LK.getScore(); var speedups = Math.floor(score / speedupEvery); var minTime = Math.max(targetMinTime - speedups * speedupAmount, minTargetTime); var maxTime = Math.max(targetMaxTime - speedups * speedupAmount, minTargetTime + 0.2); // Create new target var target = new Target(); // Random position, avoid edges (target is 220x220, keep 120px margin) var margin = 120; var x = margin + Math.random() * (2048 - 2 * margin); var y = margin + 200 + Math.random() * (2732 - 2 * margin - 400); // avoid top GUI target.x = x; target.y = y; // Add to game game.addChild(target); currentTarget = target; // Set up timeout for missing the target if (targetTimeout) LK.clearTimeout(targetTimeout); var targetTime = minTime + Math.random() * (maxTime - minTime); targetTimeout = LK.setTimeout(function () { // If not tapped, count as miss and spawn next if (!target.tapped && !target.missed) { target.missed = true; target.destroy(); misses += 1; updateMissesDisplay(); LK.effects.flashScreen(0xff3b30, 200); if (misses >= maxMisses) { LK.showGameOver(); return; } spawnNextTarget(); } }, targetTime * 1000); } // Update misses display (hearts) function updateMissesDisplay() { var hearts = ''; for (var i = 0; i < maxMisses - misses; i++) hearts += '❤'; for (var i = 0; i < misses; i++) hearts += '♡'; missesTxt.setText(hearts); } // Timer logic function startTimer() { if (timerInterval) LK.clearInterval(timerInterval); timerInterval = LK.setInterval(function () { timeLeft -= 0.1; if (timeLeft < 0) timeLeft = 0; timerTxt.setText(Math.ceil(timeLeft)); if (timeLeft <= 0) { // End game if (targetTimeout) LK.clearTimeout(targetTimeout); LK.showGameOver(); } }, 100); } // Game start/reset logic function startGame() { LK.setScore(0); scoreTxt.setText('0'); misses = 0; updateMissesDisplay(); timeLeft = 30.0; timerTxt.setText('30'); if (currentTarget) { currentTarget.destroy(); currentTarget = null; } if (targetTimeout) LK.clearTimeout(targetTimeout); startTimer(); spawnNextTarget(); } // Start the game on load startGame(); // On game over, reset everything (LK will re-init Game, but for safety) game.on('gameover', function () { if (targetTimeout) LK.clearTimeout(targetTimeout); if (timerInterval) LK.clearInterval(timerInterval); if (currentTarget) currentTarget.destroy(); }); // On you win (not used in this version, but for future) game.on('youwin', function () { if (targetTimeout) LK.clearTimeout(targetTimeout); if (timerInterval) LK.clearInterval(timerInterval); if (currentTarget) currentTarget.destroy(); }); // Prevent accidental drag (no drag logic needed) game.move = function (x, y, obj) {}; // Prevent tap-through on GUI scoreTxt.down = function () {}; timerTxt.down = function () {}; missesTxt.down = function () {}; // No update loop needed, all logic is event/timer based
===================================================================
--- original.js
+++ change.js
@@ -1,6 +1,217 @@
-/****
+/****
+* Plugins
+****/
+var tween = LK.import("@upit/tween.v1");
+
+/****
+* Classes
+****/
+// Target class: a tappable, animated target
+var Target = Container.expand(function () {
+ var self = Container.call(this);
+ // Pick a random color for the target
+ var colorIds = ['targetRed', 'targetBlue', 'targetGreen', 'targetYellow'];
+ var colorId = colorIds[Math.floor(Math.random() * colorIds.length)];
+ // Attach the asset, anchor at center
+ var targetAsset = self.attachAsset(colorId, {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ // For animation (pop in)
+ targetAsset.scaleX = 0.7;
+ targetAsset.scaleY = 0.7;
+ tween(targetAsset, {
+ scaleX: 1,
+ scaleY: 1
+ }, {
+ duration: 120,
+ easing: tween.easeOut
+ });
+ // Mark as not yet tapped
+ self.tapped = false;
+ // Called when the target is tapped
+ self.down = function (x, y, obj) {
+ if (self.tapped) return;
+ self.tapped = true;
+ // Animate: shrink and fade out
+ tween(targetAsset, {
+ scaleX: 1.3,
+ scaleY: 1.3,
+ alpha: 0
+ }, {
+ duration: 120,
+ easing: tween.easeIn,
+ onFinish: function onFinish() {
+ self.destroy();
+ }
+ });
+ // Play pop sound
+ LK.getSound('pop').play();
+ // Increase score
+ LK.setScore(LK.getScore() + 1);
+ scoreTxt.setText(LK.getScore());
+ // Spawn next target immediately
+ spawnNextTarget();
+ };
+ // For missed detection
+ self.missed = false;
+ return self;
+});
+
+/****
* Initialize Game
-****/
+****/
var game = new LK.Game({
- backgroundColor: 0x000000
-});
\ No newline at end of file
+ backgroundColor: 0x181818
+});
+
+/****
+* Game Code
+****/
+// Targets: Large, colorful circles
+// Score display
+var scoreTxt = new Text2('0', {
+ size: 150,
+ fill: 0xFFFFFF
+});
+scoreTxt.anchor.set(0.5, 0);
+LK.gui.top.addChild(scoreTxt);
+// Timer display
+var timerTxt = new Text2('30', {
+ size: 90,
+ fill: 0xFFF700
+});
+timerTxt.anchor.set(0.5, 0);
+LK.gui.top.addChild(timerTxt);
+timerTxt.y = 160;
+// Misses display (hearts)
+var missesTxt = new Text2('❤❤❤', {
+ size: 90,
+ fill: 0xFF3B30
+});
+missesTxt.anchor.set(0.5, 0);
+LK.gui.top.addChild(missesTxt);
+missesTxt.y = 260;
+// Game state variables
+var currentTarget = null;
+var misses = 0;
+var maxMisses = 3;
+var timeLeft = 30.0; // seconds
+var targetTimeout = null;
+var timerInterval = null;
+var targetMinTime = 0.7; // seconds
+var targetMaxTime = 1.3; // seconds
+var minTargetTime = 0.4; // seconds (minimum as game speeds up)
+var speedupEvery = 5; // every 5 points, speed up
+var speedupAmount = 0.08; // decrease max/min time by this much
+// Helper: spawn a new target at a random position
+function spawnNextTarget() {
+ // If game is over, do not spawn
+ if (misses >= maxMisses || timeLeft <= 0) return;
+ // Remove previous target if still present
+ if (currentTarget && !currentTarget.tapped) {
+ // Missed!
+ currentTarget.missed = true;
+ currentTarget.destroy();
+ misses += 1;
+ updateMissesDisplay();
+ // Flash screen red
+ LK.effects.flashScreen(0xff3b30, 200);
+ if (misses >= maxMisses) {
+ LK.showGameOver();
+ return;
+ }
+ }
+ // Calculate speedup
+ var score = LK.getScore();
+ var speedups = Math.floor(score / speedupEvery);
+ var minTime = Math.max(targetMinTime - speedups * speedupAmount, minTargetTime);
+ var maxTime = Math.max(targetMaxTime - speedups * speedupAmount, minTargetTime + 0.2);
+ // Create new target
+ var target = new Target();
+ // Random position, avoid edges (target is 220x220, keep 120px margin)
+ var margin = 120;
+ var x = margin + Math.random() * (2048 - 2 * margin);
+ var y = margin + 200 + Math.random() * (2732 - 2 * margin - 400); // avoid top GUI
+ target.x = x;
+ target.y = y;
+ // Add to game
+ game.addChild(target);
+ currentTarget = target;
+ // Set up timeout for missing the target
+ if (targetTimeout) LK.clearTimeout(targetTimeout);
+ var targetTime = minTime + Math.random() * (maxTime - minTime);
+ targetTimeout = LK.setTimeout(function () {
+ // If not tapped, count as miss and spawn next
+ if (!target.tapped && !target.missed) {
+ target.missed = true;
+ target.destroy();
+ misses += 1;
+ updateMissesDisplay();
+ LK.effects.flashScreen(0xff3b30, 200);
+ if (misses >= maxMisses) {
+ LK.showGameOver();
+ return;
+ }
+ spawnNextTarget();
+ }
+ }, targetTime * 1000);
+}
+// Update misses display (hearts)
+function updateMissesDisplay() {
+ var hearts = '';
+ for (var i = 0; i < maxMisses - misses; i++) hearts += '❤';
+ for (var i = 0; i < misses; i++) hearts += '♡';
+ missesTxt.setText(hearts);
+}
+// Timer logic
+function startTimer() {
+ if (timerInterval) LK.clearInterval(timerInterval);
+ timerInterval = LK.setInterval(function () {
+ timeLeft -= 0.1;
+ if (timeLeft < 0) timeLeft = 0;
+ timerTxt.setText(Math.ceil(timeLeft));
+ if (timeLeft <= 0) {
+ // End game
+ if (targetTimeout) LK.clearTimeout(targetTimeout);
+ LK.showGameOver();
+ }
+ }, 100);
+}
+// Game start/reset logic
+function startGame() {
+ LK.setScore(0);
+ scoreTxt.setText('0');
+ misses = 0;
+ updateMissesDisplay();
+ timeLeft = 30.0;
+ timerTxt.setText('30');
+ if (currentTarget) {
+ currentTarget.destroy();
+ currentTarget = null;
+ }
+ if (targetTimeout) LK.clearTimeout(targetTimeout);
+ startTimer();
+ spawnNextTarget();
+}
+// Start the game on load
+startGame();
+// On game over, reset everything (LK will re-init Game, but for safety)
+game.on('gameover', function () {
+ if (targetTimeout) LK.clearTimeout(targetTimeout);
+ if (timerInterval) LK.clearInterval(timerInterval);
+ if (currentTarget) currentTarget.destroy();
+});
+// On you win (not used in this version, but for future)
+game.on('youwin', function () {
+ if (targetTimeout) LK.clearTimeout(targetTimeout);
+ if (timerInterval) LK.clearInterval(timerInterval);
+ if (currentTarget) currentTarget.destroy();
+});
+// Prevent accidental drag (no drag logic needed)
+game.move = function (x, y, obj) {};
+// Prevent tap-through on GUI
+scoreTxt.down = function () {};
+timerTxt.down = function () {};
+missesTxt.down = function () {};
+// No update loop needed, all logic is event/timer based
\ No newline at end of file