/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ var Card = Container.expand(function (labubuColor) { var self = Container.call(this); self.labubuColor = labubuColor; self.isFlipped = false; self.isMatched = false; self.isFlipping = false; // Create card back outline self.cardBackOutline = self.attachAsset('cardBackOutline', { anchorX: 0.5, anchorY: 0.5 }); // Create card back self.cardBack = self.attachAsset('cardBack', { anchorX: 0.5, anchorY: 0.5 }); // Create card front self.cardFront = self.attachAsset('cardFront', { anchorX: 0.5, anchorY: 0.5, scaleX: 0, alpha: 0 }); // Create Labubu character self.labubu = self.cardFront.addChild(LK.getAsset(labubuColor, { anchorX: 0.5, anchorY: 0.5 })); self.flip = function (callback) { if (self.isFlipping || self.isMatched) return; self.isFlipping = true; LK.getSound('cardFlip').play(); if (!self.isFlipped) { // Flip to front tween(self.cardBack, { scaleX: 0 }, { duration: 150, onFinish: function onFinish() { self.cardBack.alpha = 0; self.cardBackOutline.alpha = 0; self.cardFront.alpha = 1; tween(self.cardFront, { scaleX: 1 }, { duration: 150, onFinish: function onFinish() { self.isFlipped = true; self.isFlipping = false; if (callback) callback(); } }); } }); } else { // Flip to back tween(self.cardFront, { scaleX: 0 }, { duration: 150, onFinish: function onFinish() { self.cardFront.alpha = 0; self.cardBack.alpha = 1; self.cardBackOutline.alpha = 1; tween(self.cardBack, { scaleX: 1 }, { duration: 150, onFinish: function onFinish() { self.isFlipped = false; self.isFlipping = false; if (callback) callback(); } }); } }); } }; self.setMatched = function () { self.isMatched = true; LK.getSound('match').play(); tween(self, { alpha: 0, scaleX: 0.8, scaleY: 0.8 }, { duration: 300, easing: tween.easeOut }); }; self.down = function (x, y, obj) { if (!self.isFlipping && !self.isMatched && !gameWon) { handleCardClick(self); } }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x2C3E50 }); /**** * Game Code ****/ var currentLevel = 1; var maxLevel = 10; var cards = []; var flippedCards = []; var isCheckingMatch = false; var gameWon = false; var labubuColors = ['labubuRed', 'labubuBlue', 'labubuGreen', 'labubuYellow', 'labubuPurple', 'labubuOrange', 'labubuPink', 'labubuCyan']; // UI Elements var levelText = new Text2('Level 1', { size: 80, fill: 0xFFFFFF }); levelText.anchor.set(0.5, 0); LK.gui.top.addChild(levelText); levelText.y = 120; var scoreText = new Text2('0', { size: 60, fill: 0xFFFFFF }); scoreText.anchor.set(1, 0); LK.gui.topRight.addChild(scoreText); scoreText.x = -50; scoreText.y = 50; function updateUI() { levelText.setText('Level ' + currentLevel); scoreText.setText(LK.getScore()); } function getCardsForLevel(level) { var numPairs = Math.min(4 + Math.floor(level / 2), 16); var colorsNeeded = Math.min(numPairs, labubuColors.length); var cardData = []; for (var i = 0; i < colorsNeeded; i++) { cardData.push(labubuColors[i]); cardData.push(labubuColors[i]); } // Shuffle the array for (var i = cardData.length - 1; i > 0; i--) { var j = Math.floor(Math.random() * (i + 1)); var temp = cardData[i]; cardData[i] = cardData[j]; cardData[j] = temp; } return cardData; } function createLevel() { // Clear existing cards for (var i = 0; i < cards.length; i++) { cards[i].destroy(); } cards = []; flippedCards = []; isCheckingMatch = false; gameWon = false; var cardData = getCardsForLevel(currentLevel); var numCards = cardData.length; // Calculate grid layout var cols = Math.ceil(Math.sqrt(numCards)); var rows = Math.ceil(numCards / cols); var cardSpacing = 230; var startX = (2048 - (cols - 1) * cardSpacing) / 2; var startY = (2732 - (rows - 1) * cardSpacing) / 2; // Create cards for (var i = 0; i < numCards; i++) { var card = new Card(cardData[i]); var col = i % cols; var row = Math.floor(i / cols); card.x = startX + col * cardSpacing; card.y = startY + row * cardSpacing; cards.push(card); game.addChild(card); } updateUI(); } function handleCardClick(card) { if (isCheckingMatch || flippedCards.length >= 2) return; flippedCards.push(card); card.flip(); if (flippedCards.length === 2) { isCheckingMatch = true; LK.setTimeout(function () { checkMatch(); }, 1000); } } function checkMatch() { var card1 = flippedCards[0]; var card2 = flippedCards[1]; if (card1.labubuColor === card2.labubuColor) { // Match found card1.setMatched(); card2.setMatched(); LK.setScore(LK.getScore() + 10); updateUI(); // Check if level complete var matchedCount = 0; for (var i = 0; i < cards.length; i++) { if (cards[i].isMatched) { matchedCount++; } } if (matchedCount === cards.length) { // Level complete LK.setTimeout(function () { nextLevel(); }, 1000); } } else { // No match - flip cards back card1.flip(); card2.flip(); } flippedCards = []; isCheckingMatch = false; } function nextLevel() { currentLevel++; if (currentLevel > maxLevel) { // Game won gameWon = true; LK.showYouWin(); } else { createLevel(); } } // Initialize first level createLevel(); game.update = function () { // Game logic handled by card interactions and timers };
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var Card = Container.expand(function (labubuColor) {
var self = Container.call(this);
self.labubuColor = labubuColor;
self.isFlipped = false;
self.isMatched = false;
self.isFlipping = false;
// Create card back outline
self.cardBackOutline = self.attachAsset('cardBackOutline', {
anchorX: 0.5,
anchorY: 0.5
});
// Create card back
self.cardBack = self.attachAsset('cardBack', {
anchorX: 0.5,
anchorY: 0.5
});
// Create card front
self.cardFront = self.attachAsset('cardFront', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0,
alpha: 0
});
// Create Labubu character
self.labubu = self.cardFront.addChild(LK.getAsset(labubuColor, {
anchorX: 0.5,
anchorY: 0.5
}));
self.flip = function (callback) {
if (self.isFlipping || self.isMatched) return;
self.isFlipping = true;
LK.getSound('cardFlip').play();
if (!self.isFlipped) {
// Flip to front
tween(self.cardBack, {
scaleX: 0
}, {
duration: 150,
onFinish: function onFinish() {
self.cardBack.alpha = 0;
self.cardBackOutline.alpha = 0;
self.cardFront.alpha = 1;
tween(self.cardFront, {
scaleX: 1
}, {
duration: 150,
onFinish: function onFinish() {
self.isFlipped = true;
self.isFlipping = false;
if (callback) callback();
}
});
}
});
} else {
// Flip to back
tween(self.cardFront, {
scaleX: 0
}, {
duration: 150,
onFinish: function onFinish() {
self.cardFront.alpha = 0;
self.cardBack.alpha = 1;
self.cardBackOutline.alpha = 1;
tween(self.cardBack, {
scaleX: 1
}, {
duration: 150,
onFinish: function onFinish() {
self.isFlipped = false;
self.isFlipping = false;
if (callback) callback();
}
});
}
});
}
};
self.setMatched = function () {
self.isMatched = true;
LK.getSound('match').play();
tween(self, {
alpha: 0,
scaleX: 0.8,
scaleY: 0.8
}, {
duration: 300,
easing: tween.easeOut
});
};
self.down = function (x, y, obj) {
if (!self.isFlipping && !self.isMatched && !gameWon) {
handleCardClick(self);
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x2C3E50
});
/****
* Game Code
****/
var currentLevel = 1;
var maxLevel = 10;
var cards = [];
var flippedCards = [];
var isCheckingMatch = false;
var gameWon = false;
var labubuColors = ['labubuRed', 'labubuBlue', 'labubuGreen', 'labubuYellow', 'labubuPurple', 'labubuOrange', 'labubuPink', 'labubuCyan'];
// UI Elements
var levelText = new Text2('Level 1', {
size: 80,
fill: 0xFFFFFF
});
levelText.anchor.set(0.5, 0);
LK.gui.top.addChild(levelText);
levelText.y = 120;
var scoreText = new Text2('0', {
size: 60,
fill: 0xFFFFFF
});
scoreText.anchor.set(1, 0);
LK.gui.topRight.addChild(scoreText);
scoreText.x = -50;
scoreText.y = 50;
function updateUI() {
levelText.setText('Level ' + currentLevel);
scoreText.setText(LK.getScore());
}
function getCardsForLevel(level) {
var numPairs = Math.min(4 + Math.floor(level / 2), 16);
var colorsNeeded = Math.min(numPairs, labubuColors.length);
var cardData = [];
for (var i = 0; i < colorsNeeded; i++) {
cardData.push(labubuColors[i]);
cardData.push(labubuColors[i]);
}
// Shuffle the array
for (var i = cardData.length - 1; i > 0; i--) {
var j = Math.floor(Math.random() * (i + 1));
var temp = cardData[i];
cardData[i] = cardData[j];
cardData[j] = temp;
}
return cardData;
}
function createLevel() {
// Clear existing cards
for (var i = 0; i < cards.length; i++) {
cards[i].destroy();
}
cards = [];
flippedCards = [];
isCheckingMatch = false;
gameWon = false;
var cardData = getCardsForLevel(currentLevel);
var numCards = cardData.length;
// Calculate grid layout
var cols = Math.ceil(Math.sqrt(numCards));
var rows = Math.ceil(numCards / cols);
var cardSpacing = 230;
var startX = (2048 - (cols - 1) * cardSpacing) / 2;
var startY = (2732 - (rows - 1) * cardSpacing) / 2;
// Create cards
for (var i = 0; i < numCards; i++) {
var card = new Card(cardData[i]);
var col = i % cols;
var row = Math.floor(i / cols);
card.x = startX + col * cardSpacing;
card.y = startY + row * cardSpacing;
cards.push(card);
game.addChild(card);
}
updateUI();
}
function handleCardClick(card) {
if (isCheckingMatch || flippedCards.length >= 2) return;
flippedCards.push(card);
card.flip();
if (flippedCards.length === 2) {
isCheckingMatch = true;
LK.setTimeout(function () {
checkMatch();
}, 1000);
}
}
function checkMatch() {
var card1 = flippedCards[0];
var card2 = flippedCards[1];
if (card1.labubuColor === card2.labubuColor) {
// Match found
card1.setMatched();
card2.setMatched();
LK.setScore(LK.getScore() + 10);
updateUI();
// Check if level complete
var matchedCount = 0;
for (var i = 0; i < cards.length; i++) {
if (cards[i].isMatched) {
matchedCount++;
}
}
if (matchedCount === cards.length) {
// Level complete
LK.setTimeout(function () {
nextLevel();
}, 1000);
}
} else {
// No match - flip cards back
card1.flip();
card2.flip();
}
flippedCards = [];
isCheckingMatch = false;
}
function nextLevel() {
currentLevel++;
if (currentLevel > maxLevel) {
// Game won
gameWon = true;
LK.showYouWin();
} else {
createLevel();
}
}
// Initialize first level
createLevel();
game.update = function () {
// Game logic handled by card interactions and timers
};
Red Labubu. In-Game asset. 2d. High contrast. No shadows
Blue Labubu. In-Game asset. 2d. High contrast. No shadows
Cyan Labubu. In-Game asset. 2d. High contrast. No shadows
Yellow Labubu. In-Game asset. 2d. High contrast. No shadows
Labubu green. In-Game asset. 2d. High contrast. No shadows
Orange Labubu. In-Game asset. 2d. High contrast. No shadows
Labubu pink. In-Game asset. 2d. High contrast. No shadows
Labubu purple. In-Game asset. 2d. High contrast. No shadows