User prompt
Play button automatically resets coin count.
User prompt
Play button automatically send player to 1st level.
User prompt
First level has 4 tiles.
User prompt
Keep tile symbol colors to the main color wheel: red, orange, yellow, green, blue, and purple.
User prompt
Create 50 different tile symbols to match.
User prompt
Please fix the bug: 'Timeout.tick error: Invalid value. Only literals or 1-level deep objects/arrays containing literals are allowed.' in or related to this line: 'storage.savedGames = flattenedSavedGames;' Line Number: 677 ↪💡 Consider importing and using the following plugins: @upit/storage.v1
User prompt
Please fix the bug: 'Timeout.tick error: Invalid value. Only literals or 1-level deep objects/arrays containing literals are allowed.' in or related to this line: 'storage.savedGames = savedGames;' Line Number: 663 ↪💡 Consider importing and using the following plugins: @upit/storage.v1
User prompt
fix
User prompt
Create system to all players to advance to next level after they complete the current one.
User prompt
Please fix the bug: 'Timeout.tick error: Invalid value. Only literals or 1-level deep objects/arrays containing literals are allowed.' in or related to this line: 'savedGames.unshift(gameData);' Line Number: 617 ↪💡 Consider importing and using the following plugins: @upit/storage.v1
User prompt
Please fix the bug: 'Timeout.tick error: Invalid value. Only literals or 1-level deep objects/arrays containing literals are allowed.' in or related to this line: 'savedGames.unshift(gameData);' Line Number: 615 ↪💡 Consider importing and using the following plugins: @upit/storage.v1
User prompt
Create more title symbol designs for players to match.
User prompt
Saved games automatically save the latest five games the player played, whether they passed or failed. ↪💡 Consider importing and using the following plugins: @upit/storage.v1
User prompt
Please fix the bug: 'Script error.' in or related to this line: 'savedGames[slotIndex] = gameData;' Line Number: 585 ↪💡 Consider importing and using the following plugins: @upit/storage.v1
User prompt
Please fix the bug: 'Uncaught TypeError: Cannot read properties of undefined (reading 'setText')' in or related to this line: 'slotBtn.setText('Slot ' + (slotIndex + 1) + ' - Level ' + gameData.level + ' (' + gameData.coins + ' coins)');' Line Number: 589 ↪💡 Consider importing and using the following plugins: @upit/storage.v1
User prompt
First level has 4 tiles.
User prompt
The play button automatically sends player to level 1. ↪💡 Consider importing and using the following plugins: @upit/storage.v1
User prompt
The save button allows players to choose any of the five previously saved games. ↪💡 Consider importing and using the following plugins: @upit/storage.v1
User prompt
Create a menu screen
User prompt
Create a menu screen with multiple languages, play, and save buttons. The save button allows players to choose any of the five previously saved games. ↪💡 Consider importing and using the following plugins: @upit/storage.v1
User prompt
Create a system that automatically saves players' levels even if they pass or fail. ↪💡 Consider importing and using the following plugins: @upit/storage.v1
User prompt
Add a skip button option for the level. Cost 100 coins. ↪💡 Consider importing and using the following plugins: @upit/storage.v1
User prompt
Create system to all players to advance to next level after they complete the current one.
User prompt
Create a system where coins are used to purchase bombs (deletes six titles), a lightbulb (shows one matching pair), a clock (adds 5 minutes) and a timer (adds 1 minute). ↪💡 Consider importing and using the following plugins: @upit/storage.v1
User prompt
Total levels are 500
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var storage = LK.import("@upit/storage.v1"); /**** * Classes ****/ var Card = Container.expand(function (symbolType) { var self = Container.call(this); self.symbolType = symbolType; self.isFlipped = false; self.isMatched = false; self.canFlip = true; // Card back (always visible when not flipped) var cardBack = self.attachAsset('cardBack', { anchorX: 0.5, anchorY: 0.5 }); // Card front (white background) var cardFront = self.attachAsset('cardFront', { anchorX: 0.5, anchorY: 0.5, alpha: 0 }); // Symbol on the card var symbol = self.attachAsset('symbol' + symbolType, { anchorX: 0.5, anchorY: 0.5, alpha: 0 }); self.flip = function () { if (!self.canFlip || self.isMatched) return; LK.getSound('cardFlip').play(); self.isFlipped = !self.isFlipped; if (self.isFlipped) { // Show front and symbol tween(cardFront, { alpha: 1 }, { duration: 200 }); tween(symbol, { alpha: 1 }, { duration: 200 }); } else { // Hide front and symbol tween(cardFront, { alpha: 0 }, { duration: 200 }); tween(symbol, { alpha: 0 }, { duration: 200 }); } }; self.setMatched = function () { self.isMatched = true; self.canFlip = false; // Add a subtle scale effect for matched cards tween(self, { scaleX: 1.1, scaleY: 1.1 }, { duration: 300, easing: tween.easeOut }); }; self.down = function (x, y, obj) { if (self.canFlip && !self.isFlipped && !self.isMatched) { handleCardTap(self); } }; return self; }); var MenuScreen = Container.expand(function () { var self = Container.call(this); // Background var menuBg = LK.getAsset('cardBack', { anchorX: 0.5, anchorY: 0.5, scaleX: 15, scaleY: 20 }); self.addChild(menuBg); menuBg.x = 2048 / 2; menuBg.y = 2732 / 2; // Title var titleTxt = new Text2('Memory Game', { size: 120, fill: 0xFFFFFF }); titleTxt.anchor.set(0.5, 0.5); self.addChild(titleTxt); titleTxt.x = 2048 / 2; titleTxt.y = 400; // Language selection var languages = ['English', 'Spanish', 'French', 'German', 'Italian']; var selectedLanguage = storage.selectedLanguage || 'English'; var languageTxt = new Text2('Language: ' + selectedLanguage, { size: 60, fill: 0xFFD700 }); languageTxt.anchor.set(0.5, 0.5); self.addChild(languageTxt); languageTxt.x = 2048 / 2; languageTxt.y = 600; // Play button var playBtn = LK.getAsset('symbol2', { anchorX: 0.5, anchorY: 0.5, scaleX: 2, scaleY: 1 }); self.addChild(playBtn); playBtn.x = 2048 / 2; playBtn.y = 800; var playTxt = new Text2('PLAY', { size: 80, fill: 0xFFFFFF }); playTxt.anchor.set(0.5, 0.5); self.addChild(playTxt); playTxt.x = 2048 / 2; playTxt.y = 800; // Save games section var savesTxt = new Text2('Saved Games', { size: 60, fill: 0xFFFFFF }); savesTxt.anchor.set(0.5, 0.5); self.addChild(savesTxt); savesTxt.x = 2048 / 2; savesTxt.y = 1000; // Save slot buttons var saveSlots = []; for (var i = 1; i <= 5; i++) { var savedLevel = storage['saveSlot' + i] || 1; var slotBtn = LK.getAsset('symbol1', { anchorX: 0.5, anchorY: 0.5, scaleX: 1.5, scaleY: 0.8 }); self.addChild(slotBtn); slotBtn.x = 2048 / 2; slotBtn.y = 1100 + (i - 1) * 120; slotBtn.slotIndex = i; var slotTxt = new Text2('Slot ' + i + ' - Level ' + savedLevel, { size: 50, fill: 0xFFFFFF }); slotTxt.anchor.set(0.5, 0.5); self.addChild(slotTxt); slotTxt.x = 2048 / 2; slotTxt.y = 1100 + (i - 1) * 120; saveSlots.push(slotBtn); } // Event handlers languageTxt.down = function (x, y, obj) { var currentIndex = languages.indexOf(selectedLanguage); var nextIndex = (currentIndex + 1) % languages.length; selectedLanguage = languages[nextIndex]; storage.selectedLanguage = selectedLanguage; languageTxt.setText('Language: ' + selectedLanguage); }; playBtn.down = function (x, y, obj) { // Start game with current level self.visible = false; startGame(); }; for (var i = 0; i < saveSlots.length; i++) { saveSlots[i].down = function (x, y, obj) { var slotIndex = obj.slotIndex; var savedLevel = storage['saveSlot' + slotIndex] || 1; currentLevel = savedLevel; storage.currentLevel = currentLevel; self.visible = false; startGame(); }; } return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x2c3e50 }); /**** * Game Code ****/ // Game variables var cards = []; var flippedCards = []; var moves = 0; var startTime = Date.now(); var gameCompleted = false; var canFlipCards = true; var currentLevel = storage.currentLevel || 1; var gameStartTime = Date.now(); var LEVEL_TIME_LIMIT = 120; // 2 minutes in seconds var MOVE_LIMIT = 15; var gameOver = false; var menuScreen = new MenuScreen(); var gameStarted = false; // Grid configuration var GRID_COLS = 4; var GRID_ROWS = 4; var CARD_SIZE = 200; var CARD_SPACING = 20; // UI elements var movesTxt = new Text2('Moves: 0', { size: 60, fill: 0xFFFFFF }); movesTxt.anchor.set(0.5, 0); LK.gui.top.addChild(movesTxt); movesTxt.y = 100; var timerTxt = new Text2('Time: 0:00', { size: 60, fill: 0xFFFFFF }); timerTxt.anchor.set(0.5, 0); LK.gui.top.addChild(timerTxt); timerTxt.y = 180; // Initialize coins from storage var coins = storage.coins || 0; var coinsTxt = new Text2('Coins: ' + coins, { size: 60, fill: 0xFFD700 }); coinsTxt.anchor.set(0.5, 0); LK.gui.top.addChild(coinsTxt); coinsTxt.y = 260; var levelTxt = new Text2('Level: ' + currentLevel, { size: 60, fill: 0xFFFFFF }); levelTxt.anchor.set(0.5, 0); LK.gui.top.addChild(levelTxt); levelTxt.y = 340; // Power-up UI elements var bombTxt = new Text2('Bomb (10 coins)', { size: 40, fill: 0xFF6B6B }); bombTxt.anchor.set(0, 0); LK.gui.topLeft.addChild(bombTxt); bombTxt.x = 120; bombTxt.y = 100; var lightbulbTxt = new Text2('Hint (15 coins)', { size: 40, fill: 0xFFD700 }); lightbulbTxt.anchor.set(0, 0); LK.gui.topLeft.addChild(lightbulbTxt); lightbulbTxt.x = 120; lightbulbTxt.y = 160; var clockTxt = new Text2('Clock (20 coins)', { size: 40, fill: 0x4ECDC4 }); clockTxt.anchor.set(0, 0); LK.gui.topLeft.addChild(clockTxt); clockTxt.x = 120; clockTxt.y = 220; var timerPowerTxt = new Text2('Timer (5 coins)', { size: 40, fill: 0x96CEB4 }); timerPowerTxt.anchor.set(0, 0); LK.gui.topLeft.addChild(timerPowerTxt); timerPowerTxt.x = 120; timerPowerTxt.y = 280; var skipTxt = new Text2('Skip (100 coins)', { size: 40, fill: 0xFF9FF3 }); skipTxt.anchor.set(0, 0); LK.gui.topLeft.addChild(skipTxt); skipTxt.x = 120; skipTxt.y = 340; // Create card types array based on level (4 tiles for first level + 6 tiles per additional level) var totalTiles = 4 + (currentLevel - 1) * 6; // 4 base tiles + 6 per level var pairCount = totalTiles / 2; var cardTypes = []; for (var i = 1; i <= pairCount; i++) { var symbolIndex = (i - 1) % 8 + 1; // Cycle through available symbols cardTypes.push(symbolIndex); cardTypes.push(symbolIndex); // Add pair } // Shuffle function function shuffleArray(array) { for (var i = array.length - 1; i > 0; i--) { var j = Math.floor(Math.random() * (i + 1)); var temp = array[i]; array[i] = array[j]; array[j] = temp; } return array; } // Initialize cards function initializeCards() { var shuffledTypes = shuffleArray(cardTypes); // Calculate dynamic grid size based on total tiles var totalTiles = cardTypes.length; GRID_COLS = Math.ceil(Math.sqrt(totalTiles)); GRID_ROWS = Math.ceil(totalTiles / GRID_COLS); // Adjust card size based on grid size if (totalTiles > 16) { CARD_SIZE = Math.max(120, 200 - (totalTiles - 16) * 5); CARD_SPACING = Math.max(10, 20 - (totalTiles - 16) * 1); } // Calculate grid positioning var gridWidth = GRID_COLS * CARD_SIZE + (GRID_COLS - 1) * CARD_SPACING; var gridHeight = GRID_ROWS * CARD_SIZE + (GRID_ROWS - 1) * CARD_SPACING; var startX = (2048 - gridWidth) / 2 + CARD_SIZE / 2; var startY = (2732 - gridHeight) / 2 + CARD_SIZE / 2; for (var i = 0; i < totalTiles; i++) { var row = Math.floor(i / GRID_COLS); var col = i % GRID_COLS; var card = new Card(shuffledTypes[i]); card.x = startX + col * (CARD_SIZE + CARD_SPACING); card.y = startY + row * (CARD_SIZE + CARD_SPACING); cards.push(card); game.addChild(card); } } // Handle card tap function handleCardTap(card) { if (!canFlipCards || flippedCards.length >= 2 || gameOver) return; card.flip(); flippedCards.push(card); if (flippedCards.length === 2) { moves++; movesTxt.setText('Moves: ' + moves); // Check if move limit exceeded if (moves >= MOVE_LIMIT) { gameOver = true; // Save current level progress before game over storage.currentLevel = currentLevel; LK.setTimeout(function () { LK.showGameOver(); }, 1000); return; } canFlipCards = false; // Check for match after a short delay LK.setTimeout(function () { checkForMatch(); }, 1000); } } // Check if two flipped cards match function checkForMatch() { var card1 = flippedCards[0]; var card2 = flippedCards[1]; if (card1.symbolType === card2.symbolType) { // Match found LK.getSound('match').play(); card1.setMatched(); card2.setMatched(); // Award 5 coins for matching pair coins += 5; storage.coins = coins; coinsTxt.setText('Coins: ' + coins); // Check if game is complete var matchedCount = 0; for (var i = 0; i < cards.length; i++) { if (cards[i].isMatched) { matchedCount++; } } if (matchedCount === cards.length) { gameCompleted = true; // Save current level completion storage.currentLevel = currentLevel; // Check if we've completed all 500 levels if (currentLevel >= 500) { // Show you win when all levels are completed LK.setTimeout(function () { LK.showYouWin(); }, 1000); } else { // Advance to next level currentLevel++; storage.currentLevel = currentLevel; // Save current level to storage levelTxt.setText('Level: ' + currentLevel); // Reset for next level LK.setTimeout(function () { resetLevel(); }, 1000); } } } else { // No match LK.getSound('noMatch').play(); card1.flip(); card2.flip(); } flippedCards = []; canFlipCards = true; } // Reset level for progression function resetLevel() { // Clear existing cards for (var i = 0; i < cards.length; i++) { cards[i].destroy(); } cards = []; flippedCards = []; moves = 0; gameCompleted = false; canFlipCards = true; gameOver = false; gameStartTime = Date.now(); startTime = Date.now(); // Update UI movesTxt.setText('Moves: 0'); timerTxt.setText('Time: 0:00'); // Recreate card types for new level var totalTiles = 4 + (currentLevel - 1) * 6; var pairCount = totalTiles / 2; cardTypes = []; for (var i = 1; i <= pairCount; i++) { var symbolIndex = (i - 1) % 8 + 1; cardTypes.push(symbolIndex); cardTypes.push(symbolIndex); } // Initialize new cards initializeCards(); } // Format time display function formatTime(seconds) { var minutes = Math.floor(seconds / 60); var remainingSeconds = seconds % 60; return minutes + ':' + (remainingSeconds < 10 ? '0' : '') + remainingSeconds; } // Power-up functions function useBomb() { if (coins >= 10) { coins -= 10; storage.coins = coins; coinsTxt.setText('Coins: ' + coins); // Delete 6 random non-matched cards var availableCards = []; for (var i = 0; i < cards.length; i++) { if (!cards[i].isMatched) { availableCards.push(cards[i]); } } var cardsToRemove = Math.min(6, availableCards.length); for (var i = 0; i < cardsToRemove; i++) { var randomIndex = Math.floor(Math.random() * availableCards.length); var cardToRemove = availableCards[randomIndex]; cardToRemove.destroy(); cards.splice(cards.indexOf(cardToRemove), 1); availableCards.splice(randomIndex, 1); } } } function useLightbulb() { if (coins >= 15) { coins -= 15; storage.coins = coins; coinsTxt.setText('Coins: ' + coins); // Find a matching pair that's not matched yet var unmatchedCards = []; for (var i = 0; i < cards.length; i++) { if (!cards[i].isMatched) { unmatchedCards.push(cards[i]); } } // Group by symbol type var symbolGroups = {}; for (var i = 0; i < unmatchedCards.length; i++) { var card = unmatchedCards[i]; if (!symbolGroups[card.symbolType]) { symbolGroups[card.symbolType] = []; } symbolGroups[card.symbolType].push(card); } // Find first pair and show them for (var symbolType in symbolGroups) { if (symbolGroups[symbolType].length >= 2) { var pair = symbolGroups[symbolType].slice(0, 2); for (var i = 0; i < pair.length; i++) { if (!pair[i].isFlipped) { pair[i].flip(); } } break; } } } } function useClock() { if (coins >= 20) { coins -= 20; storage.coins = coins; coinsTxt.setText('Coins: ' + coins); // Add 5 minutes (300 seconds) to game time gameStartTime -= 300000; // Subtract 5 minutes from start time to effectively add time } } function useTimer() { if (coins >= 5) { coins -= 5; storage.coins = coins; coinsTxt.setText('Coins: ' + coins); // Add 1 minute (60 seconds) to game time gameStartTime -= 60000; // Subtract 1 minute from start time to effectively add time } } function useSkip() { if (coins >= 100) { coins -= 100; storage.coins = coins; coinsTxt.setText('Coins: ' + coins); // Save current level before skipping storage.currentLevel = currentLevel; // Check if we've completed all 500 levels if (currentLevel >= 500) { // Show you win when all levels are completed LK.setTimeout(function () { LK.showYouWin(); }, 1000); } else { // Advance to next level currentLevel++; storage.currentLevel = currentLevel; // Save current level to storage levelTxt.setText('Level: ' + currentLevel); // Reset for next level LK.setTimeout(function () { resetLevel(); }, 1000); } } } // Add click handlers for power-ups bombTxt.down = function (x, y, obj) { useBomb(); }; lightbulbTxt.down = function (x, y, obj) { useLightbulb(); }; clockTxt.down = function (x, y, obj) { useClock(); }; timerPowerTxt.down = function (x, y, obj) { useTimer(); }; skipTxt.down = function (x, y, obj) { useSkip(); }; // Show menu screen initially game.addChild(menuScreen); // Start game function function startGame() { gameStarted = true; // Save current level to a save slot (slot 1 by default) storage.saveSlot1 = currentLevel; // Initialize the game initializeCards(); } // Main game update loop game.update = function () { // Only update game when started if (!gameStarted) return; // Update timer if (!gameCompleted && !gameOver) { var elapsedTime = Math.floor((Date.now() - gameStartTime) / 1000); var remainingTime = Math.max(0, LEVEL_TIME_LIMIT - elapsedTime); timerTxt.setText('Time: ' + formatTime(remainingTime)); // Check if time is up if (remainingTime <= 0) { gameOver = true; // Save current level progress before game over storage.currentLevel = currentLevel; LK.showGameOver(); } } };
===================================================================
--- original.js
+++ change.js
@@ -78,8 +78,116 @@
}
};
return self;
});
+var MenuScreen = Container.expand(function () {
+ var self = Container.call(this);
+ // Background
+ var menuBg = LK.getAsset('cardBack', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ scaleX: 15,
+ scaleY: 20
+ });
+ self.addChild(menuBg);
+ menuBg.x = 2048 / 2;
+ menuBg.y = 2732 / 2;
+ // Title
+ var titleTxt = new Text2('Memory Game', {
+ size: 120,
+ fill: 0xFFFFFF
+ });
+ titleTxt.anchor.set(0.5, 0.5);
+ self.addChild(titleTxt);
+ titleTxt.x = 2048 / 2;
+ titleTxt.y = 400;
+ // Language selection
+ var languages = ['English', 'Spanish', 'French', 'German', 'Italian'];
+ var selectedLanguage = storage.selectedLanguage || 'English';
+ var languageTxt = new Text2('Language: ' + selectedLanguage, {
+ size: 60,
+ fill: 0xFFD700
+ });
+ languageTxt.anchor.set(0.5, 0.5);
+ self.addChild(languageTxt);
+ languageTxt.x = 2048 / 2;
+ languageTxt.y = 600;
+ // Play button
+ var playBtn = LK.getAsset('symbol2', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ scaleX: 2,
+ scaleY: 1
+ });
+ self.addChild(playBtn);
+ playBtn.x = 2048 / 2;
+ playBtn.y = 800;
+ var playTxt = new Text2('PLAY', {
+ size: 80,
+ fill: 0xFFFFFF
+ });
+ playTxt.anchor.set(0.5, 0.5);
+ self.addChild(playTxt);
+ playTxt.x = 2048 / 2;
+ playTxt.y = 800;
+ // Save games section
+ var savesTxt = new Text2('Saved Games', {
+ size: 60,
+ fill: 0xFFFFFF
+ });
+ savesTxt.anchor.set(0.5, 0.5);
+ self.addChild(savesTxt);
+ savesTxt.x = 2048 / 2;
+ savesTxt.y = 1000;
+ // Save slot buttons
+ var saveSlots = [];
+ for (var i = 1; i <= 5; i++) {
+ var savedLevel = storage['saveSlot' + i] || 1;
+ var slotBtn = LK.getAsset('symbol1', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ scaleX: 1.5,
+ scaleY: 0.8
+ });
+ self.addChild(slotBtn);
+ slotBtn.x = 2048 / 2;
+ slotBtn.y = 1100 + (i - 1) * 120;
+ slotBtn.slotIndex = i;
+ var slotTxt = new Text2('Slot ' + i + ' - Level ' + savedLevel, {
+ size: 50,
+ fill: 0xFFFFFF
+ });
+ slotTxt.anchor.set(0.5, 0.5);
+ self.addChild(slotTxt);
+ slotTxt.x = 2048 / 2;
+ slotTxt.y = 1100 + (i - 1) * 120;
+ saveSlots.push(slotBtn);
+ }
+ // Event handlers
+ languageTxt.down = function (x, y, obj) {
+ var currentIndex = languages.indexOf(selectedLanguage);
+ var nextIndex = (currentIndex + 1) % languages.length;
+ selectedLanguage = languages[nextIndex];
+ storage.selectedLanguage = selectedLanguage;
+ languageTxt.setText('Language: ' + selectedLanguage);
+ };
+ playBtn.down = function (x, y, obj) {
+ // Start game with current level
+ self.visible = false;
+ startGame();
+ };
+ for (var i = 0; i < saveSlots.length; i++) {
+ saveSlots[i].down = function (x, y, obj) {
+ var slotIndex = obj.slotIndex;
+ var savedLevel = storage['saveSlot' + slotIndex] || 1;
+ currentLevel = savedLevel;
+ storage.currentLevel = currentLevel;
+ self.visible = false;
+ startGame();
+ };
+ }
+ return self;
+});
/****
* Initialize Game
****/
@@ -101,8 +209,10 @@
var gameStartTime = Date.now();
var LEVEL_TIME_LIMIT = 120; // 2 minutes in seconds
var MOVE_LIMIT = 15;
var gameOver = false;
+var menuScreen = new MenuScreen();
+var gameStarted = false;
// Grid configuration
var GRID_COLS = 4;
var GRID_ROWS = 4;
var CARD_SIZE = 200;
@@ -451,12 +561,22 @@
};
skipTxt.down = function (x, y, obj) {
useSkip();
};
-// Initialize the game
-initializeCards();
+// Show menu screen initially
+game.addChild(menuScreen);
+// Start game function
+function startGame() {
+ gameStarted = true;
+ // Save current level to a save slot (slot 1 by default)
+ storage.saveSlot1 = currentLevel;
+ // Initialize the game
+ initializeCards();
+}
// Main game update loop
game.update = function () {
+ // Only update game when started
+ if (!gameStarted) return;
// Update timer
if (!gameCompleted && !gameOver) {
var elapsedTime = Math.floor((Date.now() - gameStartTime) / 1000);
var remainingTime = Math.max(0, LEVEL_TIME_LIMIT - elapsedTime);