/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var storage = LK.import("@upit/storage.v1"); /**** * Classes ****/ var GridCell = Container.expand(function () { var self = Container.call(this); self.bg = null; self.nameText = null; self.objectName = ''; self.init = function (name) { self.objectName = name; self.bg = self.attachAsset('gridCell', { anchorX: 0.5, anchorY: 0.5 }); self.nameText = new Text2(name, { size: 55, fill: 0xFFFFFF }); self.nameText.anchor.set(0.5, 0.5); self.addChild(self.nameText); }; self.markFound = function () { tween(self.bg, { alpha: 0.3 }, { duration: 300 }); tween(self.nameText, { alpha: 0.3 }, { duration: 300 }); }; self.reset = function () { self.bg.alpha = 1; self.nameText.alpha = 1; }; return self; }); var HiddenObject = Container.expand(function () { var self = Container.call(this); self.objectType = ''; self.objectName = ''; self.found = false; self.init = function (type, name) { self.objectType = type; self.objectName = name; // Calculate random scale to achieve size between 100 and 200 // Most objects are 60-90 pixels, so we need to scale them var minScale = 100 / 90; // Approximately 1.11 var maxScale = 200 / 60; // Approximately 3.33 var randomScale = minScale + Math.random() * (maxScale - minScale); var asset = self.attachAsset(type, { anchorX: 0.5, anchorY: 0.5, scaleX: randomScale, scaleY: randomScale }); self.asset = asset; }; self.down = function (x, y, obj) { if (!self.found && currentLevel && !hintActive) { var targetIndex = currentLevel.targetObjects.indexOf(self); if (targetIndex !== -1) { self.found = true; LK.getSound('found').play(); tween(self.asset, { alpha: 0.3 }, { duration: 300 }); var gridIndex = currentLevel.gridOrder.indexOf(self.objectName); if (gridIndex !== -1 && gridCells[gridIndex]) { gridCells[gridIndex].markFound(); } objectsFound++; updateScore(); if (objectsFound >= 12) { levelComplete(); } } } }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x1a1a1a }); /**** * Game Code ****/ var currentLevel = null; var objectsFound = 0; var playerLevel = storage.playerLevel || 1; var totalObjectsFound = storage.totalObjectsFound || 0; var hintActive = false; var hintsUsed = 0; var gridCells = []; var objectTypes = ['object1', 'object2', 'object3', 'object4', 'object5', 'object6', 'object7', 'object8', 'object9', 'object10', 'object11', 'object12', 'object13', 'object14', 'object15', 'object16', 'object17', 'object18', 'object19', 'object20', 'object21', 'object22', 'object23', 'object24', 'object25', 'object26', 'object27', 'object28', 'object29', 'object30', 'object31', 'object32']; var objectNames = ['Ball', 'Key', 'Table', 'Watch', 'Mirror', 'Vase', 'Book', 'Lamp', 'Phone', 'Cup', 'Clock', 'Bottle', 'Chair', 'Pencil', 'Camera', 'Wallet', 'Scissors', 'Umbrella', 'Glasses', 'Coin', 'Candle', 'Flower', 'Ring', 'Brush', 'Spoon', 'Apple', 'Shoe', 'Hat', 'Fork', 'Plate', 'Guitar', 'Knife']; var sceneContainer = new Container(); game.addChild(sceneContainer); var sceneBg = LK.getAsset('sceneBg', { anchorX: 0.5, anchorY: 0, x: 1024, y: 0 }); sceneContainer.addChild(sceneBg); var gridContainer = new Container(); gridContainer.y = 1800; game.addChild(gridContainer); var gridBg = LK.getAsset('gridBg', { anchorX: 0.5, anchorY: 0, x: 1024, y: 0 }); gridContainer.addChild(gridBg); var levelText = new Text2('Level ' + playerLevel, { size: 60, fill: 0xFFFFFF }); levelText.anchor.set(1, 0); LK.gui.topRight.addChild(levelText); levelText.x = -20; levelText.y = 20; var scoreText = new Text2('Found: 0/12', { size: 50, fill: 0xFFFFFF }); scoreText.anchor.set(0.5, 0); gridContainer.addChild(scoreText); scoreText.x = 1024; scoreText.y = 20; var hintButton = new Container(); var hintBg = LK.getAsset('hintButton', { anchorX: 0.5, anchorY: 0.5 }); hintButton.addChild(hintBg); var hintText = new Text2('HINT', { size: 40, fill: 0xFFFFFF }); hintText.anchor.set(0.5, 0.5); hintButton.addChild(hintText); gridContainer.addChild(hintButton); hintButton.x = 1024; hintButton.y = 850; hintButton.down = function () { if (!hintActive && objectsFound < 12 && currentLevel) { useHint(); } }; function createLevel() { if (currentLevel) { currentLevel.destroy(); } currentLevel = new Container(); currentLevel.objects = []; currentLevel.gridOrder = []; currentLevel.targetObjects = []; sceneContainer.addChild(currentLevel); // Create all 32 objects var allIndices = []; for (var i = 0; i < 32; i++) { allIndices.push(i); } // Shuffle the indices for (var i = allIndices.length - 1; i > 0; i--) { var j = Math.floor(Math.random() * (i + 1)); var temp = allIndices[i]; allIndices[i] = allIndices[j]; allIndices[j] = temp; } // Create all 32 objects for (var i = 0; i < 32; i++) { var typeIndex = allIndices[i]; var obj = new HiddenObject(); obj.init(objectTypes[typeIndex], objectNames[typeIndex]); // Try to find a non-overlapping position var maxAttempts = 100; var placed = false; var attempt = 0; while (attempt < maxAttempts && !placed) { obj.x = 100 + Math.random() * 1848; // Full width minus margins obj.y = 1300 + Math.random() * 400; // Place in bottom 500px area (1800-500=1300) // Check if this position overlaps with any existing objects var overlaps = false; for (var j = 0; j < currentLevel.objects.length; j++) { var other = currentLevel.objects[j]; var dx = obj.x - other.x; var dy = obj.y - other.y; // Calculate minimum distance based on both objects' sizes var minDist = (obj.asset.width * obj.asset.scaleX + other.asset.width * other.asset.scaleX) / 2 + 10; // 10px padding if (Math.sqrt(dx * dx + dy * dy) < minDist) { overlaps = true; break; } } if (!overlaps) { placed = true; } attempt++; } currentLevel.objects.push(obj); currentLevel.addChild(obj); } // Select 12 random objects to be the target objects var targetIndices = []; while (targetIndices.length < 12) { var index = Math.floor(Math.random() * 32); if (targetIndices.indexOf(index) === -1) { targetIndices.push(index); currentLevel.targetObjects.push(currentLevel.objects[index]); currentLevel.gridOrder.push(currentLevel.objects[index].objectName); } } updateGrid(); } function updateGrid() { for (var i = 0; i < gridCells.length; i++) { gridCells[i].destroy(); } gridCells = []; for (var row = 0; row < 3; row++) { for (var col = 0; col < 4; col++) { var index = row * 4 + col; if (index < currentLevel.gridOrder.length) { var cell = new GridCell(); cell.init(currentLevel.gridOrder[index]); cell.x = 256 + col * 512; cell.y = 200 + row * 220; gridContainer.addChild(cell); gridCells.push(cell); } } } } function updateScore() { scoreText.setText('Found: ' + objectsFound + '/12'); } function useHint() { hintActive = true; hintsUsed++; LK.getSound('hint').play(); var unfoundObjects = []; for (var i = 0; i < currentLevel.targetObjects.length; i++) { if (!currentLevel.targetObjects[i].found) { unfoundObjects.push(currentLevel.targetObjects[i]); } } if (unfoundObjects.length > 0) { var targetObject = unfoundObjects[Math.floor(Math.random() * unfoundObjects.length)]; var hintCircle = LK.getAsset('hintCircle', { anchorX: 0.5, anchorY: 0.5, x: targetObject.x, y: targetObject.y, alpha: 0.5 }); sceneContainer.addChild(hintCircle); tween(hintCircle, { scaleX: 1.5, scaleY: 1.5, alpha: 0 }, { duration: 1500, onFinish: function onFinish() { hintCircle.destroy(); hintActive = false; } }); } } function levelComplete() { LK.getSound('levelup').play(); totalObjectsFound += 12; playerLevel++; storage.playerLevel = playerLevel; storage.totalObjectsFound = totalObjectsFound; levelText.setText('Level ' + playerLevel); LK.setTimeout(function () { objectsFound = 0; hintsUsed = 0; updateScore(); createLevel(); }, 1000); } createLevel(); game.update = function () { if (LK.getScore() !== totalObjectsFound) { LK.setScore(totalObjectsFound); } };
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/****
* Classes
****/
var GridCell = Container.expand(function () {
var self = Container.call(this);
self.bg = null;
self.nameText = null;
self.objectName = '';
self.init = function (name) {
self.objectName = name;
self.bg = self.attachAsset('gridCell', {
anchorX: 0.5,
anchorY: 0.5
});
self.nameText = new Text2(name, {
size: 55,
fill: 0xFFFFFF
});
self.nameText.anchor.set(0.5, 0.5);
self.addChild(self.nameText);
};
self.markFound = function () {
tween(self.bg, {
alpha: 0.3
}, {
duration: 300
});
tween(self.nameText, {
alpha: 0.3
}, {
duration: 300
});
};
self.reset = function () {
self.bg.alpha = 1;
self.nameText.alpha = 1;
};
return self;
});
var HiddenObject = Container.expand(function () {
var self = Container.call(this);
self.objectType = '';
self.objectName = '';
self.found = false;
self.init = function (type, name) {
self.objectType = type;
self.objectName = name;
// Calculate random scale to achieve size between 100 and 200
// Most objects are 60-90 pixels, so we need to scale them
var minScale = 100 / 90; // Approximately 1.11
var maxScale = 200 / 60; // Approximately 3.33
var randomScale = minScale + Math.random() * (maxScale - minScale);
var asset = self.attachAsset(type, {
anchorX: 0.5,
anchorY: 0.5,
scaleX: randomScale,
scaleY: randomScale
});
self.asset = asset;
};
self.down = function (x, y, obj) {
if (!self.found && currentLevel && !hintActive) {
var targetIndex = currentLevel.targetObjects.indexOf(self);
if (targetIndex !== -1) {
self.found = true;
LK.getSound('found').play();
tween(self.asset, {
alpha: 0.3
}, {
duration: 300
});
var gridIndex = currentLevel.gridOrder.indexOf(self.objectName);
if (gridIndex !== -1 && gridCells[gridIndex]) {
gridCells[gridIndex].markFound();
}
objectsFound++;
updateScore();
if (objectsFound >= 12) {
levelComplete();
}
}
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x1a1a1a
});
/****
* Game Code
****/
var currentLevel = null;
var objectsFound = 0;
var playerLevel = storage.playerLevel || 1;
var totalObjectsFound = storage.totalObjectsFound || 0;
var hintActive = false;
var hintsUsed = 0;
var gridCells = [];
var objectTypes = ['object1', 'object2', 'object3', 'object4', 'object5', 'object6', 'object7', 'object8', 'object9', 'object10', 'object11', 'object12', 'object13', 'object14', 'object15', 'object16', 'object17', 'object18', 'object19', 'object20', 'object21', 'object22', 'object23', 'object24', 'object25', 'object26', 'object27', 'object28', 'object29', 'object30', 'object31', 'object32'];
var objectNames = ['Ball', 'Key', 'Table', 'Watch', 'Mirror', 'Vase', 'Book', 'Lamp', 'Phone', 'Cup', 'Clock', 'Bottle', 'Chair', 'Pencil', 'Camera', 'Wallet', 'Scissors', 'Umbrella', 'Glasses', 'Coin', 'Candle', 'Flower', 'Ring', 'Brush', 'Spoon', 'Apple', 'Shoe', 'Hat', 'Fork', 'Plate', 'Guitar', 'Knife'];
var sceneContainer = new Container();
game.addChild(sceneContainer);
var sceneBg = LK.getAsset('sceneBg', {
anchorX: 0.5,
anchorY: 0,
x: 1024,
y: 0
});
sceneContainer.addChild(sceneBg);
var gridContainer = new Container();
gridContainer.y = 1800;
game.addChild(gridContainer);
var gridBg = LK.getAsset('gridBg', {
anchorX: 0.5,
anchorY: 0,
x: 1024,
y: 0
});
gridContainer.addChild(gridBg);
var levelText = new Text2('Level ' + playerLevel, {
size: 60,
fill: 0xFFFFFF
});
levelText.anchor.set(1, 0);
LK.gui.topRight.addChild(levelText);
levelText.x = -20;
levelText.y = 20;
var scoreText = new Text2('Found: 0/12', {
size: 50,
fill: 0xFFFFFF
});
scoreText.anchor.set(0.5, 0);
gridContainer.addChild(scoreText);
scoreText.x = 1024;
scoreText.y = 20;
var hintButton = new Container();
var hintBg = LK.getAsset('hintButton', {
anchorX: 0.5,
anchorY: 0.5
});
hintButton.addChild(hintBg);
var hintText = new Text2('HINT', {
size: 40,
fill: 0xFFFFFF
});
hintText.anchor.set(0.5, 0.5);
hintButton.addChild(hintText);
gridContainer.addChild(hintButton);
hintButton.x = 1024;
hintButton.y = 850;
hintButton.down = function () {
if (!hintActive && objectsFound < 12 && currentLevel) {
useHint();
}
};
function createLevel() {
if (currentLevel) {
currentLevel.destroy();
}
currentLevel = new Container();
currentLevel.objects = [];
currentLevel.gridOrder = [];
currentLevel.targetObjects = [];
sceneContainer.addChild(currentLevel);
// Create all 32 objects
var allIndices = [];
for (var i = 0; i < 32; i++) {
allIndices.push(i);
}
// Shuffle the indices
for (var i = allIndices.length - 1; i > 0; i--) {
var j = Math.floor(Math.random() * (i + 1));
var temp = allIndices[i];
allIndices[i] = allIndices[j];
allIndices[j] = temp;
}
// Create all 32 objects
for (var i = 0; i < 32; i++) {
var typeIndex = allIndices[i];
var obj = new HiddenObject();
obj.init(objectTypes[typeIndex], objectNames[typeIndex]);
// Try to find a non-overlapping position
var maxAttempts = 100;
var placed = false;
var attempt = 0;
while (attempt < maxAttempts && !placed) {
obj.x = 100 + Math.random() * 1848; // Full width minus margins
obj.y = 1300 + Math.random() * 400; // Place in bottom 500px area (1800-500=1300)
// Check if this position overlaps with any existing objects
var overlaps = false;
for (var j = 0; j < currentLevel.objects.length; j++) {
var other = currentLevel.objects[j];
var dx = obj.x - other.x;
var dy = obj.y - other.y;
// Calculate minimum distance based on both objects' sizes
var minDist = (obj.asset.width * obj.asset.scaleX + other.asset.width * other.asset.scaleX) / 2 + 10; // 10px padding
if (Math.sqrt(dx * dx + dy * dy) < minDist) {
overlaps = true;
break;
}
}
if (!overlaps) {
placed = true;
}
attempt++;
}
currentLevel.objects.push(obj);
currentLevel.addChild(obj);
}
// Select 12 random objects to be the target objects
var targetIndices = [];
while (targetIndices.length < 12) {
var index = Math.floor(Math.random() * 32);
if (targetIndices.indexOf(index) === -1) {
targetIndices.push(index);
currentLevel.targetObjects.push(currentLevel.objects[index]);
currentLevel.gridOrder.push(currentLevel.objects[index].objectName);
}
}
updateGrid();
}
function updateGrid() {
for (var i = 0; i < gridCells.length; i++) {
gridCells[i].destroy();
}
gridCells = [];
for (var row = 0; row < 3; row++) {
for (var col = 0; col < 4; col++) {
var index = row * 4 + col;
if (index < currentLevel.gridOrder.length) {
var cell = new GridCell();
cell.init(currentLevel.gridOrder[index]);
cell.x = 256 + col * 512;
cell.y = 200 + row * 220;
gridContainer.addChild(cell);
gridCells.push(cell);
}
}
}
}
function updateScore() {
scoreText.setText('Found: ' + objectsFound + '/12');
}
function useHint() {
hintActive = true;
hintsUsed++;
LK.getSound('hint').play();
var unfoundObjects = [];
for (var i = 0; i < currentLevel.targetObjects.length; i++) {
if (!currentLevel.targetObjects[i].found) {
unfoundObjects.push(currentLevel.targetObjects[i]);
}
}
if (unfoundObjects.length > 0) {
var targetObject = unfoundObjects[Math.floor(Math.random() * unfoundObjects.length)];
var hintCircle = LK.getAsset('hintCircle', {
anchorX: 0.5,
anchorY: 0.5,
x: targetObject.x,
y: targetObject.y,
alpha: 0.5
});
sceneContainer.addChild(hintCircle);
tween(hintCircle, {
scaleX: 1.5,
scaleY: 1.5,
alpha: 0
}, {
duration: 1500,
onFinish: function onFinish() {
hintCircle.destroy();
hintActive = false;
}
});
}
}
function levelComplete() {
LK.getSound('levelup').play();
totalObjectsFound += 12;
playerLevel++;
storage.playerLevel = playerLevel;
storage.totalObjectsFound = totalObjectsFound;
levelText.setText('Level ' + playerLevel);
LK.setTimeout(function () {
objectsFound = 0;
hintsUsed = 0;
updateScore();
createLevel();
}, 1000);
}
createLevel();
game.update = function () {
if (LK.getScore() !== totalObjectsFound) {
LK.setScore(totalObjectsFound);
}
};