User prompt
First level has 4 tiles.
User prompt
Each level has 2 minute timer, 15 move limit, and +6 tiles.
User prompt
Matching titles earns five coins. ↪💡 Consider importing and using the following plugins: @upit/storage.v1
Code edit (1 edits merged)
Please save this source code
User prompt
Memory Match
Initial prompt
# Initialize Pygame pygame.init() # Set up display WIDTH, HEIGHT = 600, 600 screen = pygame.display.set_mode((WIDTH, HEIGHT)) pygame.display.set_caption("Memory Matching Game") font = pygame.font.Font(None, 74) # Colors WHITE = (255, 255, 255) BLACK = (0, 0, 0) GREEN = (0, 255, 0) RED = (255, 0, 0)
/**** * 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; }); /**** * 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 = 1; var gameStartTime = Date.now(); var LEVEL_TIME_LIMIT = 120; // 2 minutes in seconds var MOVE_LIMIT = 15; var gameOver = 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; // Create card types array based on level (8 pairs + 6 tiles per level) var totalTiles = 16 + (currentLevel - 1) * 6; // 16 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; 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; currentLevel++; 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 = 16 + (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; } // Initialize the game initializeCards(); // Main game update loop game.update = function () { // 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; LK.showGameOver(); } } };
===================================================================
--- original.js
+++ change.js
@@ -96,8 +96,13 @@
var moves = 0;
var startTime = Date.now();
var gameCompleted = false;
var canFlipCards = true;
+var currentLevel = 1;
+var gameStartTime = Date.now();
+var LEVEL_TIME_LIMIT = 120; // 2 minutes in seconds
+var MOVE_LIMIT = 15;
+var gameOver = false;
// Grid configuration
var GRID_COLS = 4;
var GRID_ROWS = 4;
var CARD_SIZE = 200;
@@ -125,13 +130,23 @@
});
coinsTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(coinsTxt);
coinsTxt.y = 260;
-// Create card types array (8 pairs)
+var levelTxt = new Text2('Level: ' + currentLevel, {
+ size: 60,
+ fill: 0xFFFFFF
+});
+levelTxt.anchor.set(0.5, 0);
+LK.gui.top.addChild(levelTxt);
+levelTxt.y = 340;
+// Create card types array based on level (8 pairs + 6 tiles per level)
+var totalTiles = 16 + (currentLevel - 1) * 6; // 16 base tiles + 6 per level
+var pairCount = totalTiles / 2;
var cardTypes = [];
-for (var i = 1; i <= 8; i++) {
- cardTypes.push(i);
- cardTypes.push(i); // Add pair
+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--) {
@@ -144,32 +159,48 @@
}
// 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 row = 0; row < GRID_ROWS; row++) {
- for (var col = 0; col < GRID_COLS; col++) {
- var index = row * GRID_COLS + col;
- var card = new Card(shuffledTypes[index]);
- card.x = startX + col * (CARD_SIZE + CARD_SPACING);
- card.y = startY + row * (CARD_SIZE + CARD_SPACING);
- cards.push(card);
- game.addChild(card);
- }
+ 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) return;
+ 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;
+ LK.setTimeout(function () {
+ LK.showGameOver();
+ }, 1000);
+ return;
+ }
canFlipCards = false;
// Check for match after a short delay
LK.setTimeout(function () {
checkForMatch();
@@ -197,11 +228,14 @@
}
}
if (matchedCount === cards.length) {
gameCompleted = true;
+ currentLevel++;
+ levelTxt.setText('Level: ' + currentLevel);
+ // Reset for next level
LK.setTimeout(function () {
- LK.showYouWin();
- }, 500);
+ resetLevel();
+ }, 1000);
}
} else {
// No match
LK.getSound('noMatch').play();
@@ -210,8 +244,37 @@
}
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 = 16 + (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;
@@ -221,9 +284,15 @@
initializeCards();
// Main game update loop
game.update = function () {
// Update timer
- if (!gameCompleted) {
- var elapsedTime = Math.floor((Date.now() - startTime) / 1000);
- timerTxt.setText('Time: ' + formatTime(elapsedTime));
+ 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;
+ LK.showGameOver();
+ }
}
};
\ No newline at end of file