Code edit (1 edits merged)
Please save this source code
User prompt
Dot Precision Master
Initial prompt
Create a precision-based visual memory game with the following rules: • The game screen has a solid black background. • A small dot appears randomly on the screen for a brief moment and then disappears. • The player must guess the exact latitude and longitude (X and Y coordinates) where the dot appeared. • The accuracy required is extremely high: 99.99999%. Even being off by a ten-thousandth of a millimeter will count as incorrect. • Points are awarded based on the accuracy of the guess (e.g. 100% accuracy = full score, 90% accuracy = partial score, etc.). • Every 5 levels, the number of dots to guess increases: • Levels 1–4: 1 dot per round • Levels 5–8: 2 dots appear simultaneously • Levels 9–12: 3 dots appear simultaneously • And so on... • In rounds with multiple dots, all dots appear and disappear at the same time, and the player must submit a guess for the coordinates of each dot. • The challenge escalates with speed, complexity, and required precision. Design the game UI to provide instant feedback on guess accuracy, track level progression, and maintain a score based on cumulative accuracy.
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var Dot = Container.expand(function () {
var self = Container.call(this);
var dotGraphics = self.attachAsset('dot', {
anchorX: 0.5,
anchorY: 0.5
});
self.actualX = 0;
self.actualY = 0;
self.isVisible = false;
self.showAt = function (x, y) {
self.actualX = x;
self.actualY = y;
self.x = x;
self.y = y;
self.alpha = 1;
self.isVisible = true;
};
self.hide = function () {
self.alpha = 0;
self.isVisible = false;
};
return self;
});
var GuessIndicator = Container.expand(function () {
var self = Container.call(this);
var guessGraphics = self.attachAsset('playerGuess', {
anchorX: 0.5,
anchorY: 0.5
});
var actualGraphics = self.attachAsset('actualPosition', {
anchorX: 0.5,
anchorY: 0.5
});
self.showComparison = function (guessX, guessY, actualX, actualY) {
guessGraphics.x = 0;
guessGraphics.y = 0;
actualGraphics.x = actualX - guessX;
actualGraphics.y = actualY - guessY;
self.x = guessX;
self.y = guessY;
self.alpha = 1;
};
self.hide = function () {
self.alpha = 0;
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x000000
});
/****
* Game Code
****/
var gameState = 'waiting'; // 'waiting', 'showing', 'guessing', 'feedback', 'gameOver'
var level = 1;
var currentDots = [];
var currentGuesses = [];
var showTimer = null;
var feedbackTimer = null;
var totalAccuracy = 0;
var totalGuesses = 0;
var dotsToShow = 1;
var showDuration = 2000;
var guessIndicators = [];
// UI Elements
var levelText = new Text2('Level: 1', {
size: 60,
fill: 0xFFFFFF
});
levelText.anchor.set(0.5, 0);
LK.gui.top.addChild(levelText);
levelText.y = 100;
var instructionText = new Text2('Watch the dot(s), then tap where they appeared', {
size: 45,
fill: 0xFFFFFF
});
instructionText.anchor.set(0.5, 0.5);
game.addChild(instructionText);
instructionText.x = 1024;
instructionText.y = 1366;
var accuracyText = new Text2('Accuracy: 100.00%', {
size: 50,
fill: 0xFFFFFF
});
accuracyText.anchor.set(0.5, 1);
LK.gui.bottom.addChild(accuracyText);
accuracyText.y = -50;
var scoreText = new Text2('Score: 0', {
size: 50,
fill: 0xFFFFFF
});
scoreText.anchor.set(0.5, 1);
LK.gui.bottom.addChild(scoreText);
scoreText.y = -120;
function calculateDistance(x1, y1, x2, y2) {
return Math.sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1));
}
function calculateAccuracy(distance) {
var maxDistance = 100; // Maximum distance for 0% accuracy
var accuracy = Math.max(0, (maxDistance - distance) / maxDistance);
return accuracy;
}
function updateDotsToShow() {
dotsToShow = Math.floor((level - 1) / 4) + 1;
}
function updateShowDuration() {
showDuration = Math.max(800, 2000 - (level - 1) * 50);
}
function startLevel() {
gameState = 'showing';
currentDots = [];
currentGuesses = [];
updateDotsToShow();
updateShowDuration();
levelText.setText('Level: ' + level);
instructionText.setText('Memorize the positions!');
// Clear previous indicators
for (var i = 0; i < guessIndicators.length; i++) {
guessIndicators[i].destroy();
}
guessIndicators = [];
// Create and show dots
for (var i = 0; i < dotsToShow; i++) {
var dot = new Dot();
var x = 200 + Math.random() * (2048 - 400);
var y = 300 + Math.random() * (2732 - 600);
dot.showAt(x, y);
currentDots.push(dot);
game.addChild(dot);
}
// Hide dots after duration
showTimer = LK.setTimeout(function () {
for (var i = 0; i < currentDots.length; i++) {
currentDots[i].hide();
}
gameState = 'guessing';
instructionText.setText('Tap where the dot(s) appeared (' + currentGuesses.length + '/' + dotsToShow + ')');
}, showDuration);
}
function processGuess(x, y) {
if (gameState !== 'guessing') return;
currentGuesses.push({
x: x,
y: y
});
// Create guess indicator
var indicator = new GuessIndicator();
var closestDot = null;
var minDistance = Infinity;
// Find closest dot to this guess
for (var i = 0; i < currentDots.length; i++) {
var dot = currentDots[i];
var distance = calculateDistance(x, y, dot.actualX, dot.actualY);
if (distance < minDistance) {
minDistance = distance;
closestDot = dot;
}
}
if (closestDot) {
indicator.showComparison(x, y, closestDot.actualX, closestDot.actualY);
guessIndicators.push(indicator);
game.addChild(indicator);
}
instructionText.setText('Tap where the dot(s) appeared (' + currentGuesses.length + '/' + dotsToShow + ')');
if (currentGuesses.length >= dotsToShow) {
evaluateRound();
}
}
function evaluateRound() {
gameState = 'feedback';
var roundAccuracies = [];
var roundScore = 0;
// Calculate accuracy for each guess
for (var i = 0; i < currentGuesses.length; i++) {
var guess = currentGuesses[i];
var closestDistance = Infinity;
// Find the closest dot to each guess
for (var j = 0; j < currentDots.length; j++) {
var dot = currentDots[j];
var distance = calculateDistance(guess.x, guess.y, dot.actualX, dot.actualY);
if (distance < closestDistance) {
closestDistance = distance;
}
}
var accuracy = calculateAccuracy(closestDistance);
roundAccuracies.push(accuracy);
roundScore += accuracy * 100;
}
// Update total statistics
for (var i = 0; i < roundAccuracies.length; i++) {
totalAccuracy += roundAccuracies[i];
totalGuesses++;
}
var overallAccuracy = totalAccuracy / totalGuesses * 100;
var currentScore = Math.floor(overallAccuracy * totalGuesses);
// Update UI
accuracyText.setText('Accuracy: ' + overallAccuracy.toFixed(5) + '%');
scoreText.setText('Score: ' + currentScore);
LK.setScore(currentScore);
// Check if accuracy is too low
if (overallAccuracy < 50 && totalGuesses > 5) {
gameState = 'gameOver';
instructionText.setText('Game Over! Accuracy too low');
LK.setTimeout(function () {
LK.showGameOver();
}, 2000);
return;
}
// Play feedback sound
var avgAccuracy = roundAccuracies.reduce(function (a, b) {
return a + b;
}, 0) / roundAccuracies.length;
if (avgAccuracy > 0.8) {
LK.getSound('success').play();
} else {
LK.getSound('fail').play();
}
instructionText.setText('Round complete! Accuracy: ' + (avgAccuracy * 100).toFixed(2) + '%');
// Move to next level after feedback
feedbackTimer = LK.setTimeout(function () {
// Clean up current round
for (var i = 0; i < currentDots.length; i++) {
currentDots[i].destroy();
}
for (var i = 0; i < guessIndicators.length; i++) {
guessIndicators[i].destroy();
}
level++;
// Check win condition
if (level > 20) {
gameState = 'gameOver';
instructionText.setText('Congratulations! You are a Precision Master!');
LK.setTimeout(function () {
LK.showYouWin();
}, 2000);
return;
}
startLevel();
}, 2000);
}
game.down = function (x, y, obj) {
if (gameState === 'waiting') {
startLevel();
} else if (gameState === 'guessing') {
processGuess(x, y);
}
};
game.update = function () {
if (gameState === 'waiting') {
instructionText.setText('Tap to start Level ' + level);
}
};
// Initialize first level
gameState = 'waiting'; ===================================================================
--- original.js
+++ change.js
@@ -1,6 +1,267 @@
-/****
+/****
+* Plugins
+****/
+var tween = LK.import("@upit/tween.v1");
+
+/****
+* Classes
+****/
+var Dot = Container.expand(function () {
+ var self = Container.call(this);
+ var dotGraphics = self.attachAsset('dot', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ self.actualX = 0;
+ self.actualY = 0;
+ self.isVisible = false;
+ self.showAt = function (x, y) {
+ self.actualX = x;
+ self.actualY = y;
+ self.x = x;
+ self.y = y;
+ self.alpha = 1;
+ self.isVisible = true;
+ };
+ self.hide = function () {
+ self.alpha = 0;
+ self.isVisible = false;
+ };
+ return self;
+});
+var GuessIndicator = Container.expand(function () {
+ var self = Container.call(this);
+ var guessGraphics = self.attachAsset('playerGuess', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ var actualGraphics = self.attachAsset('actualPosition', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ self.showComparison = function (guessX, guessY, actualX, actualY) {
+ guessGraphics.x = 0;
+ guessGraphics.y = 0;
+ actualGraphics.x = actualX - guessX;
+ actualGraphics.y = actualY - guessY;
+ self.x = guessX;
+ self.y = guessY;
+ self.alpha = 1;
+ };
+ self.hide = function () {
+ self.alpha = 0;
+ };
+ return self;
+});
+
+/****
* Initialize Game
-****/
+****/
var game = new LK.Game({
backgroundColor: 0x000000
-});
\ No newline at end of file
+});
+
+/****
+* Game Code
+****/
+var gameState = 'waiting'; // 'waiting', 'showing', 'guessing', 'feedback', 'gameOver'
+var level = 1;
+var currentDots = [];
+var currentGuesses = [];
+var showTimer = null;
+var feedbackTimer = null;
+var totalAccuracy = 0;
+var totalGuesses = 0;
+var dotsToShow = 1;
+var showDuration = 2000;
+var guessIndicators = [];
+// UI Elements
+var levelText = new Text2('Level: 1', {
+ size: 60,
+ fill: 0xFFFFFF
+});
+levelText.anchor.set(0.5, 0);
+LK.gui.top.addChild(levelText);
+levelText.y = 100;
+var instructionText = new Text2('Watch the dot(s), then tap where they appeared', {
+ size: 45,
+ fill: 0xFFFFFF
+});
+instructionText.anchor.set(0.5, 0.5);
+game.addChild(instructionText);
+instructionText.x = 1024;
+instructionText.y = 1366;
+var accuracyText = new Text2('Accuracy: 100.00%', {
+ size: 50,
+ fill: 0xFFFFFF
+});
+accuracyText.anchor.set(0.5, 1);
+LK.gui.bottom.addChild(accuracyText);
+accuracyText.y = -50;
+var scoreText = new Text2('Score: 0', {
+ size: 50,
+ fill: 0xFFFFFF
+});
+scoreText.anchor.set(0.5, 1);
+LK.gui.bottom.addChild(scoreText);
+scoreText.y = -120;
+function calculateDistance(x1, y1, x2, y2) {
+ return Math.sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1));
+}
+function calculateAccuracy(distance) {
+ var maxDistance = 100; // Maximum distance for 0% accuracy
+ var accuracy = Math.max(0, (maxDistance - distance) / maxDistance);
+ return accuracy;
+}
+function updateDotsToShow() {
+ dotsToShow = Math.floor((level - 1) / 4) + 1;
+}
+function updateShowDuration() {
+ showDuration = Math.max(800, 2000 - (level - 1) * 50);
+}
+function startLevel() {
+ gameState = 'showing';
+ currentDots = [];
+ currentGuesses = [];
+ updateDotsToShow();
+ updateShowDuration();
+ levelText.setText('Level: ' + level);
+ instructionText.setText('Memorize the positions!');
+ // Clear previous indicators
+ for (var i = 0; i < guessIndicators.length; i++) {
+ guessIndicators[i].destroy();
+ }
+ guessIndicators = [];
+ // Create and show dots
+ for (var i = 0; i < dotsToShow; i++) {
+ var dot = new Dot();
+ var x = 200 + Math.random() * (2048 - 400);
+ var y = 300 + Math.random() * (2732 - 600);
+ dot.showAt(x, y);
+ currentDots.push(dot);
+ game.addChild(dot);
+ }
+ // Hide dots after duration
+ showTimer = LK.setTimeout(function () {
+ for (var i = 0; i < currentDots.length; i++) {
+ currentDots[i].hide();
+ }
+ gameState = 'guessing';
+ instructionText.setText('Tap where the dot(s) appeared (' + currentGuesses.length + '/' + dotsToShow + ')');
+ }, showDuration);
+}
+function processGuess(x, y) {
+ if (gameState !== 'guessing') return;
+ currentGuesses.push({
+ x: x,
+ y: y
+ });
+ // Create guess indicator
+ var indicator = new GuessIndicator();
+ var closestDot = null;
+ var minDistance = Infinity;
+ // Find closest dot to this guess
+ for (var i = 0; i < currentDots.length; i++) {
+ var dot = currentDots[i];
+ var distance = calculateDistance(x, y, dot.actualX, dot.actualY);
+ if (distance < minDistance) {
+ minDistance = distance;
+ closestDot = dot;
+ }
+ }
+ if (closestDot) {
+ indicator.showComparison(x, y, closestDot.actualX, closestDot.actualY);
+ guessIndicators.push(indicator);
+ game.addChild(indicator);
+ }
+ instructionText.setText('Tap where the dot(s) appeared (' + currentGuesses.length + '/' + dotsToShow + ')');
+ if (currentGuesses.length >= dotsToShow) {
+ evaluateRound();
+ }
+}
+function evaluateRound() {
+ gameState = 'feedback';
+ var roundAccuracies = [];
+ var roundScore = 0;
+ // Calculate accuracy for each guess
+ for (var i = 0; i < currentGuesses.length; i++) {
+ var guess = currentGuesses[i];
+ var closestDistance = Infinity;
+ // Find the closest dot to each guess
+ for (var j = 0; j < currentDots.length; j++) {
+ var dot = currentDots[j];
+ var distance = calculateDistance(guess.x, guess.y, dot.actualX, dot.actualY);
+ if (distance < closestDistance) {
+ closestDistance = distance;
+ }
+ }
+ var accuracy = calculateAccuracy(closestDistance);
+ roundAccuracies.push(accuracy);
+ roundScore += accuracy * 100;
+ }
+ // Update total statistics
+ for (var i = 0; i < roundAccuracies.length; i++) {
+ totalAccuracy += roundAccuracies[i];
+ totalGuesses++;
+ }
+ var overallAccuracy = totalAccuracy / totalGuesses * 100;
+ var currentScore = Math.floor(overallAccuracy * totalGuesses);
+ // Update UI
+ accuracyText.setText('Accuracy: ' + overallAccuracy.toFixed(5) + '%');
+ scoreText.setText('Score: ' + currentScore);
+ LK.setScore(currentScore);
+ // Check if accuracy is too low
+ if (overallAccuracy < 50 && totalGuesses > 5) {
+ gameState = 'gameOver';
+ instructionText.setText('Game Over! Accuracy too low');
+ LK.setTimeout(function () {
+ LK.showGameOver();
+ }, 2000);
+ return;
+ }
+ // Play feedback sound
+ var avgAccuracy = roundAccuracies.reduce(function (a, b) {
+ return a + b;
+ }, 0) / roundAccuracies.length;
+ if (avgAccuracy > 0.8) {
+ LK.getSound('success').play();
+ } else {
+ LK.getSound('fail').play();
+ }
+ instructionText.setText('Round complete! Accuracy: ' + (avgAccuracy * 100).toFixed(2) + '%');
+ // Move to next level after feedback
+ feedbackTimer = LK.setTimeout(function () {
+ // Clean up current round
+ for (var i = 0; i < currentDots.length; i++) {
+ currentDots[i].destroy();
+ }
+ for (var i = 0; i < guessIndicators.length; i++) {
+ guessIndicators[i].destroy();
+ }
+ level++;
+ // Check win condition
+ if (level > 20) {
+ gameState = 'gameOver';
+ instructionText.setText('Congratulations! You are a Precision Master!');
+ LK.setTimeout(function () {
+ LK.showYouWin();
+ }, 2000);
+ return;
+ }
+ startLevel();
+ }, 2000);
+}
+game.down = function (x, y, obj) {
+ if (gameState === 'waiting') {
+ startLevel();
+ } else if (gameState === 'guessing') {
+ processGuess(x, y);
+ }
+};
+game.update = function () {
+ if (gameState === 'waiting') {
+ instructionText.setText('Tap to start Level ' + level);
+ }
+};
+// Initialize first level
+gameState = 'waiting';
\ No newline at end of file