/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ // Tile class: represents a single memory tile var Tile = Container.expand(function () { var self = Container.call(this); // Properties self.isFlipped = false; self.isMatched = false; self.animalId = null; // Will be set on creation // Create the back of the tile (hidden state) var back = self.attachAsset('tileBack', { anchorX: 0.5, anchorY: 0.5 }); // Create the front of the tile (animal/plant) var front = self.attachAsset('animal0', { // Placeholder, will be replaced anchorX: 0.5, anchorY: 0.5, visible: false }); self.back = back; self.front = front; // Set animal asset self.setAnimal = function (animalId) { self.animalId = animalId; // Remove old front if exists if (self.front) { self.removeChild(self.front); } // Attach new front self.front = self.attachAsset('animal' + animalId, { anchorX: 0.5, anchorY: 0.5, visible: false }); }; // Flip to show animal self.flipUp = function () { if (self.isFlipped || self.isMatched) return; self.isFlipped = true; // Play flip sound LK.getSound('flip').play(); // Animate flip tween(self, { scaleX: 0 }, { duration: 100, easing: tween.easeIn, onFinish: function onFinish() { self.back.visible = false; self.front.visible = true; tween(self, { scaleX: 1 }, { duration: 100, easing: tween.easeOut }); } }); }; // Flip to hide animal self.flipDown = function () { if (!self.isFlipped || self.isMatched) return; self.isFlipped = false; // Play flip sound LK.getSound('flip').play(); tween(self, { scaleX: 0 }, { duration: 100, easing: tween.easeIn, onFinish: function onFinish() { self.front.visible = false; self.back.visible = true; tween(self, { scaleX: 1 }, { duration: 100, easing: tween.easeOut }); } }); }; // Mark as matched (permanently face up) self.setMatched = function () { self.isMatched = true; self.isFlipped = true; self.back.visible = false; self.front.visible = true; // Optional: animate a little pop tween(self, { scaleX: 1.2, scaleY: 1.2 }, { duration: 100, easing: tween.easeOut, onFinish: function onFinish() { tween(self, { scaleX: 1, scaleY: 1 }, { duration: 100, easing: tween.easeIn }); } }); }; // Handle tap self.down = function (x, y, obj) { if (self.isFlipped || self.isMatched || !canFlipTiles) return; onTileFlipped(self); }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x2f4a01 // Changed to requested color #2f4a01 }); /**** * Game Code ****/ // Animal tile assets: numbers 0-10 for 10 levels (11 unique animals) // --- Game variables --- // Sound assets var animalCount = 11; // Number of unique animals/plants (animal0 ... animal10) var tileBackColor = 0x8db580; // Light green for tile back var tileSize = 260; // px, square var tilePadding = 32; // px var minBoardMargin = 60; // px, margin from edge var level = 1; var hearts = 10; var score = 0; var combo = 0; var maxCombo = 0; var consecutiveMisses = 0; var tiles = []; var flippedTiles = []; var canFlipTiles = true; var pairsLeft = 0; // --- UI elements --- var scoreTxt = new Text2('0', { size: 120, fill: "#fff" }); scoreTxt.anchor.set(0.5, 0); LK.gui.top.addChild(scoreTxt); var heartsTxt = new Text2('♥ 10', { size: 90, fill: 0xFF4D4D }); heartsTxt.anchor.set(0.5, 0); LK.gui.top.addChild(heartsTxt); heartsTxt.y = 120; heartsTxt.x = 0; var levelTxt = new Text2('Level 1', { size: 90, fill: 0xFFE066 }); levelTxt.anchor.set(0.5, 0); LK.gui.top.addChild(levelTxt); levelTxt.y = 220; levelTxt.x = 0; // --- Asset initialization (shapes for tile back, animal images) --- for (var i = 0; i < animalCount; i++) {} // --- Helper: shuffle array --- function shuffle(arr) { for (var i = arr.length - 1; i > 0; i--) { var j = Math.floor(Math.random() * (i + 1)); var t = arr[i]; arr[i] = arr[j]; arr[j] = t; } return arr; } // --- Helper: update UI --- function updateUI() { scoreTxt.setText(score); heartsTxt.setText('♥ ' + hearts); levelTxt.setText('Level ' + level); } // --- Helper: show all tiles for preview --- function previewTiles(cb) { canFlipTiles = false; for (var i = 0; i < tiles.length; i++) { tiles[i].flipUp(); } LK.setTimeout(function () { for (var i = 0; i < tiles.length; i++) { tiles[i].flipDown(); } canFlipTiles = true; if (cb) cb(); }, 1200 + Math.min(600, level * 100)); } // --- Helper: create board for current level --- function createBoard() { // Remove old tiles for (var i = 0; i < tiles.length; i++) { tiles[i].destroy(); } tiles = []; flippedTiles = []; canFlipTiles = false; // Determine number of tiles for this level // Level 1: 4 tiles (2 pairs), then +2 tiles per level, up to level 10 var maxLevel = 10; var cappedLevel = Math.min(level, maxLevel); var tileCount = 4 + (cappedLevel - 1) * 2; var pairCount = Math.floor(tileCount / 2); if (pairCount > animalCount) pairCount = animalCount; // Cap to available animal assets tileCount = pairCount * 2; // Ensure even number // Find grid size (try to make as square as possible) var cols = Math.ceil(Math.sqrt(tileCount)); var rows = Math.ceil(tileCount / cols); // Prepare animal pairs var animalIds = []; for (var i = 0; i < pairCount; i++) { animalIds.push(i); animalIds.push(i); } shuffle(animalIds); // Board centering var boardW = cols * tileSize + (cols - 1) * tilePadding; var boardH = rows * tileSize + (rows - 1) * tilePadding; var startX = Math.floor((2048 - boardW) / 2) + tileSize / 2; var startY = Math.floor((2732 - boardH) / 2) + tileSize / 2; // Create tiles var idx = 0; for (var r = 0; r < rows; r++) { for (var c = 0; c < cols; c++) { if (idx >= animalIds.length) continue; var tile = new Tile(); tile.setAnimal(animalIds[idx]); tile.x = startX + c * (tileSize + tilePadding); tile.y = startY + r * (tileSize + tilePadding); tile.scaleX = 1; tile.scaleY = 1; game.addChild(tile); tiles.push(tile); idx++; } } pairsLeft = pairCount; updateUI(); previewTiles(function () { canFlipTiles = true; }); } // --- Tile flip handler --- function onTileFlipped(tile) { if (!canFlipTiles) return; if (tile.isFlipped || tile.isMatched) return; tile.flipUp(); flippedTiles.push(tile); if (flippedTiles.length === 2) { canFlipTiles = false; var t1 = flippedTiles[0]; var t2 = flippedTiles[1]; if (t1.animalId === t2.animalId) { // Match! LK.setTimeout(function () { // Play match sound LK.getSound('match').play(); t1.setMatched(); t2.setMatched(); pairsLeft--; combo++; maxCombo = Math.max(combo, maxCombo); score += 10 * combo; updateUI(); flippedTiles = []; canFlipTiles = true; consecutiveMisses = 0; // Animate match LK.effects.flashObject(t1, 0xFFFF99, 300); LK.effects.flashObject(t2, 0xFFFF99, 300); if (pairsLeft === 0) { // Level complete! LK.setTimeout(function () { nextLevel(); }, 800); } }, 400); } else { // Not a match LK.setTimeout(function () { // Play error sound LK.getSound('error').play(); t1.flipDown(); t2.flipDown(); flippedTiles = []; canFlipTiles = true; combo = 0; consecutiveMisses++; if (consecutiveMisses >= 3) { hearts--; consecutiveMisses = 0; // Play lose heart sound LK.getSound('loseHeart').play(); LK.effects.flashScreen(0xff0000, 400); updateUI(); if (hearts <= 0) { LK.showGameOver(); return; } } updateUI(); }, 700); } } } // --- Next level --- function nextLevel() { level++; // If player reaches level 10, they win! if (level > 10) { LK.showYouWin(); return; } // Reward: extra heart for levels > 3 if (level > 3) { hearts++; // Play gain heart sound LK.getSound('gainHeart').play(); LK.effects.flashScreen(0x66ff66, 400); } combo = 0; consecutiveMisses = 0; createBoard(); } // --- Start game --- function startGame() { level = 1; hearts = 10; score = 0; combo = 0; maxCombo = 0; consecutiveMisses = 0; createBoard(); } // --- Game update (not used for logic here) --- game.update = function () { // No per-frame logic needed }; // --- Start screen --- var startScreen = new Container(); var titleTxt = new Text2('Animal Match', { size: 180, fill: "#fff" }); titleTxt.anchor.set(0.5, 0.5); titleTxt.x = 2048 / 2; titleTxt.y = 900; startScreen.addChild(titleTxt); var startBtn = new Container(); var btnBg = LK.getAsset('tileBack', { anchorX: 0.5, anchorY: 0.5 }); btnBg.width = 500; btnBg.height = 180; startBtn.addChild(btnBg); var btnTxt = new Text2('Start', { size: 110, fill: 0x2E4D2C }); btnTxt.anchor.set(0.5, 0.5); btnTxt.x = 0; btnTxt.y = 0; startBtn.addChild(btnTxt); startBtn.x = 2048 / 2; startBtn.y = 1400; startScreen.addChild(startBtn); game.addChild(startScreen); startBtn.down = function (x, y, obj) { // Remove start screen and start the game startScreen.destroy(); startGame(); }; // Hide UI until game starts scoreTxt.visible = false; heartsTxt.visible = false; levelTxt.visible = false; // Show UI when game starts var _origStartGame = startGame; startGame = function startGame() { scoreTxt.visible = true; heartsTxt.visible = true; levelTxt.visible = true; _origStartGame(); };
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
// Tile class: represents a single memory tile
var Tile = Container.expand(function () {
var self = Container.call(this);
// Properties
self.isFlipped = false;
self.isMatched = false;
self.animalId = null; // Will be set on creation
// Create the back of the tile (hidden state)
var back = self.attachAsset('tileBack', {
anchorX: 0.5,
anchorY: 0.5
});
// Create the front of the tile (animal/plant)
var front = self.attachAsset('animal0', {
// Placeholder, will be replaced
anchorX: 0.5,
anchorY: 0.5,
visible: false
});
self.back = back;
self.front = front;
// Set animal asset
self.setAnimal = function (animalId) {
self.animalId = animalId;
// Remove old front if exists
if (self.front) {
self.removeChild(self.front);
}
// Attach new front
self.front = self.attachAsset('animal' + animalId, {
anchorX: 0.5,
anchorY: 0.5,
visible: false
});
};
// Flip to show animal
self.flipUp = function () {
if (self.isFlipped || self.isMatched) return;
self.isFlipped = true;
// Play flip sound
LK.getSound('flip').play();
// Animate flip
tween(self, {
scaleX: 0
}, {
duration: 100,
easing: tween.easeIn,
onFinish: function onFinish() {
self.back.visible = false;
self.front.visible = true;
tween(self, {
scaleX: 1
}, {
duration: 100,
easing: tween.easeOut
});
}
});
};
// Flip to hide animal
self.flipDown = function () {
if (!self.isFlipped || self.isMatched) return;
self.isFlipped = false;
// Play flip sound
LK.getSound('flip').play();
tween(self, {
scaleX: 0
}, {
duration: 100,
easing: tween.easeIn,
onFinish: function onFinish() {
self.front.visible = false;
self.back.visible = true;
tween(self, {
scaleX: 1
}, {
duration: 100,
easing: tween.easeOut
});
}
});
};
// Mark as matched (permanently face up)
self.setMatched = function () {
self.isMatched = true;
self.isFlipped = true;
self.back.visible = false;
self.front.visible = true;
// Optional: animate a little pop
tween(self, {
scaleX: 1.2,
scaleY: 1.2
}, {
duration: 100,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(self, {
scaleX: 1,
scaleY: 1
}, {
duration: 100,
easing: tween.easeIn
});
}
});
};
// Handle tap
self.down = function (x, y, obj) {
if (self.isFlipped || self.isMatched || !canFlipTiles) return;
onTileFlipped(self);
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x2f4a01 // Changed to requested color #2f4a01
});
/****
* Game Code
****/
// Animal tile assets: numbers 0-10 for 10 levels (11 unique animals)
// --- Game variables ---
// Sound assets
var animalCount = 11; // Number of unique animals/plants (animal0 ... animal10)
var tileBackColor = 0x8db580; // Light green for tile back
var tileSize = 260; // px, square
var tilePadding = 32; // px
var minBoardMargin = 60; // px, margin from edge
var level = 1;
var hearts = 10;
var score = 0;
var combo = 0;
var maxCombo = 0;
var consecutiveMisses = 0;
var tiles = [];
var flippedTiles = [];
var canFlipTiles = true;
var pairsLeft = 0;
// --- UI elements ---
var scoreTxt = new Text2('0', {
size: 120,
fill: "#fff"
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
var heartsTxt = new Text2('♥ 10', {
size: 90,
fill: 0xFF4D4D
});
heartsTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(heartsTxt);
heartsTxt.y = 120;
heartsTxt.x = 0;
var levelTxt = new Text2('Level 1', {
size: 90,
fill: 0xFFE066
});
levelTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(levelTxt);
levelTxt.y = 220;
levelTxt.x = 0;
// --- Asset initialization (shapes for tile back, animal images) ---
for (var i = 0; i < animalCount; i++) {}
// --- Helper: shuffle array ---
function shuffle(arr) {
for (var i = arr.length - 1; i > 0; i--) {
var j = Math.floor(Math.random() * (i + 1));
var t = arr[i];
arr[i] = arr[j];
arr[j] = t;
}
return arr;
}
// --- Helper: update UI ---
function updateUI() {
scoreTxt.setText(score);
heartsTxt.setText('♥ ' + hearts);
levelTxt.setText('Level ' + level);
}
// --- Helper: show all tiles for preview ---
function previewTiles(cb) {
canFlipTiles = false;
for (var i = 0; i < tiles.length; i++) {
tiles[i].flipUp();
}
LK.setTimeout(function () {
for (var i = 0; i < tiles.length; i++) {
tiles[i].flipDown();
}
canFlipTiles = true;
if (cb) cb();
}, 1200 + Math.min(600, level * 100));
}
// --- Helper: create board for current level ---
function createBoard() {
// Remove old tiles
for (var i = 0; i < tiles.length; i++) {
tiles[i].destroy();
}
tiles = [];
flippedTiles = [];
canFlipTiles = false;
// Determine number of tiles for this level
// Level 1: 4 tiles (2 pairs), then +2 tiles per level, up to level 10
var maxLevel = 10;
var cappedLevel = Math.min(level, maxLevel);
var tileCount = 4 + (cappedLevel - 1) * 2;
var pairCount = Math.floor(tileCount / 2);
if (pairCount > animalCount) pairCount = animalCount; // Cap to available animal assets
tileCount = pairCount * 2; // Ensure even number
// Find grid size (try to make as square as possible)
var cols = Math.ceil(Math.sqrt(tileCount));
var rows = Math.ceil(tileCount / cols);
// Prepare animal pairs
var animalIds = [];
for (var i = 0; i < pairCount; i++) {
animalIds.push(i);
animalIds.push(i);
}
shuffle(animalIds);
// Board centering
var boardW = cols * tileSize + (cols - 1) * tilePadding;
var boardH = rows * tileSize + (rows - 1) * tilePadding;
var startX = Math.floor((2048 - boardW) / 2) + tileSize / 2;
var startY = Math.floor((2732 - boardH) / 2) + tileSize / 2;
// Create tiles
var idx = 0;
for (var r = 0; r < rows; r++) {
for (var c = 0; c < cols; c++) {
if (idx >= animalIds.length) continue;
var tile = new Tile();
tile.setAnimal(animalIds[idx]);
tile.x = startX + c * (tileSize + tilePadding);
tile.y = startY + r * (tileSize + tilePadding);
tile.scaleX = 1;
tile.scaleY = 1;
game.addChild(tile);
tiles.push(tile);
idx++;
}
}
pairsLeft = pairCount;
updateUI();
previewTiles(function () {
canFlipTiles = true;
});
}
// --- Tile flip handler ---
function onTileFlipped(tile) {
if (!canFlipTiles) return;
if (tile.isFlipped || tile.isMatched) return;
tile.flipUp();
flippedTiles.push(tile);
if (flippedTiles.length === 2) {
canFlipTiles = false;
var t1 = flippedTiles[0];
var t2 = flippedTiles[1];
if (t1.animalId === t2.animalId) {
// Match!
LK.setTimeout(function () {
// Play match sound
LK.getSound('match').play();
t1.setMatched();
t2.setMatched();
pairsLeft--;
combo++;
maxCombo = Math.max(combo, maxCombo);
score += 10 * combo;
updateUI();
flippedTiles = [];
canFlipTiles = true;
consecutiveMisses = 0;
// Animate match
LK.effects.flashObject(t1, 0xFFFF99, 300);
LK.effects.flashObject(t2, 0xFFFF99, 300);
if (pairsLeft === 0) {
// Level complete!
LK.setTimeout(function () {
nextLevel();
}, 800);
}
}, 400);
} else {
// Not a match
LK.setTimeout(function () {
// Play error sound
LK.getSound('error').play();
t1.flipDown();
t2.flipDown();
flippedTiles = [];
canFlipTiles = true;
combo = 0;
consecutiveMisses++;
if (consecutiveMisses >= 3) {
hearts--;
consecutiveMisses = 0;
// Play lose heart sound
LK.getSound('loseHeart').play();
LK.effects.flashScreen(0xff0000, 400);
updateUI();
if (hearts <= 0) {
LK.showGameOver();
return;
}
}
updateUI();
}, 700);
}
}
}
// --- Next level ---
function nextLevel() {
level++;
// If player reaches level 10, they win!
if (level > 10) {
LK.showYouWin();
return;
}
// Reward: extra heart for levels > 3
if (level > 3) {
hearts++;
// Play gain heart sound
LK.getSound('gainHeart').play();
LK.effects.flashScreen(0x66ff66, 400);
}
combo = 0;
consecutiveMisses = 0;
createBoard();
}
// --- Start game ---
function startGame() {
level = 1;
hearts = 10;
score = 0;
combo = 0;
maxCombo = 0;
consecutiveMisses = 0;
createBoard();
}
// --- Game update (not used for logic here) ---
game.update = function () {
// No per-frame logic needed
};
// --- Start screen ---
var startScreen = new Container();
var titleTxt = new Text2('Animal Match', {
size: 180,
fill: "#fff"
});
titleTxt.anchor.set(0.5, 0.5);
titleTxt.x = 2048 / 2;
titleTxt.y = 900;
startScreen.addChild(titleTxt);
var startBtn = new Container();
var btnBg = LK.getAsset('tileBack', {
anchorX: 0.5,
anchorY: 0.5
});
btnBg.width = 500;
btnBg.height = 180;
startBtn.addChild(btnBg);
var btnTxt = new Text2('Start', {
size: 110,
fill: 0x2E4D2C
});
btnTxt.anchor.set(0.5, 0.5);
btnTxt.x = 0;
btnTxt.y = 0;
startBtn.addChild(btnTxt);
startBtn.x = 2048 / 2;
startBtn.y = 1400;
startScreen.addChild(startBtn);
game.addChild(startScreen);
startBtn.down = function (x, y, obj) {
// Remove start screen and start the game
startScreen.destroy();
startGame();
};
// Hide UI until game starts
scoreTxt.visible = false;
heartsTxt.visible = false;
levelTxt.visible = false;
// Show UI when game starts
var _origStartGame = startGame;
startGame = function startGame() {
scoreTxt.visible = true;
heartsTxt.visible = true;
levelTxt.visible = true;
_origStartGame();
};
Put like a wooden background
Put like a wooden background
make the rabbit cartoony
Cartoon deer with plane wooden background. In-Game asset. 2d. High contrast. No shadows
Owl Image with wooden background. In-Game asset. 2d. High contrast. No shadows
A scary lion image with wooden background. In-Game asset. 2d. High contrast. No shadows
A tiger image, with wooden background. In-Game asset. 2d. High contrast. No shadows
A beaver with wooden background. In-Game asset. 2d. High contrast. No shadows
Racoon image with wooden background. In-Game asset. 2d. High contrast. No shadows
Moose pic with wooden background. In-Game asset. 2d. High contrast. No shadows
Bear with wooden background. In-Game asset. 2d. High contrast. No shadows
A Wooden square tile with dark borders. In-Game asset. 2d. High contrast. No shadows