/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var storage = LK.import("@upit/storage.v1"); var facekit = LK.import("@upit/facekit.v1"); /**** * Classes ****/ var Character = Container.expand(function () { var self = Container.call(this); // Character properties self.isHidden = true; self.isFound = false; self.peekFrequency = 0; self.peekDuration = 0; self.soundFrequency = 0; self.lastPeekTime = 0; self.lastSoundTime = 0; self.requiresMouthOpen = false; self.requiresSound = false; // Create character visual var characterGraphics = self.attachAsset('hiddenCharacter', { anchorX: 0.5, anchorY: 0.5, alpha: 0.4 }); // Create found effect (initially invisible) var foundEffect = self.attachAsset('foundEffect', { anchorX: 0.5, anchorY: 0.5, alpha: 0, scaleX: 0.5, scaleY: 0.5 }); // Setup character with specific behavior self.setup = function (config) { self.peekFrequency = config.peekFrequency || 0; self.peekDuration = config.peekDuration || 0; self.soundFrequency = config.soundFrequency || 0; self.requiresMouthOpen = config.requiresMouthOpen || false; self.requiresSound = config.requiresSound || false; // Set initial state if (self.peekFrequency === 0) { characterGraphics.alpha = 0.3; // Always slightly visible } else { characterGraphics.alpha = 0; // Hide initially } }; // Check if the character is currently revealing itself self.update = function () { // Skip if already found if (self.isFound) { return; } // Handle peek behavior if (self.peekFrequency > 0) { var currentTime = Date.now(); // Time to start a new peek if (currentTime - self.lastPeekTime > self.peekFrequency) { self.lastPeekTime = currentTime; characterGraphics.alpha = 0.5; // Set timer to hide again LK.setTimeout(function () { if (!self.isFound) { characterGraphics.alpha = 0; } }, self.peekDuration); } } // Handle sound behavior if (self.soundFrequency > 0) { var currentTime = Date.now(); // Time to make a sound if (currentTime - self.lastSoundTime > self.soundFrequency) { self.lastSoundTime = currentTime; LK.getSound('characterSound').play(); } } }; // Check if player can find this character self.checkFindCondition = function () { if (self.isFound) { return false; } var canFind = true; // Check for mouth open requirement if (self.requiresMouthOpen && !facekit.mouthOpen) { canFind = false; } // Check for sound requirement if (self.requiresSound && facekit.volume < 0.3) { canFind = false; } return canFind; }; // Mark as found and show animation self.findCharacter = function () { if (self.isFound) { return; } self.isFound = true; characterGraphics.alpha = 1; // Switch to found appearance tween(characterGraphics, { tint: 0x22aa22 }, { duration: 500 }); // Show found effect foundEffect.alpha = 0.7; tween(foundEffect, { alpha: 0, scaleX: 2, scaleY: 2 }, { duration: 1000 }); // Play sound LK.getSound('found').play(); return true; }; return self; }); var TimerBar = Container.expand(function () { var self = Container.call(this); // Create background bar var barBg = self.attachAsset('timerBg', { anchorX: 0, anchorY: 0.5 }); // Create timer bar var bar = self.attachAsset('timerBar', { anchorX: 0, anchorY: 0.5 }); // Properties self.maxTime = 60; // seconds self.currentTime = 60; self.warningThreshold = 10; // seconds self.hasWarnedLowTime = false; // Initialize with time self.setTime = function (time) { self.maxTime = time; self.currentTime = time; self.updateVisual(); }; // Update time remaining self.updateTime = function (delta) { self.currentTime -= delta; if (self.currentTime < 0) { self.currentTime = 0; } // Check for low time warning if (self.currentTime <= self.warningThreshold && !self.hasWarnedLowTime) { self.hasWarnedLowTime = true; LK.getSound('timeWarn').play(); tween(bar, { tint: 0xff0000 }, { duration: 500 }); } self.updateVisual(); return self.currentTime <= 0; }; // Update visual representation self.updateVisual = function () { var percentage = self.currentTime / self.maxTime; bar.scale.x = percentage; }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x000000 }); /**** * Game Code ****/ // Game state variables var level = 1; var charactersFound = 0; var totalCharacters = 0; var gameActive = false; var lastTime = Date.now(); var timeSinceLastTick = 0; var characters = []; var timerBar; var levelTime = 60; // seconds var isLevelComplete = false; // UI Elements var scoreTxt; var levelTxt; var findTxt; var instructionTxt; // Initialize game function initGame() { // Set up UI setupUI(); // Start game with level 1 startLevel(level); // Start background music LK.playMusic('bgMusic', { fade: { start: 0, end: 0.4, duration: 1000 } }); } // Setup UI elements function setupUI() { // Create score text scoreTxt = new Text2('Score: 0', { size: 80, fill: 0xFFFFFF }); scoreTxt.anchor.set(1, 0); LK.gui.topRight.addChild(scoreTxt); // Create level text levelTxt = new Text2('Level: 1', { size: 80, fill: 0xFFFFFF }); levelTxt.anchor.set(0, 0); LK.gui.topRight.addChild(levelTxt); levelTxt.y = 100; // Create find text (shows how many characters left to find) findTxt = new Text2('Find: 0/0', { size: 80, fill: 0xFFFFFF }); findTxt.anchor.set(0.5, 0); LK.gui.top.addChild(findTxt); // Create instruction text instructionTxt = new Text2('Find the hidden characters!', { size: 60, fill: 0xFFFFFF }); instructionTxt.anchor.set(0.5, 1); LK.gui.bottom.addChild(instructionTxt); // Create timer bar timerBar = new TimerBar(); timerBar.x = 2048 / 2 - 900; // Center timerBar.y = 120; LK.gui.top.addChild(timerBar); } // Start a new level function startLevel(levelNum) { // Clean up previous level cleanupLevel(); // Update variables level = levelNum; charactersFound = 0; isLevelComplete = false; // Set level time (decreases with each level) levelTime = Math.max(30, 60 - (level - 1) * 5); // Update UI levelTxt.setText('Level: ' + level); // Calculate number of characters for this level totalCharacters = 3 + Math.min(7, Math.floor(level / 2)); // Update find text findTxt.setText('Find: 0/' + totalCharacters); // Show appropriate instructions if (level === 1) { instructionTxt.setText('Look around to find the hidden characters!'); } else if (level === 2) { instructionTxt.setText('Some characters need you to open your mouth!'); } else if (level === 3) { instructionTxt.setText('Try making sounds to find some characters!'); } else { instructionTxt.setText('Use all your skills to find the hidden characters!'); } // Create characters createCharacters(); // Reset timer timerBar.setTime(levelTime); timerBar.hasWarnedLowTime = false; // Start the game gameActive = true; lastTime = Date.now(); } // Create characters for the current level function createCharacters() { // Clear any existing characters characters = []; for (var i = 0; i < totalCharacters; i++) { var character = new Character(); // Position randomly on screen character.x = 200 + Math.random() * (2048 - 400); character.y = 200 + Math.random() * (2732 - 400); // Determine character behavior based on level and position in array var config = { peekFrequency: 0, peekDuration: 0, soundFrequency: 0, requiresMouthOpen: false, requiresSound: false }; // Different character behaviors based on index and level if (i < totalCharacters / 3) { // Basic characters - just peek occasionally config.peekFrequency = 3000 + Math.random() * 5000; config.peekDuration = 500 + Math.random() * 1000; } else if (i < totalCharacters * 2 / 3) { // Medium characters - require mouth to be open if (level >= 2) { config.requiresMouthOpen = true; config.peekFrequency = 4000 + Math.random() * 6000; config.peekDuration = 400 + Math.random() * 800; } else { config.peekFrequency = 3000 + Math.random() * 5000; config.peekDuration = 500 + Math.random() * 1000; } } else { // Advanced characters - require sound if (level >= 3) { config.requiresSound = true; config.soundFrequency = 7000 + Math.random() * 10000; } else { config.peekFrequency = 4000 + Math.random() * 6000; config.peekDuration = 300 + Math.random() * 600; } } // Setup character character.setup(config); // Add to game and tracking array game.addChild(character); characters.push(character); } } // Clean up the current level function cleanupLevel() { // Remove all characters for (var i = 0; i < characters.length; i++) { if (characters[i].parent) { characters[i].parent.removeChild(characters[i]); } } characters = []; } // Update game state game.update = function () { // Skip if game not active if (!gameActive) { return; } // Calculate time delta var currentTime = Date.now(); var delta = (currentTime - lastTime) / 1000; // Convert to seconds lastTime = currentTime; // Update timer var timeUp = timerBar.updateTime(delta); if (timeUp && !isLevelComplete) { gameOver(); return; } // Update each character for (var i = 0; i < characters.length; i++) { characters[i].update(); } }; // Handle touch/click on game game.down = function (x, y, obj) { // Skip if game not active if (!gameActive) { return; } // Check each character to see if clicked for (var i = 0; i < characters.length; i++) { var character = characters[i]; // Check if touch is on this character if (x >= character.x - 100 && x <= character.x + 100 && y >= character.y - 100 && y <= character.y + 100) { // Check if this character can be found based on conditions if (character.checkFindCondition()) { // Find the character if (character.findCharacter()) { // Update found count charactersFound++; // Update UI findTxt.setText('Find: ' + charactersFound + '/' + totalCharacters); // Add score var scoreGain = 100 + Math.floor(timerBar.currentTime * 10); LK.setScore(LK.getScore() + scoreGain); scoreTxt.setText('Score: ' + LK.getScore()); // Check if level complete if (charactersFound >= totalCharacters) { levelComplete(); } } } } } }; // Handle move events game.move = function (x, y, obj) { // Game uses camera, no specific move handling needed }; // Level complete function levelComplete() { isLevelComplete = true; gameActive = false; // Show level complete message instructionTxt.setText('Level ' + level + ' Complete! Starting next level...'); // Wait a moment before starting next level LK.setTimeout(function () { startLevel(level + 1); }, 3000); } // Game over function gameOver() { gameActive = false; // Show game over message instructionTxt.setText('Time\'s up! Game Over!'); // Short delay before showing game over screen LK.setTimeout(function () { LK.showGameOver(); }, 2000); } // Initialize the game initGame();
===================================================================
--- original.js
+++ change.js
@@ -1,6 +1,427 @@
-/****
+/****
+* Plugins
+****/
+var tween = LK.import("@upit/tween.v1");
+var storage = LK.import("@upit/storage.v1");
+var facekit = LK.import("@upit/facekit.v1");
+
+/****
+* Classes
+****/
+var Character = Container.expand(function () {
+ var self = Container.call(this);
+ // Character properties
+ self.isHidden = true;
+ self.isFound = false;
+ self.peekFrequency = 0;
+ self.peekDuration = 0;
+ self.soundFrequency = 0;
+ self.lastPeekTime = 0;
+ self.lastSoundTime = 0;
+ self.requiresMouthOpen = false;
+ self.requiresSound = false;
+ // Create character visual
+ var characterGraphics = self.attachAsset('hiddenCharacter', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ alpha: 0.4
+ });
+ // Create found effect (initially invisible)
+ var foundEffect = self.attachAsset('foundEffect', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ alpha: 0,
+ scaleX: 0.5,
+ scaleY: 0.5
+ });
+ // Setup character with specific behavior
+ self.setup = function (config) {
+ self.peekFrequency = config.peekFrequency || 0;
+ self.peekDuration = config.peekDuration || 0;
+ self.soundFrequency = config.soundFrequency || 0;
+ self.requiresMouthOpen = config.requiresMouthOpen || false;
+ self.requiresSound = config.requiresSound || false;
+ // Set initial state
+ if (self.peekFrequency === 0) {
+ characterGraphics.alpha = 0.3; // Always slightly visible
+ } else {
+ characterGraphics.alpha = 0; // Hide initially
+ }
+ };
+ // Check if the character is currently revealing itself
+ self.update = function () {
+ // Skip if already found
+ if (self.isFound) {
+ return;
+ }
+ // Handle peek behavior
+ if (self.peekFrequency > 0) {
+ var currentTime = Date.now();
+ // Time to start a new peek
+ if (currentTime - self.lastPeekTime > self.peekFrequency) {
+ self.lastPeekTime = currentTime;
+ characterGraphics.alpha = 0.5;
+ // Set timer to hide again
+ LK.setTimeout(function () {
+ if (!self.isFound) {
+ characterGraphics.alpha = 0;
+ }
+ }, self.peekDuration);
+ }
+ }
+ // Handle sound behavior
+ if (self.soundFrequency > 0) {
+ var currentTime = Date.now();
+ // Time to make a sound
+ if (currentTime - self.lastSoundTime > self.soundFrequency) {
+ self.lastSoundTime = currentTime;
+ LK.getSound('characterSound').play();
+ }
+ }
+ };
+ // Check if player can find this character
+ self.checkFindCondition = function () {
+ if (self.isFound) {
+ return false;
+ }
+ var canFind = true;
+ // Check for mouth open requirement
+ if (self.requiresMouthOpen && !facekit.mouthOpen) {
+ canFind = false;
+ }
+ // Check for sound requirement
+ if (self.requiresSound && facekit.volume < 0.3) {
+ canFind = false;
+ }
+ return canFind;
+ };
+ // Mark as found and show animation
+ self.findCharacter = function () {
+ if (self.isFound) {
+ return;
+ }
+ self.isFound = true;
+ characterGraphics.alpha = 1;
+ // Switch to found appearance
+ tween(characterGraphics, {
+ tint: 0x22aa22
+ }, {
+ duration: 500
+ });
+ // Show found effect
+ foundEffect.alpha = 0.7;
+ tween(foundEffect, {
+ alpha: 0,
+ scaleX: 2,
+ scaleY: 2
+ }, {
+ duration: 1000
+ });
+ // Play sound
+ LK.getSound('found').play();
+ return true;
+ };
+ return self;
+});
+var TimerBar = Container.expand(function () {
+ var self = Container.call(this);
+ // Create background bar
+ var barBg = self.attachAsset('timerBg', {
+ anchorX: 0,
+ anchorY: 0.5
+ });
+ // Create timer bar
+ var bar = self.attachAsset('timerBar', {
+ anchorX: 0,
+ anchorY: 0.5
+ });
+ // Properties
+ self.maxTime = 60; // seconds
+ self.currentTime = 60;
+ self.warningThreshold = 10; // seconds
+ self.hasWarnedLowTime = false;
+ // Initialize with time
+ self.setTime = function (time) {
+ self.maxTime = time;
+ self.currentTime = time;
+ self.updateVisual();
+ };
+ // Update time remaining
+ self.updateTime = function (delta) {
+ self.currentTime -= delta;
+ if (self.currentTime < 0) {
+ self.currentTime = 0;
+ }
+ // Check for low time warning
+ if (self.currentTime <= self.warningThreshold && !self.hasWarnedLowTime) {
+ self.hasWarnedLowTime = true;
+ LK.getSound('timeWarn').play();
+ tween(bar, {
+ tint: 0xff0000
+ }, {
+ duration: 500
+ });
+ }
+ self.updateVisual();
+ return self.currentTime <= 0;
+ };
+ // Update visual representation
+ self.updateVisual = function () {
+ var percentage = self.currentTime / self.maxTime;
+ bar.scale.x = percentage;
+ };
+ return self;
+});
+
+/****
* Initialize Game
-****/
+****/
var game = new LK.Game({
backgroundColor: 0x000000
-});
\ No newline at end of file
+});
+
+/****
+* Game Code
+****/
+// Game state variables
+var level = 1;
+var charactersFound = 0;
+var totalCharacters = 0;
+var gameActive = false;
+var lastTime = Date.now();
+var timeSinceLastTick = 0;
+var characters = [];
+var timerBar;
+var levelTime = 60; // seconds
+var isLevelComplete = false;
+// UI Elements
+var scoreTxt;
+var levelTxt;
+var findTxt;
+var instructionTxt;
+// Initialize game
+function initGame() {
+ // Set up UI
+ setupUI();
+ // Start game with level 1
+ startLevel(level);
+ // Start background music
+ LK.playMusic('bgMusic', {
+ fade: {
+ start: 0,
+ end: 0.4,
+ duration: 1000
+ }
+ });
+}
+// Setup UI elements
+function setupUI() {
+ // Create score text
+ scoreTxt = new Text2('Score: 0', {
+ size: 80,
+ fill: 0xFFFFFF
+ });
+ scoreTxt.anchor.set(1, 0);
+ LK.gui.topRight.addChild(scoreTxt);
+ // Create level text
+ levelTxt = new Text2('Level: 1', {
+ size: 80,
+ fill: 0xFFFFFF
+ });
+ levelTxt.anchor.set(0, 0);
+ LK.gui.topRight.addChild(levelTxt);
+ levelTxt.y = 100;
+ // Create find text (shows how many characters left to find)
+ findTxt = new Text2('Find: 0/0', {
+ size: 80,
+ fill: 0xFFFFFF
+ });
+ findTxt.anchor.set(0.5, 0);
+ LK.gui.top.addChild(findTxt);
+ // Create instruction text
+ instructionTxt = new Text2('Find the hidden characters!', {
+ size: 60,
+ fill: 0xFFFFFF
+ });
+ instructionTxt.anchor.set(0.5, 1);
+ LK.gui.bottom.addChild(instructionTxt);
+ // Create timer bar
+ timerBar = new TimerBar();
+ timerBar.x = 2048 / 2 - 900; // Center
+ timerBar.y = 120;
+ LK.gui.top.addChild(timerBar);
+}
+// Start a new level
+function startLevel(levelNum) {
+ // Clean up previous level
+ cleanupLevel();
+ // Update variables
+ level = levelNum;
+ charactersFound = 0;
+ isLevelComplete = false;
+ // Set level time (decreases with each level)
+ levelTime = Math.max(30, 60 - (level - 1) * 5);
+ // Update UI
+ levelTxt.setText('Level: ' + level);
+ // Calculate number of characters for this level
+ totalCharacters = 3 + Math.min(7, Math.floor(level / 2));
+ // Update find text
+ findTxt.setText('Find: 0/' + totalCharacters);
+ // Show appropriate instructions
+ if (level === 1) {
+ instructionTxt.setText('Look around to find the hidden characters!');
+ } else if (level === 2) {
+ instructionTxt.setText('Some characters need you to open your mouth!');
+ } else if (level === 3) {
+ instructionTxt.setText('Try making sounds to find some characters!');
+ } else {
+ instructionTxt.setText('Use all your skills to find the hidden characters!');
+ }
+ // Create characters
+ createCharacters();
+ // Reset timer
+ timerBar.setTime(levelTime);
+ timerBar.hasWarnedLowTime = false;
+ // Start the game
+ gameActive = true;
+ lastTime = Date.now();
+}
+// Create characters for the current level
+function createCharacters() {
+ // Clear any existing characters
+ characters = [];
+ for (var i = 0; i < totalCharacters; i++) {
+ var character = new Character();
+ // Position randomly on screen
+ character.x = 200 + Math.random() * (2048 - 400);
+ character.y = 200 + Math.random() * (2732 - 400);
+ // Determine character behavior based on level and position in array
+ var config = {
+ peekFrequency: 0,
+ peekDuration: 0,
+ soundFrequency: 0,
+ requiresMouthOpen: false,
+ requiresSound: false
+ };
+ // Different character behaviors based on index and level
+ if (i < totalCharacters / 3) {
+ // Basic characters - just peek occasionally
+ config.peekFrequency = 3000 + Math.random() * 5000;
+ config.peekDuration = 500 + Math.random() * 1000;
+ } else if (i < totalCharacters * 2 / 3) {
+ // Medium characters - require mouth to be open
+ if (level >= 2) {
+ config.requiresMouthOpen = true;
+ config.peekFrequency = 4000 + Math.random() * 6000;
+ config.peekDuration = 400 + Math.random() * 800;
+ } else {
+ config.peekFrequency = 3000 + Math.random() * 5000;
+ config.peekDuration = 500 + Math.random() * 1000;
+ }
+ } else {
+ // Advanced characters - require sound
+ if (level >= 3) {
+ config.requiresSound = true;
+ config.soundFrequency = 7000 + Math.random() * 10000;
+ } else {
+ config.peekFrequency = 4000 + Math.random() * 6000;
+ config.peekDuration = 300 + Math.random() * 600;
+ }
+ }
+ // Setup character
+ character.setup(config);
+ // Add to game and tracking array
+ game.addChild(character);
+ characters.push(character);
+ }
+}
+// Clean up the current level
+function cleanupLevel() {
+ // Remove all characters
+ for (var i = 0; i < characters.length; i++) {
+ if (characters[i].parent) {
+ characters[i].parent.removeChild(characters[i]);
+ }
+ }
+ characters = [];
+}
+// Update game state
+game.update = function () {
+ // Skip if game not active
+ if (!gameActive) {
+ return;
+ }
+ // Calculate time delta
+ var currentTime = Date.now();
+ var delta = (currentTime - lastTime) / 1000; // Convert to seconds
+ lastTime = currentTime;
+ // Update timer
+ var timeUp = timerBar.updateTime(delta);
+ if (timeUp && !isLevelComplete) {
+ gameOver();
+ return;
+ }
+ // Update each character
+ for (var i = 0; i < characters.length; i++) {
+ characters[i].update();
+ }
+};
+// Handle touch/click on game
+game.down = function (x, y, obj) {
+ // Skip if game not active
+ if (!gameActive) {
+ return;
+ }
+ // Check each character to see if clicked
+ for (var i = 0; i < characters.length; i++) {
+ var character = characters[i];
+ // Check if touch is on this character
+ if (x >= character.x - 100 && x <= character.x + 100 && y >= character.y - 100 && y <= character.y + 100) {
+ // Check if this character can be found based on conditions
+ if (character.checkFindCondition()) {
+ // Find the character
+ if (character.findCharacter()) {
+ // Update found count
+ charactersFound++;
+ // Update UI
+ findTxt.setText('Find: ' + charactersFound + '/' + totalCharacters);
+ // Add score
+ var scoreGain = 100 + Math.floor(timerBar.currentTime * 10);
+ LK.setScore(LK.getScore() + scoreGain);
+ scoreTxt.setText('Score: ' + LK.getScore());
+ // Check if level complete
+ if (charactersFound >= totalCharacters) {
+ levelComplete();
+ }
+ }
+ }
+ }
+ }
+};
+// Handle move events
+game.move = function (x, y, obj) {
+ // Game uses camera, no specific move handling needed
+};
+// Level complete
+function levelComplete() {
+ isLevelComplete = true;
+ gameActive = false;
+ // Show level complete message
+ instructionTxt.setText('Level ' + level + ' Complete! Starting next level...');
+ // Wait a moment before starting next level
+ LK.setTimeout(function () {
+ startLevel(level + 1);
+ }, 3000);
+}
+// Game over
+function gameOver() {
+ gameActive = false;
+ // Show game over message
+ instructionTxt.setText('Time\'s up! Game Over!');
+ // Short delay before showing game over screen
+ LK.setTimeout(function () {
+ LK.showGameOver();
+ }, 2000);
+}
+// Initialize the game
+initGame();
\ No newline at end of file