User prompt
Increase max level number to 50
User prompt
Use “cardback3” asset for cards after level10
User prompt
Add rveal button near to dev button. This button reveals all cards at the level
User prompt
Use “cardback2” asset for card after level5
User prompt
Remove moves gui
Code edit (13 edits merged)
Please save this source code
User prompt
Please fix the bug: 'Timeout.tick error: null is not an object (evaluating 'firstCard.symbol')' in or related to this line: 'if (firstCard.symbol === secondCard.symbol) {' Line Number: 342
Code edit (1 edits merged)
Please save this source code
Code edit (1 edits merged)
Please save this source code
User prompt
Add DEV button to the game. This button must be at center bottom and always visible. This button take you to next level immediately
User prompt
Next button always appear at bottom
User prompt
Add next button to the game. This button take you to next level
User prompt
After matching cards, matching cards must disappear
User prompt
Please fix the bug: 'TypeError: Cannot use 'in' operator to search for 'scaleX' in null' in or related to this line: 'tween(firstCard, {' Line Number: 356
User prompt
Please fix the bug: 'TypeError: Cannot use 'in' operator to search for 'scaleX' in null' in or related to this line: 'tween(firstCard, {' Line Number: 355
User prompt
Align level indicator to top middle
User prompt
There must be level system for the game. If you match all cards you will go next level. Maximum level number must be 25.
Code edit (1 edits merged)
Please save this source code
User prompt
Card Match Mania
Initial prompt
I want card match game
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ // Card class: represents a single card in the memory game var Card = Container.expand(function () { var self = Container.call(this); // Card properties self.symbol = null; // Symbol or id for matching self.isFaceUp = false; self.isMatched = false; self.index = -1; // Position in the grid // Card dimensions (will be set in game code) self.cardWidth = 0; self.cardHeight = 0; // Face-down asset (back of card) var backAssetId = typeof currentLevel !== "undefined" && currentLevel > 5 ? 'CardBack2' : 'cardBack'; var back = self.attachAsset(backAssetId, { anchorX: 0.5, anchorY: 0.5 }); // Face-up asset (front of card, shows symbol) var front = self.attachAsset('cardFront', { anchorX: 0.5, anchorY: 0.5 }); // Symbol text (shows symbol when face up) var symbolText = new Text2('', { size: 90, fill: 0x222222 }); symbolText.anchor.set(0.5, 0.5); front.addChild(symbolText); // Set card size self.setSize = function (w, h) { self.cardWidth = w; self.cardHeight = h; back.width = w; back.height = h; front.width = w; front.height = h; }; // Set the symbol for this card self.setSymbol = function (symbol) { self.symbol = symbol; symbolText.setText(symbol); }; // Flip the card to face up (with animation) self.flipUp = function (_onFinish) { if (self.isFaceUp || self.isMatched) { return; } self.isFaceUp = true; // Animate flip: scaleX 1 -> 0, swap, 0 -> 1 tween(self, { scaleX: 0 }, { duration: 120, easing: tween.cubicIn, onFinish: function onFinish() { back.visible = false; front.visible = true; tween(self, { scaleX: 1 }, { duration: 120, easing: tween.cubicOut, onFinish: function onFinish() { if (_onFinish) { _onFinish(); } } }); } }); }; // Flip the card to face down (with animation) self.flipDown = function (_onFinish2) { if (!self.isFaceUp || self.isMatched) { return; } self.isFaceUp = false; // Animate flip: scaleX 1 -> 0, swap, 0 -> 1 tween(self, { scaleX: 0 }, { duration: 120, easing: tween.cubicIn, onFinish: function onFinish() { front.visible = false; back.visible = true; tween(self, { scaleX: 1 }, { duration: 120, easing: tween.cubicOut, onFinish: function onFinish() { if (_onFinish2) { _onFinish2(); } } }); } }); }; // Instantly show face up (no animation) self.showFaceUp = function () { self.isFaceUp = true; self.scaleX = 1; back.visible = false; front.visible = true; }; // Instantly show face down (no animation) self.showFaceDown = function () { self.isFaceUp = false; self.scaleX = 1; front.visible = false; back.visible = true; }; // Mark as matched (disable interaction, highlight) self.setMatched = function () { self.isMatched = true; // Subtle highlight tween(self, { tint: 0xA0FFA0 }, { duration: 300, easing: tween.linear }); }; // Handle tap/click self.down = function (x, y, obj) { if (self.isFaceUp || self.isMatched || game.lockInput) { return; } game.onCardTapped(self); }; // Initialize: show face down self.showFaceDown(); return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x2e3a4f // Deep blue background }); /**** * Game Code ****/ // Tween plugin for card flip and reveal animations // --- Card symbols (use simple emojis for MVP) --- var cardSymbols = ["🍎", "🍌", "🍇", "🍉", "🍒", "🍋", "🍓", "🍍", "🥝", "🥑", "🍊", "🍐", "🍈", "🍑", "🥥", "🍅"]; // --- Game settings --- var maxLevel = 25; var currentLevel = 1; // Level configuration: grid size per level (increase difficulty) function getLevelConfig(level) { // Level 1-5: 4x4, 6-10: 5x4, 11-15: 6x5, 16-20: 6x6, 21-25: 7x6 if (level <= 5) { return { cols: 4, rows: 4 }; } if (level <= 10) { return { cols: 5, rows: 4 }; } if (level <= 15) { return { cols: 6, rows: 5 }; } if (level <= 20) { return { cols: 6, rows: 6 }; } return { cols: 7, rows: 6 }; } var gridCols = getLevelConfig(currentLevel).cols; var gridRows = getLevelConfig(currentLevel).rows; var totalPairs = gridCols * gridRows / 2; var cardSpacing = 36; // px between cards // --- Card assets (simple colored rectangles) --- // --- Game state --- var cards = []; // All card objects var firstCard = null; var secondCard = null; var lockInput = false; // Prevent input during animations var moves = 0; var matchesFound = 0; var timer = null; var elapsedTime = 0; // in seconds var timerText = null; var movesText = null; // --- GUI: Moves, Timer, Level --- var levelText = new Text2('Level: 1', { size: 80, fill: 0xFFFFFF }); levelText.anchor.set(0.5, 0); LK.gui.top.addChild(levelText); timerText = new Text2('Time: 0s', { size: 80, fill: 0xFFFFFF }); timerText.anchor.set(0.5, 0); LK.gui.top.addChild(timerText); // Position GUI elements (timer right, avoid top-left 100x100) // Align level indicator to top middle using LK.gui.top levelText.x = -10; levelText.y = 20; timerText.x = 500; timerText.y = 20; // --- Helper: Shuffle array (Fisher-Yates) --- function shuffleArray(arr) { for (var i = arr.length - 1; i > 0; i--) { var j = Math.floor(Math.random() * (i + 1)); var temp = arr[i]; arr[i] = arr[j]; arr[j] = temp; } } // --- Layout cards --- function layoutCards() { // Remove old cards if any for (var i = 0; i < cards.length; i++) { cards[i].destroy(); } cards = []; // Prepare symbols (duplicate and shuffle) var symbols = []; for (var i = 0; i < totalPairs; i++) { symbols.push(cardSymbols[i]); symbols.push(cardSymbols[i]); } shuffleArray(symbols); // Card size: fit grid to 2048x2732 with spacing var availableWidth = 2048 - cardSpacing * (gridCols + 1); var availableHeight = 1800 - cardSpacing * (gridRows + 1); // leave space for GUI var cardWidth = Math.floor(availableWidth / gridCols); var cardHeight = Math.floor(availableHeight / gridRows); // Center grid var gridPixelWidth = cardWidth * gridCols + cardSpacing * (gridCols - 1); var gridPixelHeight = cardHeight * gridRows + cardSpacing * (gridRows - 1); var startX = Math.floor((2048 - gridPixelWidth) / 2) + cardWidth / 2; var startY = 350 + cardHeight / 2; // leave space for GUI // Create cards for (var row = 0; row < gridRows; row++) { for (var col = 0; col < gridCols; col++) { var idx = row * gridCols + col; var card = new Card(); card.setSize(cardWidth, cardHeight); card.setSymbol(symbols[idx]); card.index = idx; card.x = startX + col * (cardWidth + cardSpacing); card.y = startY + row * (cardHeight + cardSpacing); card.showFaceDown(); game.addChild(card); cards.push(card); } } } // --- Reset game state --- function resetGame() { firstCard = null; secondCard = null; lockInput = false; moves = 0; matchesFound = 0; elapsedTime = 0; if (typeof levelText !== "undefined") { levelText.setText('Level: ' + currentLevel); } // Update grid size for this level var config = getLevelConfig(currentLevel); gridCols = config.cols; gridRows = config.rows; totalPairs = gridCols * gridRows / 2; timerText.setText('Time: 0s'); layoutCards(); if (timer) { LK.clearInterval(timer); } timer = LK.setInterval(function () { elapsedTime++; timerText.setText('Time: ' + elapsedTime + 's'); }, 1000); } // --- Card tap handler --- game.onCardTapped = function (card) { if (lockInput || card.isFaceUp || card.isMatched) { return; } if (!firstCard) { firstCard = card; card.flipUp(); } else if (!secondCard && card !== firstCard) { secondCard = card; lockInput = true; card.flipUp(function () { // Check for match after both are face up LK.setTimeout(function () { checkMatch(); }, 350); }); } }; // --- Check for match --- function checkMatch() { moves++; if (firstCard && secondCard && firstCard.symbol === secondCard.symbol) { // Match! firstCard.setMatched(); secondCard.setMatched(); matchesFound++; // Subtle scale animation for matched cards, then disappear if (firstCard && secondCard) { var matched1 = firstCard; var matched2 = secondCard; if (matched1) { tween(matched1, { scaleX: 1.15, scaleY: 1.15 }, { duration: 120, easing: tween.cubicOut, onFinish: function onFinish() { if (matched1) { tween(matched1, { scaleX: 0, scaleY: 0, alpha: 0 }, { duration: 180, onFinish: function onFinish() { if (matched1) { matched1.destroy(); } } }); } } }); } if (matched2) { tween(matched2, { scaleX: 1.15, scaleY: 1.15 }, { duration: 120, easing: tween.cubicOut, onFinish: function onFinish() { if (matched2) { tween(matched2, { scaleX: 0, scaleY: 0, alpha: 0 }, { duration: 180, onFinish: function onFinish() { if (matched2) { matched2.destroy(); } } }); } } }); } } // Check for win if (matchesFound === totalPairs) { LK.clearInterval(timer); LK.setScore(moves); // Use moves as score (lower is better) if (currentLevel < maxLevel) { currentLevel++; // Short delay before next level LK.setTimeout(function () { resetGame(); }, 1200); } else { LK.showYouWin(); } } // Reset selection firstCard = null; secondCard = null; lockInput = false; } else { // Not a match: flip both back after short delay LK.setTimeout(function () { firstCard.flipDown(); secondCard.flipDown(function () { firstCard = null; secondCard = null; lockInput = false; }); }, 600); } } // --- Game update (not used for logic, but required) --- game.update = function () { // No per-frame logic needed for MVP }; // --- DEV Button: Center bottom, always visible, go to next level --- var devBtn = new Text2('DEV', { size: 90, fill: 0xFF00FF, font: "Impact" }); devBtn.anchor.set(0.5, 1); // Place DEV button slightly left of center devBtn.x = -120; devBtn.y = -50; LK.gui.bottom.addChild(devBtn); // DEV button handler: go to next level immediately (max 25) devBtn.down = function (x, y, obj) { if (currentLevel < maxLevel) { currentLevel++; resetGame(); } else { LK.showYouWin(); } }; // --- Reveal Button: Center bottom, always visible, reveals all cards --- var revealBtn = new Text2('Reveal', { size: 90, fill: 0x00CCFF, font: "Impact" }); revealBtn.anchor.set(0.5, 1); // Place Reveal button slightly right of center revealBtn.x = 120; revealBtn.y = -50; LK.gui.bottom.addChild(revealBtn); // Reveal button handler: flip all cards face up (if not matched) revealBtn.down = function (x, y, obj) { for (var i = 0; i < cards.length; i++) { var card = cards[i]; if (!card.isFaceUp && !card.isMatched) { card.flipUp(); } } }; // --- Start game --- resetGame(); // --- Game over handler (reset on game over) --- game.onGameOver = function () { if (timer) { LK.clearInterval(timer); } currentLevel = 1; resetGame(); }; // --- Win handler (reset on win) --- game.onYouWin = function () { if (timer) { LK.clearInterval(timer); } currentLevel = 1; // Game will reset automatically by LK };
===================================================================
--- original.js
+++ change.js
@@ -424,9 +424,10 @@
fill: 0xFF00FF,
font: "Impact"
});
devBtn.anchor.set(0.5, 1);
-devBtn.x = 10;
+// Place DEV button slightly left of center
+devBtn.x = -120;
devBtn.y = -50;
LK.gui.bottom.addChild(devBtn);
// DEV button handler: go to next level immediately (max 25)
devBtn.down = function (x, y, obj) {
@@ -436,8 +437,28 @@
} else {
LK.showYouWin();
}
};
+// --- Reveal Button: Center bottom, always visible, reveals all cards ---
+var revealBtn = new Text2('Reveal', {
+ size: 90,
+ fill: 0x00CCFF,
+ font: "Impact"
+});
+revealBtn.anchor.set(0.5, 1);
+// Place Reveal button slightly right of center
+revealBtn.x = 120;
+revealBtn.y = -50;
+LK.gui.bottom.addChild(revealBtn);
+// Reveal button handler: flip all cards face up (if not matched)
+revealBtn.down = function (x, y, obj) {
+ for (var i = 0; i < cards.length; i++) {
+ var card = cards[i];
+ if (!card.isFaceUp && !card.isMatched) {
+ card.flipUp();
+ }
+ }
+};
// --- Start game ---
resetGame();
// --- Game over handler (reset on game over) ---
game.onGameOver = function () {