User prompt
Fix errors
User prompt
Change symbol shapes to 25 different shapes.
User prompt
Fix all errors ↪💡 Consider importing and using the following plugins: @upit/storage.v1
User prompt
Please fix the bug: 'Script error.' in or related to this line: 'storage.buildingPositions = positions;' Line Number: 1469 ↪💡 Consider importing and using the following plugins: @upit/storage.v1
User prompt
Add worldbackground as background for spooky world tab
User prompt
Remove worldbackground as background for main menu
User prompt
Add worldbackground as background for world
User prompt
Add worldbackground as background for world button.
User prompt
Clean code.
User prompt
Play button should return player to level 1.
User prompt
Cannot go back to main menu after playing game
User prompt
Shop function does not work. Cannot buy any of the items
User prompt
fix errors
User prompt
Create a system to allow players to purchase power-ups and buildings. ↪💡 Consider importing and using the following plugins: @upit/storage.v1
User prompt
Cannot buy anything in shop button,
User prompt
Add assets for buildings.
User prompt
Make the building tab in the shop functional. Cannot click on any of the buildings.
User prompt
fix errors
User prompt
Please fix the bug: 'Cannot set properties of undefined (setting 'down')' in or related to this line: 'playBackBtn.down = function (x, y, obj) {' Line Number: 1574
User prompt
Add back button to play funtion.
User prompt
Background is black
User prompt
All word text black turn white
User prompt
Make text bold.
User prompt
Apread out everything to fit screen
User prompt
Change background to white.
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var storage = LK.import("@upit/storage.v1", { coins: 0, currentLevel: 1, bombCount: 0, hintCount: 0, clockCount: 0, timerCount: 0, skipCount: 0, mansionCount: 0, hutCount: 0, patchCount: 0, towerCount: 0, castleCount: 0, ghostCount: 0, wizardCount: 0, catCount: 0, buildingPositions: {} }); /**** * 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 = LK.getAsset('cardBack', { anchorX: 0.5, anchorY: 0.5 }); self.addChild(cardBack); // Card front (white background) var cardFront = LK.getAsset('cardFront', { anchorX: 0.5, anchorY: 0.5, alpha: 0 }); self.addChild(cardFront); // Symbol on the card var symbol = LK.getAsset('symbol' + symbolType, { anchorX: 0.5, anchorY: 0.5, alpha: 0 }); self.addChild(symbol); 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; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x000000 }); /**** * Game Code ****/ // Game variables // Game state variables function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); } var cards = []; var flippedCards = []; var moves = 0; var gameCompleted = false; var canFlipCards = true; var gameOver = false; var showMenu = true; // Level and timing variables var currentLevel = storage.currentLevel || 1; var startTime = Date.now(); var gameStartTime = Date.now(); var LEVEL_TIME_LIMIT = 120; // 2 minutes in seconds var MOVE_LIMIT = 15; // 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: 0x000000, fontWeight: 'bold' }); movesTxt.anchor.set(0.5, 0); LK.gui.top.addChild(movesTxt); movesTxt.y = 100; var timerTxt = new Text2('Time: 0:00', { size: 60, fill: 0x000000, fontWeight: 'bold' }); timerTxt.anchor.set(0.5, 0); LK.gui.top.addChild(timerTxt); timerTxt.y = 180; // Initialize storage with defaults to prevent undefined access errors // Initialize coins from storage var coins = storage.coins || 0; var coinsTxt = new Text2('Coins: ' + coins, { size: 60, fill: 0xFFD700, fontWeight: 'bold' }); coinsTxt.anchor.set(0.5, 0); LK.gui.top.addChild(coinsTxt); coinsTxt.y = 260; // Initialize saved games from individual storage slots with validation var savedGames = []; for (var i = 0; i < 5; i++) { var slotData = storage['savedGame' + i] || null; // Validate slotData structure if (slotData && _typeof(slotData) === 'object' && typeof slotData.level === 'number' && typeof slotData.coins === 'number') { savedGames.push(slotData); } else { savedGames.push(null); } } if (!Array.isArray(savedGames)) { savedGames = []; } while (savedGames.length < 5) { savedGames.push(null); } var levelTxt = new Text2('Level: ' + currentLevel, { size: 60, fill: 0x000000, fontWeight: 'bold' }); levelTxt.anchor.set(0.5, 0); LK.gui.top.addChild(levelTxt); levelTxt.y = 340; // Level completion notification text var levelCompleteTxt = new Text2('LEVEL COMPLETE!', { size: 100, fill: 0x00FF00, fontWeight: 'bold' }); levelCompleteTxt.anchor.set(0.5, 0.5); levelCompleteTxt.x = 2048 / 2; levelCompleteTxt.y = 2732 / 2; levelCompleteTxt.visible = false; game.addChild(levelCompleteTxt); // Power-up UI elements var bombTxt = new Text2('Bomb: ' + (storage.bombCount || 0), { size: 40, fill: 0xFF6B6B, fontWeight: 'bold' }); bombTxt.anchor.set(0, 0); LK.gui.topLeft.addChild(bombTxt); bombTxt.x = 120; bombTxt.y = 100; var lightbulbTxt = new Text2('Hint: ' + (storage.hintCount || 0), { size: 40, fill: 0xFFD700, fontWeight: 'bold' }); lightbulbTxt.anchor.set(0, 0); LK.gui.topLeft.addChild(lightbulbTxt); lightbulbTxt.x = 120; lightbulbTxt.y = 160; var clockTxt = new Text2('Clock: ' + (storage.clockCount || 0), { size: 40, fill: 0x4ECDC4, fontWeight: 'bold' }); clockTxt.anchor.set(0, 0); LK.gui.topLeft.addChild(clockTxt); clockTxt.x = 120; clockTxt.y = 220; var timerPowerTxt = new Text2('Timer: ' + (storage.timerCount || 0), { size: 40, fill: 0x96CEB4, fontWeight: 'bold' }); timerPowerTxt.anchor.set(0, 0); LK.gui.topLeft.addChild(timerPowerTxt); timerPowerTxt.x = 120; timerPowerTxt.y = 280; var skipTxt = new Text2('Skip: ' + (storage.skipCount || 0), { size: 40, fill: 0xFF9FF3, fontWeight: 'bold' }); skipTxt.anchor.set(0, 0); LK.gui.topLeft.addChild(skipTxt); skipTxt.x = 120; skipTxt.y = 340; // Menu screen elements var menuContainer = new Container(); game.addChild(menuContainer); var titleTxt = new Text2('SPOOKY MEMORY MATCH', { size: 120, fill: 0xFF6600, fontWeight: 'bold' }); titleTxt.anchor.set(0.5, 0.5); titleTxt.x = 2048 / 2; titleTxt.y = 500; menuContainer.addChild(titleTxt); var levelInfoTxt = new Text2('Current Level: ' + currentLevel, { size: 80, fill: 0xFFD700, fontWeight: 'bold' }); levelInfoTxt.anchor.set(0.5, 0.5); levelInfoTxt.x = 2048 / 2; levelInfoTxt.y = 700; menuContainer.addChild(levelInfoTxt); var coinsInfoTxt = new Text2('Coins: ' + coins, { size: 80, fill: 0xFFD700, fontWeight: 'bold' }); coinsInfoTxt.anchor.set(0.5, 0.5); coinsInfoTxt.x = 2048 / 2; coinsInfoTxt.y = 850; menuContainer.addChild(coinsInfoTxt); var playBtn = new Text2('PLAY', { size: 100, fill: 0x4ECDC4, fontWeight: 'bold' }); playBtn.anchor.set(0.5, 0.5); playBtn.x = 2048 / 2; playBtn.y = 1050; menuContainer.addChild(playBtn); var instructionsTxt = new Text2('Match spooky pairs to advance levels!\nEarn coins to buy magical power-ups!', { size: 60, fill: 0xFF6600, fontWeight: 'bold' }); instructionsTxt.anchor.set(0.5, 0.5); instructionsTxt.x = 2048 / 2; instructionsTxt.y = 2200; menuContainer.addChild(instructionsTxt); var progressTxt = new Text2('Progress: ' + currentLevel + '/500', { size: 70, fill: 0x96CEB4, fontWeight: 'bold' }); progressTxt.anchor.set(0.5, 0.5); progressTxt.x = 2048 / 2; progressTxt.y = 2400; menuContainer.addChild(progressTxt); // Shop button for buying power-ups var shopBtn = new Text2('SHOP', { size: 100, fill: 0xFFD700, fontWeight: 'bold' }); shopBtn.anchor.set(0.5, 0.5); shopBtn.x = 2048 / 2; shopBtn.y = 1250; menuContainer.addChild(shopBtn); // Shop screen elements var shopContainer = new Container(); shopContainer.visible = false; game.addChild(shopContainer); var shopTitleTxt = new Text2('SHOP', { size: 120, fill: 0xFFD700, fontWeight: 'bold' }); shopTitleTxt.anchor.set(0.5, 0.5); shopTitleTxt.x = 2048 / 2; shopTitleTxt.y = 400; shopContainer.addChild(shopTitleTxt); var shopCoinsTxt = new Text2('Coins: ' + coins, { size: 80, fill: 0xFFD700, fontWeight: 'bold' }); shopCoinsTxt.anchor.set(0.5, 0.5); shopCoinsTxt.x = 2048 / 2; shopCoinsTxt.y = 500; shopContainer.addChild(shopCoinsTxt); // Tab buttons var powerUpTabBtn = new Text2('POWER-UPS', { size: 80, fill: 0x4ECDC4, fontWeight: 'bold' }); powerUpTabBtn.anchor.set(0.5, 0.5); powerUpTabBtn.x = 2048 / 2 - 200; powerUpTabBtn.y = 600; shopContainer.addChild(powerUpTabBtn); var buildingTabBtn = new Text2('BUILDINGS', { size: 80, fill: 0x666666, fontWeight: 'bold' }); buildingTabBtn.anchor.set(0.5, 0.5); buildingTabBtn.x = 2048 / 2 + 200; buildingTabBtn.y = 600; shopContainer.addChild(buildingTabBtn); // Power-ups tab content var powerUpTabContainer = new Container(); powerUpTabContainer.visible = true; // Start with power-ups tab visible shopContainer.addChild(powerUpTabContainer); var shopBombBtn = new Text2('BOMB - 10 Coins\n(Removes 6 random cards)', { size: 60, fill: 0xFF6B6B, fontWeight: 'bold' }); shopBombBtn.anchor.set(0.5, 0.5); shopBombBtn.x = 2048 / 2; shopBombBtn.y = 800; powerUpTabContainer.addChild(shopBombBtn); var shopHintBtn = new Text2('HINT - 15 Coins\n(Reveals a matching pair)', { size: 60, fill: 0xFFD700, fontWeight: 'bold' }); shopHintBtn.anchor.set(0.5, 0.5); shopHintBtn.x = 2048 / 2; shopHintBtn.y = 1000; powerUpTabContainer.addChild(shopHintBtn); var shopClockBtn = new Text2('CLOCK - 20 Coins\n(Adds 5 minutes)', { size: 60, fill: 0x4ECDC4, fontWeight: 'bold' }); shopClockBtn.anchor.set(0.5, 0.5); shopClockBtn.x = 2048 / 2; shopClockBtn.y = 1200; powerUpTabContainer.addChild(shopClockBtn); var shopTimerBtn = new Text2('TIMER - 5 Coins\n(Adds 1 minute)', { size: 60, fill: 0x96CEB4, fontWeight: 'bold' }); shopTimerBtn.anchor.set(0.5, 0.5); shopTimerBtn.x = 2048 / 2; shopTimerBtn.y = 1400; powerUpTabContainer.addChild(shopTimerBtn); var shopSkipBtn = new Text2('SKIP - 100 Coins\n(Skip current level)', { size: 60, fill: 0xFF9FF3, fontWeight: 'bold' }); shopSkipBtn.anchor.set(0.5, 0.5); shopSkipBtn.x = 2048 / 2; shopSkipBtn.y = 1600; powerUpTabContainer.addChild(shopSkipBtn); // Buildings tab content var buildingTabContainer = new Container(); buildingTabContainer.visible = false; shopContainer.addChild(buildingTabContainer); var hauntedMansionBtn = new Text2('HAUNTED MANSION - 50 Coins\n(Spooky decoration)', { size: 60, fill: 0x4B0082, fontWeight: 'bold' }); hauntedMansionBtn.anchor.set(0.5, 0.5); hauntedMansionBtn.x = 2048 / 2; hauntedMansionBtn.y = 800; buildingTabContainer.addChild(hauntedMansionBtn); var witchHutBtn = new Text2('WITCH HUT - 75 Coins\n(Magical dwelling)', { size: 60, fill: 0x228B22, fontWeight: 'bold' }); witchHutBtn.anchor.set(0.5, 0.5); witchHutBtn.x = 2048 / 2; witchHutBtn.y = 950; buildingTabContainer.addChild(witchHutBtn); var pumpkinPatchBtn = new Text2('PUMPKIN PATCH - 30 Coins\n(Halloween decoration)', { size: 60, fill: 0xFF8C00, fontWeight: 'bold' }); pumpkinPatchBtn.anchor.set(0.5, 0.5); pumpkinPatchBtn.x = 2048 / 2; pumpkinPatchBtn.y = 1100; buildingTabContainer.addChild(pumpkinPatchBtn); var ghostlyTowerBtn = new Text2('GHOSTLY TOWER - 100 Coins\n(Spectral building)', { size: 60, fill: 0xF5F5F5, fontWeight: 'bold' }); ghostlyTowerBtn.anchor.set(0.5, 0.5); ghostlyTowerBtn.x = 2048 / 2; ghostlyTowerBtn.y = 1250; buildingTabContainer.addChild(ghostlyTowerBtn); var vampireCastleBtn = new Text2('VAMPIRE CASTLE - 200 Coins\n(Dark fortress)', { size: 60, fill: 0x8B0000, fontWeight: 'bold' }); vampireCastleBtn.anchor.set(0.5, 0.5); vampireCastleBtn.x = 2048 / 2; vampireCastleBtn.y = 1400; buildingTabContainer.addChild(vampireCastleBtn); // NPC characters var friendlyGhostBtn = new Text2('FRIENDLY GHOST - 40 Coins\n(Helpful NPC)', { size: 60, fill: 0xD3D3D3, fontWeight: 'bold' }); friendlyGhostBtn.anchor.set(0.5, 0.5); friendlyGhostBtn.x = 2048 / 2; friendlyGhostBtn.y = 1550; buildingTabContainer.addChild(friendlyGhostBtn); var wizardBtn = new Text2('WIZARD - 60 Coins\n(Wise NPC)', { size: 60, fill: 0x191970, fontWeight: 'bold' }); wizardBtn.anchor.set(0.5, 0.5); wizardBtn.x = 2048 / 2; wizardBtn.y = 1700; buildingTabContainer.addChild(wizardBtn); var blackCatBtn = new Text2('BLACK CAT - 25 Coins\n(Mystical companion)', { size: 60, fill: 0x000000, fontWeight: 'bold' }); blackCatBtn.anchor.set(0.5, 0.5); blackCatBtn.x = 2048 / 2; blackCatBtn.y = 1850; buildingTabContainer.addChild(blackCatBtn); var shopBackBtn = new Text2('BACK TO MENU', { size: 80, fill: 0xCCCCCC, fontWeight: 'bold' }); shopBackBtn.anchor.set(0.5, 0.5); shopBackBtn.x = 2048 / 2; shopBackBtn.y = 2000; shopContainer.addChild(shopBackBtn); // Saved Games button var savedGamesBtn = new Text2('SAVED GAMES', { size: 100, fill: 0x96CEB4, fontWeight: 'bold' }); savedGamesBtn.anchor.set(0.5, 0.5); savedGamesBtn.x = 2048 / 2; savedGamesBtn.y = 1450; menuContainer.addChild(savedGamesBtn); // World button var worldBtn = new Container(); worldBtn.x = 2048 / 2; worldBtn.y = 1650; // Add background image var worldBackground = LK.getAsset('worldbackground', { anchorX: 0.5, anchorY: 0.5, scaleX: 2, scaleY: 2 }); worldBtn.addChild(worldBackground); // Add text on top of background var worldBtnText = new Text2('WORLD', { size: 100, fill: 0x4B0082, fontWeight: 'bold' }); worldBtnText.anchor.set(0.5, 0.5); worldBtn.addChild(worldBtnText); menuContainer.addChild(worldBtn); // Saved Games screen container var savedGamesContainer = new Container(); savedGamesContainer.visible = false; game.addChild(savedGamesContainer); var savedGamesTitleTxt = new Text2('SAVED GAMES', { size: 120, fill: 0x96CEB4, fontWeight: 'bold' }); savedGamesTitleTxt.anchor.set(0.5, 0.5); savedGamesTitleTxt.x = 2048 / 2; savedGamesTitleTxt.y = 400; savedGamesContainer.addChild(savedGamesTitleTxt); var savedGamesInstructionTxt = new Text2('Click a slot to load or save your game progress', { size: 60, fill: 0x000000, fontWeight: 'bold' }); savedGamesInstructionTxt.anchor.set(0.5, 0.5); savedGamesInstructionTxt.x = 2048 / 2; savedGamesInstructionTxt.y = 550; savedGamesContainer.addChild(savedGamesInstructionTxt); // Create 5 save game slot buttons in saved games container var saveSlots = []; for (var i = 0; i < 5; i++) { var slotData = savedGames[i]; var slotText = 'Slot ' + (i + 1); if (slotData) { slotText += ' - Level ' + slotData.level + ' (' + slotData.coins + ' coins)'; if (slotData.result) { slotText += ' - ' + slotData.result; } } else { slotText += ' - Empty'; } var slotBtn = new Text2(slotText, { size: 60, fill: slotData ? 0x4ECDC4 : 0x666666, fontWeight: 'bold' }); slotBtn.anchor.set(0.5, 0.5); slotBtn.x = 2048 / 2; slotBtn.y = 750 + i * 150; slotBtn.slotIndex = i; savedGamesContainer.addChild(slotBtn); saveSlots.push(slotBtn); } // Back to menu button for saved games var savedGamesBackBtn = new Text2('BACK TO MENU', { size: 80, fill: 0xCCCCCC, fontWeight: 'bold' }); savedGamesBackBtn.anchor.set(0.5, 0.5); savedGamesBackBtn.x = 2048 / 2; savedGamesBackBtn.y = 1500; savedGamesContainer.addChild(savedGamesBackBtn); // Create card types array based on level (4 tiles for first level + 6 tiles per additional level) var totalTiles; if (currentLevel === 1) { totalTiles = 4; // First level has exactly 4 tiles } else { totalTiles = 4 + (currentLevel - 1) * 6; // 4 base tiles + 6 per level } var pairCount = totalTiles / 2; var cardTypes = []; for (var i = 1; i <= pairCount; i++) { // Ensure symbol index stays within valid range (1-25) var symbolIndex = (i - 1) % 25 + 1; // Cycle through 25 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; // Auto-save failed attempt autoSaveGame('Failed - Move Limit'); 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] && typeof cards[i].isMatched !== 'undefined' && cards[i].isMatched) { matchedCount++; } } if (matchedCount === cards.length) { gameCompleted = true; // Save current level completion storage.currentLevel = currentLevel; // Auto-save completed level autoSaveGame('Completed'); // Award bonus coins for completing level coins += 10; storage.coins = coins; coinsTxt.setText('Coins: ' + coins); // 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); // Update menu progress display levelInfoTxt.setText('Current Level: ' + currentLevel); progressTxt.setText('Progress: ' + currentLevel + '/500'); // Show level completion message LK.effects.flashScreen(0x00FF00, 1000); // Reset for next level LK.setTimeout(function () { resetLevel(); }, 1500); } } } else { // No match LK.getSound('noMatch').play(); card1.flip(); card2.flip(); } flippedCards = []; canFlipCards = true; } // Reset level for progression function resetLevel() { // Show level completion message briefly if advancing if (currentLevel > 1) { levelCompleteTxt.setText('LEVEL ' + (currentLevel - 1) + ' COMPLETE!'); levelCompleteTxt.visible = true; LK.setTimeout(function () { levelCompleteTxt.visible = false; }, 2000); } // Clear existing cards for (var i = 0; i < cards.length; i++) { if (cards[i] && typeof cards[i].destroy === 'function') { 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; if (currentLevel === 1) { totalTiles = 4; // First level has exactly 4 tiles } else { totalTiles = 4 + (currentLevel - 1) * 6; // 4 base tiles + 6 per level } var pairCount = totalTiles / 2; cardTypes = []; for (var i = 1; i <= pairCount; i++) { // Ensure symbol index stays within valid range (1-25) var symbolIndex = (i - 1) % 25 + 1; // Cycle through 25 available symbols 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; } // Building purchase functions function buyHauntedMansion() { if (coins >= 50) { coins = Math.max(0, coins - 50); storage.coins = coins; shopCoinsTxt.setText('Coins: ' + coins); coinsInfoTxt.setText('Coins: ' + coins); var mansionCount = storage.mansionCount || 0; storage.mansionCount = mansionCount + 1; LK.effects.flashScreen(0x4B0082, 500); } } function buyWitchHut() { if (coins >= 75) { coins = Math.max(0, coins - 75); storage.coins = coins; shopCoinsTxt.setText('Coins: ' + coins); coinsInfoTxt.setText('Coins: ' + coins); var hutCount = storage.hutCount || 0; storage.hutCount = hutCount + 1; LK.effects.flashScreen(0x228B22, 500); } } function buyPumpkinPatch() { if (coins >= 30) { coins = Math.max(0, coins - 30); storage.coins = coins; shopCoinsTxt.setText('Coins: ' + coins); coinsInfoTxt.setText('Coins: ' + coins); var patchCount = storage.patchCount || 0; storage.patchCount = patchCount + 1; LK.effects.flashScreen(0xFF8C00, 500); } } function buyGhostlyTower() { if (coins >= 100) { coins = Math.max(0, coins - 100); storage.coins = coins; shopCoinsTxt.setText('Coins: ' + coins); coinsInfoTxt.setText('Coins: ' + coins); var towerCount = storage.towerCount || 0; storage.towerCount = towerCount + 1; LK.effects.flashScreen(0xF5F5F5, 500); } } function buyVampireCastle() { if (coins >= 200) { coins = Math.max(0, coins - 200); storage.coins = coins; shopCoinsTxt.setText('Coins: ' + coins); coinsInfoTxt.setText('Coins: ' + coins); var castleCount = storage.castleCount || 0; storage.castleCount = castleCount + 1; LK.effects.flashScreen(0x8B0000, 500); } } function buyFriendlyGhost() { if (coins >= 40) { coins = Math.max(0, coins - 40); storage.coins = coins; shopCoinsTxt.setText('Coins: ' + coins); coinsInfoTxt.setText('Coins: ' + coins); var ghostCount = storage.ghostCount || 0; storage.ghostCount = ghostCount + 1; LK.effects.flashScreen(0xD3D3D3, 500); } } function buyWizard() { if (coins >= 60) { coins = Math.max(0, coins - 60); storage.coins = coins; shopCoinsTxt.setText('Coins: ' + coins); coinsInfoTxt.setText('Coins: ' + coins); var wizardCount = storage.wizardCount || 0; storage.wizardCount = wizardCount + 1; LK.effects.flashScreen(0x191970, 500); } } function buyBlackCat() { if (coins >= 25) { coins = Math.max(0, coins - 25); storage.coins = coins; shopCoinsTxt.setText('Coins: ' + coins); coinsInfoTxt.setText('Coins: ' + coins); var catCount = storage.catCount || 0; storage.catCount = catCount + 1; LK.effects.flashScreen(0x000000, 500); } } // Shop power-up purchase functions function buyBomb() { if (coins >= 10) { coins = Math.max(0, coins - 10); storage.coins = coins; shopCoinsTxt.setText('Coins: ' + coins); coinsInfoTxt.setText('Coins: ' + coins); // Add bomb to inventory (stored in storage) var bombCount = storage.bombCount || 0; storage.bombCount = bombCount + 1; bombTxt.setText('Bomb: ' + (storage.bombCount || 0)); LK.effects.flashScreen(0x00FF00, 500); } } function buyHint() { if (coins >= 15) { coins = Math.max(0, coins - 15); storage.coins = coins; shopCoinsTxt.setText('Coins: ' + coins); coinsInfoTxt.setText('Coins: ' + coins); // Add hint to inventory var hintCount = storage.hintCount || 0; storage.hintCount = hintCount + 1; lightbulbTxt.setText('Hint: ' + (storage.hintCount || 0)); LK.effects.flashScreen(0x00FF00, 500); } } function buyClock() { if (coins >= 20) { coins = Math.max(0, coins - 20); storage.coins = coins; shopCoinsTxt.setText('Coins: ' + coins); coinsInfoTxt.setText('Coins: ' + coins); // Add clock to inventory var clockCount = storage.clockCount || 0; storage.clockCount = clockCount + 1; clockTxt.setText('Clock: ' + (storage.clockCount || 0)); LK.effects.flashScreen(0x00FF00, 500); } } function buyTimer() { if (coins >= 5) { coins = Math.max(0, coins - 5); storage.coins = coins; shopCoinsTxt.setText('Coins: ' + coins); coinsInfoTxt.setText('Coins: ' + coins); // Add timer to inventory var timerCount = storage.timerCount || 0; storage.timerCount = timerCount + 1; timerPowerTxt.setText('Timer: ' + (storage.timerCount || 0)); LK.effects.flashScreen(0x00FF00, 500); } } function buySkip() { if (coins >= 100) { coins = Math.max(0, coins - 100); storage.coins = coins; shopCoinsTxt.setText('Coins: ' + coins); coinsInfoTxt.setText('Coins: ' + coins); // Add skip to inventory var skipCount = storage.skipCount || 0; storage.skipCount = skipCount + 1; skipTxt.setText('Skip: ' + (storage.skipCount || 0)); LK.effects.flashScreen(0x00FF00, 500); } } // Power-up functions function useBomb() { var bombCount = storage.bombCount || 0; if (bombCount > 0) { storage.bombCount = bombCount - 1; // Update display bombTxt.setText('Bomb: ' + (storage.bombCount || 0)); // Delete 6 random non-matched cards var availableCards = []; for (var i = 0; i < cards.length; i++) { if (cards[i] && typeof cards[i].isMatched !== 'undefined' && !cards[i].isMatched) { availableCards.push(cards[i]); } } var cardsToRemove = Math.min(6, availableCards.length); for (var i = 0; i < cardsToRemove; i++) { if (availableCards.length > 0) { var randomIndex = Math.floor(Math.random() * availableCards.length); var cardToRemove = availableCards[randomIndex]; if (cardToRemove && cardToRemove.destroy) { cardToRemove.destroy(); var cardIndex = cards.indexOf(cardToRemove); if (cardIndex !== -1) { cards.splice(cardIndex, 1); } availableCards.splice(randomIndex, 1); } } } } } function useLightbulb() { var hintCount = storage.hintCount || 0; if (hintCount > 0) { storage.hintCount = hintCount - 1; // Update display lightbulbTxt.setText('Hint: ' + (storage.hintCount || 0)); // Find a matching pair that's not matched yet var unmatchedCards = []; for (var i = 0; i < cards.length; i++) { if (cards[i] && typeof cards[i].isMatched !== 'undefined' && !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() { var clockCount = storage.clockCount || 0; if (clockCount > 0) { storage.clockCount = clockCount - 1; // Update display clockTxt.setText('Clock: ' + (storage.clockCount || 0)); // Add 5 minutes (300 seconds) to game time gameStartTime -= 300000; // Subtract 5 minutes from start time to effectively add time } } function useTimer() { var timerCount = storage.timerCount || 0; if (timerCount > 0) { storage.timerCount = timerCount - 1; // Update display timerPowerTxt.setText('Timer: ' + (storage.timerCount || 0)); // Add 1 minute (60 seconds) to game time gameStartTime -= 60000; // Subtract 1 minute from start time to effectively add time } } function useSkip() { var skipCount = storage.skipCount || 0; if (skipCount > 0) { storage.skipCount = skipCount - 1; // Update display skipTxt.setText('Skip: ' + (storage.skipCount || 0)); // 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); } } } // Function to save current game state function saveGame(slotIndex) { // Create flattened gameData object with only literals var gameData = { level: currentLevel, coins: coins, timestamp: Date.now() }; // Ensure savedGames is initialized as an array if (!Array.isArray(savedGames)) { savedGames = []; } // Ensure we have enough slots while (savedGames.length <= slotIndex) { savedGames.push(null); } savedGames[slotIndex] = gameData; storage['savedGame' + slotIndex] = gameData; // Update the slot button text only if saveSlots exists and has the slot if (saveSlots && saveSlots[slotIndex]) { var slotBtn = saveSlots[slotIndex]; slotBtn.setText('Slot ' + (slotIndex + 1) + ' - Level ' + gameData.level + ' (' + gameData.coins + ' coins)'); slotBtn.tint = 0x4ECDC4; } } // Function to auto-save to circular buffer of latest 5 games function autoSaveGame(gameResult) { // Create flattened gameData object with only literals var gameData = { level: currentLevel, coins: coins, timestamp: Date.now(), result: gameResult }; // Ensure savedGames is initialized as an array if (!Array.isArray(savedGames)) { savedGames = []; } // Create a new array to avoid reference issues var newSavedGames = []; // Add new game to the beginning newSavedGames.push(gameData); // Add existing games (up to 4 more) for (var i = 0; i < Math.min(4, savedGames.length); i++) { if (savedGames[i]) { newSavedGames.push(savedGames[i]); } } savedGames = newSavedGames; // Keep only the latest 5 games if (savedGames.length > 5) { savedGames = savedGames.slice(0, 5); } // Save each slot individually to storage with only literals for (var i = 0; i < 5; i++) { if (i < savedGames.length && savedGames[i]) { storage['savedGame' + i] = { level: savedGames[i].level, coins: savedGames[i].coins, timestamp: savedGames[i].timestamp, result: savedGames[i].result || '' }; } else { storage['savedGame' + i] = null; } } // Update all slot buttons if they exist if (saveSlots) { for (var i = 0; i < 5; i++) { if (saveSlots[i]) { var slotData = savedGames[i]; var slotText = 'Slot ' + (i + 1); if (slotData) { slotText += ' - Level ' + slotData.level + ' (' + slotData.coins + ' coins)'; if (slotData.result) { slotText += ' - ' + slotData.result; } } else { slotText += ' - Empty'; } saveSlots[i].setText(slotText); saveSlots[i].tint = slotData ? 0x4ECDC4 : 0x666666; } } } } // Function to load saved game function loadGame(slotIndex) { if (slotIndex >= 0 && slotIndex < savedGames.length && savedGames[slotIndex]) { var gameData = savedGames[slotIndex]; if (gameData && typeof gameData.level === 'number' && typeof gameData.coins === 'number') { currentLevel = Math.max(1, Math.min(500, gameData.level)); coins = Math.max(0, gameData.coins); storage.currentLevel = currentLevel; storage.coins = coins; // Update UI levelInfoTxt.setText('Current Level: ' + currentLevel); coinsInfoTxt.setText('Coins: ' + coins); progressTxt.setText('Progress: ' + currentLevel + '/500'); } } } // Function to update power-up inventory display function updatePowerUpDisplay() { bombTxt.setText('Bomb: ' + (storage.bombCount || 0)); lightbulbTxt.setText('Hint: ' + (storage.hintCount || 0)); clockTxt.setText('Clock: ' + (storage.clockCount || 0)); timerPowerTxt.setText('Timer: ' + (storage.timerCount || 0)); skipTxt.setText('Skip: ' + (storage.skipCount || 0)); } // Function to start the game function startGame() { showMenu = false; menuContainer.visible = false; // Show game UI elements movesTxt.visible = true; timerTxt.visible = true; coinsTxt.visible = true; levelTxt.visible = true; bombTxt.visible = true; lightbulbTxt.visible = true; clockTxt.visible = true; timerPowerTxt.visible = true; skipTxt.visible = true; playBackBtn.visible = true; // Update power-up display updatePowerUpDisplay(); // Initialize game initializeCards(); gameStartTime = Date.now(); startTime = Date.now(); } // 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(); }; // Saved Games button click handler savedGamesBtn.down = function (x, y, obj) { menuContainer.visible = false; savedGamesContainer.visible = true; // Update saved games display for (var i = 0; i < saveSlots.length; i++) { var slotData = savedGames[i]; var slotText = 'Slot ' + (i + 1); if (slotData) { slotText += ' - Level ' + slotData.level + ' (' + slotData.coins + ' coins)'; if (slotData.result) { slotText += ' - ' + slotData.result; } } else { slotText += ' - Empty'; } saveSlots[i].setText(slotText); saveSlots[i].tint = slotData ? 0x4ECDC4 : 0x666666; } }; // World screen container var worldContainer = new Container(); worldContainer.visible = false; // Add worldbackground as background var worldContainerBackground = LK.getAsset('worldbackground', { anchorX: 0.5, anchorY: 0.5, scaleX: 20, scaleY: 27 }); worldContainerBackground.x = 2048 / 2; worldContainerBackground.y = 2732 / 2; worldContainer.addChild(worldContainerBackground); game.addChild(worldContainer); var worldTitleTxt = new Text2('YOUR SPOOKY WORLD', { size: 120, fill: 0x4B0082, fontWeight: 'bold' }); worldTitleTxt.anchor.set(0.5, 0.5); worldTitleTxt.x = 2048 / 2; worldTitleTxt.y = 400; worldContainer.addChild(worldTitleTxt); var worldInstructionTxt = new Text2('Drag buildings to place them in your world', { size: 60, fill: 0x000000, fontWeight: 'bold' }); worldInstructionTxt.anchor.set(0.5, 0.5); worldInstructionTxt.x = 2048 / 2; worldInstructionTxt.y = 500; worldContainer.addChild(worldInstructionTxt); // World back button var worldBackBtn = new Text2('BACK TO MENU', { size: 80, fill: 0xCCCCCC, fontWeight: 'bold' }); worldBackBtn.anchor.set(0.5, 0.5); worldBackBtn.x = 2048 / 2; worldBackBtn.y = 2400; worldContainer.addChild(worldBackBtn); // Array to store placed buildings var placedBuildings = []; // World button click handler worldBtn.down = function (x, y, obj) { menuContainer.visible = false; worldContainer.visible = true; createWorldBuildings(); }; // World back button handler worldBackBtn.down = function (x, y, obj) { worldContainer.visible = false; menuContainer.visible = true; saveWorldState(); }; // Function to create world buildings based on purchased items function createWorldBuildings() { // Clear existing buildings for (var i = 0; i < placedBuildings.length; i++) { placedBuildings[i].destroy(); } placedBuildings = []; // Load saved positions from flattened storage structure var savedPositions = {}; for (var i = 0; i < placedBuildings.length; i++) { var building = placedBuildings[i]; var x = storage['buildingPos_' + building.buildingId + '_x']; var y = storage['buildingPos_' + building.buildingId + '_y']; if (x !== undefined && y !== undefined) { savedPositions[building.buildingId] = { x: x, y: y }; } } var buildingY = 700; var buildingX = 150; var buildingSpacing = 300; // Create buildings based on purchased counts var mansionCount = storage.mansionCount || 0; for (var i = 0; i < mansionCount; i++) { var mansion = createBuilding('Haunted Mansion', 0x4B0082, buildingX, buildingY, 'mansion_' + i); placedBuildings.push(mansion); worldContainer.addChild(mansion); buildingX += buildingSpacing; if (buildingX > 1800) { buildingX = 150; buildingY += 250; } } var hutCount = storage.hutCount || 0; for (var i = 0; i < hutCount; i++) { var hut = createBuilding('Witch Hut', 0x228B22, buildingX, buildingY, 'hut_' + i); placedBuildings.push(hut); worldContainer.addChild(hut); buildingX += buildingSpacing; if (buildingX > 1800) { buildingX = 150; buildingY += 250; } } var patchCount = storage.patchCount || 0; for (var i = 0; i < patchCount; i++) { var patch = createBuilding('Pumpkin Patch', 0xFF8C00, buildingX, buildingY, 'patch_' + i); placedBuildings.push(patch); worldContainer.addChild(patch); buildingX += buildingSpacing; if (buildingX > 1800) { buildingX = 150; buildingY += 250; } } var towerCount = storage.towerCount || 0; for (var i = 0; i < towerCount; i++) { var tower = createBuilding('Ghostly Tower', 0xF5F5F5, buildingX, buildingY, 'tower_' + i); placedBuildings.push(tower); worldContainer.addChild(tower); buildingX += buildingSpacing; if (buildingX > 1800) { buildingX = 150; buildingY += 250; } } var castleCount = storage.castleCount || 0; for (var i = 0; i < castleCount; i++) { var castle = createBuilding('Vampire Castle', 0x8B0000, buildingX, buildingY, 'castle_' + i); placedBuildings.push(castle); worldContainer.addChild(castle); buildingX += buildingSpacing; if (buildingX > 1800) { buildingX = 150; buildingY += 250; } } var ghostCount = storage.ghostCount || 0; for (var i = 0; i < ghostCount; i++) { var ghost = createBuilding('Friendly Ghost', 0xD3D3D3, buildingX, buildingY, 'ghost_' + i); placedBuildings.push(ghost); worldContainer.addChild(ghost); buildingX += buildingSpacing; if (buildingX > 1800) { buildingX = 150; buildingY += 250; } } var wizardCount = storage.wizardCount || 0; for (var i = 0; i < wizardCount; i++) { var wizard = createBuilding('Wizard', 0x191970, buildingX, buildingY, 'wizard_' + i); placedBuildings.push(wizard); worldContainer.addChild(wizard); buildingX += buildingSpacing; if (buildingX > 1800) { buildingX = 150; buildingY += 250; } } var catCount = storage.catCount || 0; for (var i = 0; i < catCount; i++) { var cat = createBuilding('Black Cat', 0x000000, buildingX, buildingY, 'cat_' + i); placedBuildings.push(cat); worldContainer.addChild(cat); buildingX += buildingSpacing; if (buildingX > 1800) { buildingX = 150; buildingY += 250; } } // Apply saved positions for (var i = 0; i < placedBuildings.length; i++) { var building = placedBuildings[i]; if (savedPositions[building.buildingId]) { building.x = savedPositions[building.buildingId].x; building.y = savedPositions[building.buildingId].y; } } } // Function to create a draggable building function createBuilding(name, color, x, y, buildingId) { var building = new Container(); building.buildingId = buildingId; // Create building visual - use appropriate asset based on building type var assetName = 'hauntedMansion'; // default fallback if (name === 'Haunted Mansion') assetName = 'hauntedMansion';else if (name === 'Witch Hut') assetName = 'witchHut';else if (name === 'Pumpkin Patch') assetName = 'pumpkinPatch';else if (name === 'Ghostly Tower') assetName = 'ghostlyTower';else if (name === 'Vampire Castle') assetName = 'vampireCastle';else if (name === 'Friendly Ghost') assetName = 'friendlyGhost';else if (name === 'Wizard') assetName = 'wizard';else if (name === 'Black Cat') assetName = 'blackCat'; var buildingShape = LK.getAsset(assetName, { anchorX: 0.5, anchorY: 0.5 }); building.addChild(buildingShape); // Create building label var buildingLabel = new Text2(name, { size: 30, fill: 0x000000, fontWeight: 'bold' }); buildingLabel.anchor.set(0.5, 0.5); buildingLabel.y = 100; building.addChild(buildingLabel); building.x = x; building.y = y; // Make building draggable building.isDragging = false; building.down = function (x, y, obj) { if (building && typeof building.x !== 'undefined' && typeof building.y !== 'undefined') { building.isDragging = true; // Convert coordinates to local space for proper offset calculation var localPos = worldContainer.toLocal({ x: x, y: y }); building.dragOffsetX = localPos.x - building.x; building.dragOffsetY = localPos.y - building.y; } }; building.up = function (x, y, obj) { building.isDragging = false; }; return building; } // Function to save world state function saveWorldState() { var positions = {}; for (var i = 0; i < placedBuildings.length; i++) { var building = placedBuildings[i]; positions[building.buildingId] = { x: building.x, y: building.y }; } // Store positions as individual key-value pairs to avoid object nesting issues for (var buildingId in positions) { storage['buildingPos_' + buildingId + '_x'] = positions[buildingId].x; storage['buildingPos_' + buildingId + '_y'] = positions[buildingId].y; } } // Handle building dragging var draggedBuilding = null; // World container mouse handlers worldContainer.move = function (x, y, obj) { for (var i = 0; i < placedBuildings.length; i++) { var building = placedBuildings[i]; if (building && building.isDragging) { // Convert coordinates to world container local space var localPos = worldContainer.toLocal({ x: x, y: y }); // Keep buildings within world bounds var newX = Math.max(100, Math.min(1948, localPos.x - (building.dragOffsetX || 0))); var newY = Math.max(600, Math.min(2300, localPos.y - (building.dragOffsetY || 0))); building.x = newX; building.y = newY; break; } } }; worldContainer.up = function (x, y, obj) { for (var i = 0; i < placedBuildings.length; i++) { var building = placedBuildings[i]; if (building.isDragging) { building.isDragging = false; break; } } }; // Saved Games back button click handler savedGamesBackBtn.down = function (x, y, obj) { savedGamesContainer.visible = false; menuContainer.visible = true; }; // Save game slot click handlers for (var i = 0; i < saveSlots.length; i++) { saveSlots[i].down = function (x, y, obj) { var slotIndex = obj.slotIndex; var gameData = savedGames[slotIndex]; if (gameData) { // Load existing save and go back to menu loadGame(slotIndex); savedGamesContainer.visible = false; menuContainer.visible = true; } else { // Save current game to empty slot saveGame(slotIndex); } }; } // Shop button click handler shopBtn.down = function (x, y, obj) { menuContainer.visible = false; shopContainer.visible = true; shopCoinsTxt.setText('Coins: ' + coins); }; // Tab switching handlers powerUpTabBtn.down = function (x, y, obj) { powerUpTabContainer.visible = true; buildingTabContainer.visible = false; powerUpTabBtn.fill = 0x4ECDC4; buildingTabBtn.fill = 0x666666; }; buildingTabBtn.down = function (x, y, obj) { powerUpTabContainer.visible = false; buildingTabContainer.visible = true; powerUpTabBtn.fill = 0x666666; buildingTabBtn.fill = 0x8B4513; }; // Building purchase handlers hauntedMansionBtn.down = function (x, y, obj) { buyHauntedMansion(); }; witchHutBtn.down = function (x, y, obj) { buyWitchHut(); }; pumpkinPatchBtn.down = function (x, y, obj) { buyPumpkinPatch(); }; ghostlyTowerBtn.down = function (x, y, obj) { buyGhostlyTower(); }; vampireCastleBtn.down = function (x, y, obj) { buyVampireCastle(); }; friendlyGhostBtn.down = function (x, y, obj) { buyFriendlyGhost(); }; wizardBtn.down = function (x, y, obj) { buyWizard(); }; blackCatBtn.down = function (x, y, obj) { buyBlackCat(); }; // Shop power-up purchase handlers shopBombBtn.down = function (x, y, obj) { buyBomb(); }; shopHintBtn.down = function (x, y, obj) { buyHint(); }; shopClockBtn.down = function (x, y, obj) { buyClock(); }; shopTimerBtn.down = function (x, y, obj) { buyTimer(); }; shopSkipBtn.down = function (x, y, obj) { buySkip(); }; // Back to menu button handler shopBackBtn.down = function (x, y, obj) { shopContainer.visible = false; menuContainer.visible = true; coinsInfoTxt.setText('Coins: ' + coins); }; // Create back button for play function var playBackBtn = new Text2('BACK TO MENU', { size: 60, fill: 0xCCCCCC, fontWeight: 'bold' }); playBackBtn.anchor.set(0.5, 0); LK.gui.topRight.addChild(playBackBtn); playBackBtn.x = -100; playBackBtn.y = 100; playBackBtn.visible = false; // Back button click handler for play function playBackBtn.down = function (x, y, obj) { // Return to menu showMenu = true; menuContainer.visible = true; // Hide game UI elements movesTxt.visible = false; timerTxt.visible = false; coinsTxt.visible = false; levelTxt.visible = false; bombTxt.visible = false; lightbulbTxt.visible = false; clockTxt.visible = false; timerPowerTxt.visible = false; skipTxt.visible = false; playBackBtn.visible = false; // Clear existing cards for (var i = 0; i < cards.length; i++) { cards[i].destroy(); } cards = []; flippedCards = []; // Reset game state variables moves = 0; gameCompleted = false; canFlipCards = true; gameOver = false; // Hide level complete text if visible levelCompleteTxt.visible = false; // Update menu display with current values levelInfoTxt.setText('Current Level: ' + currentLevel); coinsInfoTxt.setText('Coins: ' + coins); progressTxt.setText('Progress: ' + currentLevel + '/500'); }; // Play button click handler playBtn.down = function (x, y, obj) { // Always start from level 1 when play button is pressed currentLevel = 1; storage.currentLevel = currentLevel; // Reset coin count when play button is pressed coins = 0; storage.coins = coins; coinsTxt.setText('Coins: ' + coins); coinsInfoTxt.setText('Coins: ' + coins); levelTxt.setText('Level: ' + currentLevel); levelInfoTxt.setText('Current Level: ' + currentLevel); progressTxt.setText('Progress: ' + currentLevel + '/500'); // Reset game state variables for fresh start moves = 0; gameCompleted = false; canFlipCards = true; gameOver = false; flippedCards = []; // Clear existing cards if any for (var i = 0; i < cards.length; i++) { cards[i].destroy(); } cards = []; startGame(); }; // Hide game UI elements initially (show only in game) movesTxt.visible = false; timerTxt.visible = false; coinsTxt.visible = false; levelTxt.visible = false; bombTxt.visible = false; lightbulbTxt.visible = false; clockTxt.visible = false; timerPowerTxt.visible = false; skipTxt.visible = false; // Don't initialize cards immediately - wait for menu // initializeCards(); // This will be called when starting the game // Main game update loop game.update = function () { // Only update game logic if not in menu if (!showMenu) { // 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; // Auto-save failed attempt autoSaveGame('Failed - Time Limit'); LK.showGameOver(); } } } }; // Start background music LK.playMusic('bgmusic');
===================================================================
--- original.js
+++ change.js
@@ -590,10 +590,10 @@
}
var pairCount = totalTiles / 2;
var cardTypes = [];
for (var i = 1; i <= pairCount; i++) {
- var themeIndex = (i - 1) % 10; // Cycle through 10 Halloween themes
- var symbolIndex = themeIndex * 5 + (i - 1) % 5 + 1; // 5 symbols per theme
+ // Ensure symbol index stays within valid range (1-25)
+ var symbolIndex = (i - 1) % 25 + 1; // Cycle through 25 available symbols
cardTypes.push(symbolIndex);
cardTypes.push(symbolIndex); // Add pair
}
// Shuffle function
@@ -677,9 +677,9 @@
coinsTxt.setText('Coins: ' + coins);
// Check if game is complete
var matchedCount = 0;
for (var i = 0; i < cards.length; i++) {
- if (cards[i] && cards[i].isMatched) {
+ if (cards[i] && typeof cards[i].isMatched !== 'undefined' && cards[i].isMatched) {
matchedCount++;
}
}
if (matchedCount === cards.length) {
@@ -734,9 +734,11 @@
}, 2000);
}
// Clear existing cards
for (var i = 0; i < cards.length; i++) {
- cards[i].destroy();
+ if (cards[i] && typeof cards[i].destroy === 'function') {
+ cards[i].destroy();
+ }
}
cards = [];
flippedCards = [];
moves = 0;
@@ -757,10 +759,10 @@
}
var pairCount = totalTiles / 2;
cardTypes = [];
for (var i = 1; i <= pairCount; i++) {
- var themeIndex = (i - 1) % 10; // Cycle through 10 Halloween themes
- var symbolIndex = themeIndex * 5 + (i - 1) % 5 + 1; // 5 symbols per theme
+ // Ensure symbol index stays within valid range (1-25)
+ var symbolIndex = (i - 1) % 25 + 1; // Cycle through 25 available symbols
cardTypes.push(symbolIndex);
cardTypes.push(symbolIndex);
}
// Initialize new cards
@@ -936,19 +938,26 @@
bombTxt.setText('Bomb: ' + (storage.bombCount || 0));
// Delete 6 random non-matched cards
var availableCards = [];
for (var i = 0; i < cards.length; i++) {
- if (!cards[i].isMatched) {
+ if (cards[i] && typeof cards[i].isMatched !== 'undefined' && !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);
+ if (availableCards.length > 0) {
+ var randomIndex = Math.floor(Math.random() * availableCards.length);
+ var cardToRemove = availableCards[randomIndex];
+ if (cardToRemove && cardToRemove.destroy) {
+ cardToRemove.destroy();
+ var cardIndex = cards.indexOf(cardToRemove);
+ if (cardIndex !== -1) {
+ cards.splice(cardIndex, 1);
+ }
+ availableCards.splice(randomIndex, 1);
+ }
+ }
}
}
}
function useLightbulb() {
@@ -959,9 +968,9 @@
lightbulbTxt.setText('Hint: ' + (storage.hintCount || 0));
// Find a matching pair that's not matched yet
var unmatchedCards = [];
for (var i = 0; i < cards.length; i++) {
- if (!cards[i].isMatched) {
+ if (cards[i] && typeof cards[i].isMatched !== 'undefined' && !cards[i].isMatched) {
unmatchedCards.push(cards[i]);
}
}
// Group by symbol type
@@ -1403,11 +1412,18 @@
building.y = y;
// Make building draggable
building.isDragging = false;
building.down = function (x, y, obj) {
- building.isDragging = true;
- building.dragOffsetX = x - building.x;
- building.dragOffsetY = y - building.y;
+ if (building && typeof building.x !== 'undefined' && typeof building.y !== 'undefined') {
+ building.isDragging = true;
+ // Convert coordinates to local space for proper offset calculation
+ var localPos = worldContainer.toLocal({
+ x: x,
+ y: y
+ });
+ building.dragOffsetX = localPos.x - building.x;
+ building.dragOffsetY = localPos.y - building.y;
+ }
};
building.up = function (x, y, obj) {
building.isDragging = false;
};
@@ -1434,12 +1450,17 @@
// World container mouse handlers
worldContainer.move = function (x, y, obj) {
for (var i = 0; i < placedBuildings.length; i++) {
var building = placedBuildings[i];
- if (building.isDragging) {
+ if (building && building.isDragging) {
+ // Convert coordinates to world container local space
+ var localPos = worldContainer.toLocal({
+ x: x,
+ y: y
+ });
// Keep buildings within world bounds
- var newX = Math.max(100, Math.min(1948, x - building.dragOffsetX));
- var newY = Math.max(600, Math.min(2300, y - building.dragOffsetY));
+ var newX = Math.max(100, Math.min(1948, localPos.x - (building.dragOffsetX || 0)));
+ var newY = Math.max(600, Math.min(2300, localPos.y - (building.dragOffsetY || 0)));
building.x = newX;
building.y = newY;
break;
}