/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var storage = LK.import("@upit/storage.v1"); /**** * Classes ****/ var Card = Container.expand(function (cardId, cardValue) { var self = Container.call(this); self.cardId = cardId; self.cardValue = cardValue; self.isFlipped = false; self.isMatched = false; // Create outline for the card var outline = self.attachAsset('cardOutline', { anchorX: 0.5, anchorY: 0.5 }); // Create back of the card var cardBack = self.attachAsset('cardBack', { anchorX: 0.5, anchorY: 0.5 }); // Create front of the card var cardFront = self.attachAsset('card' + cardValue, { anchorX: 0.5, anchorY: 0.5 }); cardFront.visible = false; // No text needed since we're using photos self.flip = function () { if (self.isMatched || self.isFlipped) { return false; } LK.getSound('flip').play(); self.isFlipped = true; // Animate the flip tween(cardBack, { scaleX: 0 }, { duration: 150, easing: tween.easeIn, onFinish: function onFinish() { cardBack.visible = false; cardFront.visible = true; cardFront.scaleX = 0; tween(cardFront, { scaleX: 1 }, { duration: 150, easing: tween.easeOut }); } }); return true; }; self.flipBack = function () { if (self.isMatched) { return; } self.isFlipped = false; // Animate the flip back tween(cardFront, { scaleX: 0 }, { duration: 150, easing: tween.easeIn, onFinish: function onFinish() { cardFront.visible = false; cardBack.visible = true; cardBack.scaleX = 0; tween(cardBack, { scaleX: 1 }, { duration: 150, easing: tween.easeOut }); } }); }; self.setMatched = function () { self.isMatched = true; // Animate the match tween(self, { alpha: 0.8 }, { duration: 300, easing: tween.easeOut }); }; self.down = function (x, y, obj) { if (!gameActive || flipInProgress) { return; } // All cards can be flipped in this version var flipped = self.flip(); if (flipped) { onCardFlip(self); } }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x000000 }); /**** * Game Code ****/ // Game configuration var GRID_COLS = 6; var GRID_ROWS = 6; var CARD_COUNT = GRID_COLS * GRID_ROWS; var CARD_WIDTH = 300; // Reduced to fit 6x6 var CARD_HEIGHT = 300; // Reduced to fit 6x6 var CARD_MARGIN = 10; // Slightly reduced margin var GRID_WIDTH = GRID_COLS * (CARD_WIDTH + CARD_MARGIN) - CARD_MARGIN; var GRID_HEIGHT = GRID_ROWS * (CARD_HEIGHT + CARD_MARGIN) - CARD_MARGIN; // Game state variables var cards = []; var firstCard = null; var secondCard = null; var matchedPairs = 0; var moves = 0; var gameActive = false; var flipInProgress = false; var timeRemaining = 150; // 2 minutes and 30 seconds var timerInterval = null; // UI Elements // No moves text needed var timerText = new Text2("Time: 150s", { size: 80, fill: 0xFFFFFF }); timerText.anchor.set(0, 0); LK.gui.topLeft.addChild(timerText); timerText.x = 50; timerText.y = 50; // No status text needed // Initialize the game function initGame() { // Set background color to soft dusty pink game.setBackgroundColor(0xF8BBD0); // Clear any existing cards if (cards.length > 0) { for (var i = 0; i < cards.length; i++) { if (cards[i]) { cards[i].destroy(); } } cards = []; } // Reset game state firstCard = null; secondCard = null; matchedPairs = 0; moves = 0; gameActive = false; flipInProgress = false; // Reset UI if (timerText) { timerText.setText("Time: 0s"); } // Create card values - using unique images for each card var cardValues = []; // Use unique values for each pair for (var i = 1; i <= 18; i++) { // Add each value twice to create pairs cardValues.push(i); cardValues.push(i); } // Shuffle the card values shuffleArray(cardValues); // Create the cards for (var i = 0; i < CARD_COUNT; i++) { var card = new Card(i, cardValues[i]); cards.push(card); game.addChild(card); // Position the card in the grid var row = Math.floor(i / GRID_COLS); var col = i % GRID_COLS; card.x = (2048 - GRID_WIDTH) / 2 + col * (CARD_WIDTH + CARD_MARGIN) + CARD_WIDTH / 2; card.y = (2732 - GRID_HEIGHT) / 2 + row * (CARD_HEIGHT + CARD_MARGIN) + CARD_HEIGHT / 2; } // Start game after a short delay LK.setTimeout(function () { startGame(); }, 500); } function startGame() { gameActive = true; // Reset timer timeRemaining = 150; // 2 minutes and 30 seconds timerText.setText("Time: " + timeRemaining + "s"); // No odd card in this version // Start timer timerInterval = LK.setInterval(function () { timeRemaining--; timerText.setText("Time: " + timeRemaining + "s"); if (timeRemaining <= 0) { LK.clearInterval(timerInterval); gameActive = false; statusText.setText("Time's up!"); // Show game over after a delay LK.setTimeout(function () { LK.showGameOver(); }, 1000); } }, 1000); // Play background music LK.playMusic('backgroundMusic'); } function onCardFlip(card) { if (!firstCard) { firstCard = card; } else if (!secondCard && firstCard.cardId !== card.cardId) { secondCard = card; moves++; flipInProgress = true; // Check for a match after a short delay LK.setTimeout(function () { checkForMatch(); flipInProgress = false; }, 500); } } function checkForMatch() { if (firstCard.cardValue === secondCard.cardValue) { // It's a match! LK.getSound('match').play(); firstCard.setMatched(); secondCard.setMatched(); matchedPairs++; // No status update needed // Check for game completion // We need to find CARD_COUNT/2 pairs (all cards are in pairs) if (matchedPairs === CARD_COUNT / 2) { gameComplete(); } } else { // Not a match LK.getSound('noMatch').play(); firstCard.flipBack(); secondCard.flipBack(); // No status update needed } // Reset selection firstCard = null; secondCard = null; } function gameComplete() { gameActive = false; // Clear the timer LK.clearInterval(timerInterval); // Play victory sound LK.getSound('victory').play(); // No status update needed // Save high score if better than previous var bestMoves = storage.bestMoves || 999; if (moves < bestMoves) { storage.bestMoves = moves; } // Update score for leaderboard var score = Math.floor(10000 / moves); LK.setScore(score); // Show game completion after a delay LK.setTimeout(function () { LK.showYouWin(); }, 2000); } // Utility function to shuffle an array 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 the game on first load initGame(); // Handle game updates game.update = function () { // Nothing needed here for this game type };
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/****
* Classes
****/
var Card = Container.expand(function (cardId, cardValue) {
var self = Container.call(this);
self.cardId = cardId;
self.cardValue = cardValue;
self.isFlipped = false;
self.isMatched = false;
// Create outline for the card
var outline = self.attachAsset('cardOutline', {
anchorX: 0.5,
anchorY: 0.5
});
// Create back of the card
var cardBack = self.attachAsset('cardBack', {
anchorX: 0.5,
anchorY: 0.5
});
// Create front of the card
var cardFront = self.attachAsset('card' + cardValue, {
anchorX: 0.5,
anchorY: 0.5
});
cardFront.visible = false;
// No text needed since we're using photos
self.flip = function () {
if (self.isMatched || self.isFlipped) {
return false;
}
LK.getSound('flip').play();
self.isFlipped = true;
// Animate the flip
tween(cardBack, {
scaleX: 0
}, {
duration: 150,
easing: tween.easeIn,
onFinish: function onFinish() {
cardBack.visible = false;
cardFront.visible = true;
cardFront.scaleX = 0;
tween(cardFront, {
scaleX: 1
}, {
duration: 150,
easing: tween.easeOut
});
}
});
return true;
};
self.flipBack = function () {
if (self.isMatched) {
return;
}
self.isFlipped = false;
// Animate the flip back
tween(cardFront, {
scaleX: 0
}, {
duration: 150,
easing: tween.easeIn,
onFinish: function onFinish() {
cardFront.visible = false;
cardBack.visible = true;
cardBack.scaleX = 0;
tween(cardBack, {
scaleX: 1
}, {
duration: 150,
easing: tween.easeOut
});
}
});
};
self.setMatched = function () {
self.isMatched = true;
// Animate the match
tween(self, {
alpha: 0.8
}, {
duration: 300,
easing: tween.easeOut
});
};
self.down = function (x, y, obj) {
if (!gameActive || flipInProgress) {
return;
}
// All cards can be flipped in this version
var flipped = self.flip();
if (flipped) {
onCardFlip(self);
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x000000
});
/****
* Game Code
****/
// Game configuration
var GRID_COLS = 6;
var GRID_ROWS = 6;
var CARD_COUNT = GRID_COLS * GRID_ROWS;
var CARD_WIDTH = 300; // Reduced to fit 6x6
var CARD_HEIGHT = 300; // Reduced to fit 6x6
var CARD_MARGIN = 10; // Slightly reduced margin
var GRID_WIDTH = GRID_COLS * (CARD_WIDTH + CARD_MARGIN) - CARD_MARGIN;
var GRID_HEIGHT = GRID_ROWS * (CARD_HEIGHT + CARD_MARGIN) - CARD_MARGIN;
// Game state variables
var cards = [];
var firstCard = null;
var secondCard = null;
var matchedPairs = 0;
var moves = 0;
var gameActive = false;
var flipInProgress = false;
var timeRemaining = 150; // 2 minutes and 30 seconds
var timerInterval = null;
// UI Elements
// No moves text needed
var timerText = new Text2("Time: 150s", {
size: 80,
fill: 0xFFFFFF
});
timerText.anchor.set(0, 0);
LK.gui.topLeft.addChild(timerText);
timerText.x = 50;
timerText.y = 50;
// No status text needed
// Initialize the game
function initGame() {
// Set background color to soft dusty pink
game.setBackgroundColor(0xF8BBD0);
// Clear any existing cards
if (cards.length > 0) {
for (var i = 0; i < cards.length; i++) {
if (cards[i]) {
cards[i].destroy();
}
}
cards = [];
}
// Reset game state
firstCard = null;
secondCard = null;
matchedPairs = 0;
moves = 0;
gameActive = false;
flipInProgress = false;
// Reset UI
if (timerText) {
timerText.setText("Time: 0s");
}
// Create card values - using unique images for each card
var cardValues = [];
// Use unique values for each pair
for (var i = 1; i <= 18; i++) {
// Add each value twice to create pairs
cardValues.push(i);
cardValues.push(i);
}
// Shuffle the card values
shuffleArray(cardValues);
// Create the cards
for (var i = 0; i < CARD_COUNT; i++) {
var card = new Card(i, cardValues[i]);
cards.push(card);
game.addChild(card);
// Position the card in the grid
var row = Math.floor(i / GRID_COLS);
var col = i % GRID_COLS;
card.x = (2048 - GRID_WIDTH) / 2 + col * (CARD_WIDTH + CARD_MARGIN) + CARD_WIDTH / 2;
card.y = (2732 - GRID_HEIGHT) / 2 + row * (CARD_HEIGHT + CARD_MARGIN) + CARD_HEIGHT / 2;
}
// Start game after a short delay
LK.setTimeout(function () {
startGame();
}, 500);
}
function startGame() {
gameActive = true;
// Reset timer
timeRemaining = 150; // 2 minutes and 30 seconds
timerText.setText("Time: " + timeRemaining + "s");
// No odd card in this version
// Start timer
timerInterval = LK.setInterval(function () {
timeRemaining--;
timerText.setText("Time: " + timeRemaining + "s");
if (timeRemaining <= 0) {
LK.clearInterval(timerInterval);
gameActive = false;
statusText.setText("Time's up!");
// Show game over after a delay
LK.setTimeout(function () {
LK.showGameOver();
}, 1000);
}
}, 1000);
// Play background music
LK.playMusic('backgroundMusic');
}
function onCardFlip(card) {
if (!firstCard) {
firstCard = card;
} else if (!secondCard && firstCard.cardId !== card.cardId) {
secondCard = card;
moves++;
flipInProgress = true;
// Check for a match after a short delay
LK.setTimeout(function () {
checkForMatch();
flipInProgress = false;
}, 500);
}
}
function checkForMatch() {
if (firstCard.cardValue === secondCard.cardValue) {
// It's a match!
LK.getSound('match').play();
firstCard.setMatched();
secondCard.setMatched();
matchedPairs++;
// No status update needed
// Check for game completion
// We need to find CARD_COUNT/2 pairs (all cards are in pairs)
if (matchedPairs === CARD_COUNT / 2) {
gameComplete();
}
} else {
// Not a match
LK.getSound('noMatch').play();
firstCard.flipBack();
secondCard.flipBack();
// No status update needed
}
// Reset selection
firstCard = null;
secondCard = null;
}
function gameComplete() {
gameActive = false;
// Clear the timer
LK.clearInterval(timerInterval);
// Play victory sound
LK.getSound('victory').play();
// No status update needed
// Save high score if better than previous
var bestMoves = storage.bestMoves || 999;
if (moves < bestMoves) {
storage.bestMoves = moves;
}
// Update score for leaderboard
var score = Math.floor(10000 / moves);
LK.setScore(score);
// Show game completion after a delay
LK.setTimeout(function () {
LK.showYouWin();
}, 2000);
}
// Utility function to shuffle an array
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 the game on first load
initGame();
// Handle game updates
game.update = function () {
// Nothing needed here for this game type
};