User prompt
Add my image's that called daisy , rock and Water to the fruit's
User prompt
add my image's that called Coconut , kiwi , apple , pear , Pineapple , Avocado from the fruits
User prompt
Show fruits for a few seconds at each level and increase the time at each level
User prompt
remove the timer
User prompt
The duration of showing the fruits should be longer at each level and the number of seconds it will be shown should be written on the top of the cards.
User prompt
show how mony hearts left in left down
User prompt
How many lives are left should be shown with hearts at the bottom left and one heart should be lost for every mistake.
User prompt
level yükseldikçe can sayısı da artsın
User prompt
change the fruit colors by the image's in my assests that named Watermelon , Lemon , Cherry , Orange , Grape , Banana , Peach and Strawberry
User prompt
use the "watermelon" image for one fruit
Code edit (1 edits merged)
Please save this source code
User prompt
Fruit Memory Match
Initial prompt
Make a memory game with cards, have fruit pictures on the cards and have 2 of each fruit. First show all the cards for a while and then close them all. The card that the player clicks on is opened and the picture that appears must be the same as the picture of the second card that he opens. If they are the same, the cards are open. If they are different, the cards are closed and have a life system. For every mistake, 1 life is lost and there is a life right. Let the game be in 10 different levels. Each level will be harder than the previous one. You cannot pass to the next level without completing it. The number of lives should change according to the difficulty of the level.
/****
* 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 states: 'hidden', 'revealed', 'matched'
self.state = 'hidden';
self.fruitId = null; // Will be set on creation
// Card back (hidden state)
var back = self.attachAsset('cardBack', {
anchorX: 0.5,
anchorY: 0.5
});
self.back = back;
// Card front (fruit image, revealed state)
// Default to watermelon image, will be replaced by setFruit
var front = self.attachAsset('Watermelon', {
anchorX: 0.5,
anchorY: 0.5
});
self.front = front;
self.front.visible = false;
// Set fruit image for this card
self.setFruit = function (fruitId) {
self.fruitId = fruitId;
// Map fruitId to asset name in assets section
var assetMap = {
'banana': 'Banana',
'cherry': 'Cherry',
'orange': 'Orange',
'grape': 'grape',
'lemon': 'lemon',
'peach': 'Peach',
'strawberry': 'strawberry',
'watermelon': 'Watermelon'
};
var assetName = assetMap[fruitId] || 'fruit';
var fruitAsset = LK.getAsset(assetName, {
anchorX: 0.5,
anchorY: 0.5
});
// Remove old front if present
if (self.front && self.front.parent) self.removeChild(self.front);
self.front = fruitAsset;
self.addChild(self.front);
self.front.visible = false;
self.front.x = 0;
self.front.y = 0;
self.back.x = 0;
self.back.y = 0;
};
// Reveal the card (show fruit)
self.reveal = function () {
if (self.state !== 'hidden') return;
self.state = 'revealed';
self.back.visible = false;
self.front.visible = true;
// Optional: flip animation
tween(self, {
scaleX: 0
}, {
duration: 80,
easing: tween.cubicIn,
onFinish: function onFinish() {
self.back.visible = false;
self.front.visible = true;
tween(self, {
scaleX: 1
}, {
duration: 80,
easing: tween.cubicOut
});
}
});
};
// Hide the card (show back)
self.hide = function () {
if (self.state !== 'revealed') return;
self.state = 'hidden';
// Optional: flip animation
tween(self, {
scaleX: 0
}, {
duration: 80,
easing: tween.cubicIn,
onFinish: function onFinish() {
self.front.visible = false;
self.back.visible = true;
tween(self, {
scaleX: 1
}, {
duration: 80,
easing: tween.cubicOut
});
}
});
};
// Mark as matched (permanently revealed)
self.match = function () {
self.state = 'matched';
self.back.visible = false;
self.front.visible = true;
// Optional: small scale bounce
tween(self, {
scaleX: 1.15,
scaleY: 1.15
}, {
duration: 100,
easing: tween.bounceOut,
onFinish: function onFinish() {
tween(self, {
scaleX: 1,
scaleY: 1
}, {
duration: 100
});
}
});
};
// Handle tap
self.down = function (x, y, obj) {
if (self.state === 'hidden' && !game.lockInput) {
game.onCardTapped(self);
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x1a1a1a
});
/****
* Game Code
****/
// Fruit pool (all fruits with images in assets)
var fruitIds = ['banana', 'cherry', 'orange', 'grape', 'lemon', 'peach', 'strawberry', 'watermelon'];
// No need to dynamically create fruit image assets, all are defined in assets section
// Game variables
var level = 1;
var maxLevel = 10;
var cards = [];
var revealedCards = [];
var matchedPairs = 0;
var totalPairs = 0;
var lives = 0;
var maxLives = 0;
var lockInput = false;
var levelText, livesText, messageText;
// Heart/lives display
var heartNodes = [];
var heartAssetName = 'heart';
// Use a heart image asset (add to assets if not present)
var heartSize = 80;
var heartSpacing = 20;
var heartMargin = 30;
// GUI setup
levelText = new Text2('Level 1', {
size: 90,
fill: "#fff"
});
levelText.anchor.set(0.5, 0);
LK.gui.top.addChild(levelText);
livesText = new Text2('Lives: 3', {
size: 90,
fill: "#fff"
});
livesText.anchor.set(0.5, 0);
LK.gui.top.addChild(livesText);
livesText.y = 100;
livesText.x = 2048 / 2;
// Message text (centered, for "Level X", "You Win", etc)
messageText = new Text2('', {
size: 140,
fill: "#fff"
});
messageText.anchor.set(0.5, 0.5);
LK.gui.center.addChild(messageText);
messageText.visible = false;
// Layout parameters
var boardMargin = 80;
var cardSpacingX = 40;
var cardSpacingY = 40;
// Helper: shuffle array
function shuffle(array) {
for (var i = array.length - 1; i > 0; i--) {
var j = Math.floor(Math.random() * (i + 1));
var t = array[i];
array[i] = array[j];
array[j] = t;
}
return array;
}
// Helper: get grid size for level
function getGridForLevel(lvl) {
// Level 1: 2x2 (4 cards, 2 pairs)
// Level 2: 2x3 (6 cards, 3 pairs)
// Level 3: 2x4 (8 cards, 4 pairs)
// Level 4: 3x4 (12 cards, 6 pairs)
// Level 5: 4x4 (16 cards, 8 pairs)
// Level 6: 4x5 (20 cards, 10 pairs)
// Level 7: 5x6 (30 cards, 15 pairs)
// Level 8: 6x6 (36 cards, 18 pairs)
// Level 9: 6x7 (42 cards, 21 pairs)
// Level 10: 7x8 (56 cards, 28 pairs)
var grids = [[2, 2], [2, 3], [2, 4], [3, 4], [4, 4], [4, 5], [5, 6], [6, 6], [6, 7], [7, 8]];
return grids[Math.min(lvl - 1, grids.length - 1)];
}
// Helper: get lives for level
function getLivesForLevel(lvl) {
// Start with 3, increase by 1 every 2 levels, max 10
return Math.min(10, 3 + Math.floor((lvl - 1) / 2));
}
// Start a new level
function startLevel(lvl) {
// Clean up
for (var i = 0; i < cards.length; i++) {
cards[i].destroy();
}
cards = [];
revealedCards = [];
matchedPairs = 0;
lockInput = true;
game.lockInput = true;
// Set level/lives
level = lvl;
var grid = getGridForLevel(level);
var rows = grid[0],
cols = grid[1];
totalPairs = Math.floor(rows * cols / 2);
maxLives = getLivesForLevel(level);
lives = maxLives;
// Update GUI
levelText.setText('Level ' + level);
livesText.setText('Lives: ' + lives);
// Remove old hearts
for (var i = 0; i < heartNodes.length; i++) {
if (heartNodes[i].parent) heartNodes[i].parent.removeChild(heartNodes[i]);
heartNodes[i].destroy && heartNodes[i].destroy();
}
heartNodes = [];
// Draw new hearts for current lives
for (var i = 0; i < lives; i++) {
var heart = LK.getAsset(heartAssetName, {
anchorX: 0,
anchorY: 1
});
// Place hearts at the bottom left, leaving a margin from the left and bottom
heart.x = heartMargin + i * (heartSize + heartSpacing);
heart.y = 2732 - heartMargin;
// Add directly to the game (not GUI overlay) so it stays at the bottom left of the play area
game.addChild(heart);
heartNodes.push(heart);
}
// Prepare fruit pairs
var fruitPool = [];
for (var i = 0; i < totalPairs; i++) {
var fruit = fruitIds[i % fruitIds.length];
fruitPool.push(fruit, fruit);
}
shuffle(fruitPool);
// Card size
var cardW = LK.getAsset('cardBack', {}).width;
var cardH = LK.getAsset('cardBack', {}).height;
// Board size
var boardW = cols * cardW + (cols - 1) * cardSpacingX;
var boardH = rows * cardH + (rows - 1) * cardSpacingY;
var startX = (2048 - boardW) / 2 + cardW / 2;
var startY = (2732 - boardH) / 2 + cardH / 2 + 60;
// Create cards
var idx = 0;
for (var r = 0; r < rows; r++) {
for (var c = 0; c < cols; c++) {
if (idx >= fruitPool.length) continue;
var card = new Card();
card.setFruit(fruitPool[idx]);
card.x = startX + c * (cardW + cardSpacingX);
card.y = startY + r * (cardH + cardSpacingY);
card.scaleX = 1;
card.scaleY = 1;
game.addChild(card);
cards.push(card);
idx++;
}
}
// Show all cards briefly, with duration increasing by level
var showDuration = 1500 + (level - 1) * 500; // 1.5s + 0.5s per level
// Add a timer text on top of each card
var timerTexts = [];
var secondsToShow = Math.round(showDuration / 100) / 10; // e.g. 2.0, 2.5, 3.0
for (var i = 0; i < cards.length; i++) {
cards[i].front.visible = true;
cards[i].back.visible = false;
cards[i].state = 'revealed';
// Add timer text above the card
var timerText = new Text2(secondsToShow.toFixed(1) + 's', {
size: 60,
fill: "#fff"
});
timerText.anchor.set(0.5, 1);
timerText.x = cards[i].x;
timerText.y = cards[i].y - LK.getAsset('cardBack', {}).height / 2 - 10;
game.addChild(timerText);
timerTexts.push(timerText);
}
messageText.setText('Level ' + level);
messageText.visible = true;
// After showDuration ms, hide all cards and allow input
LK.setTimeout(function () {
for (var i = 0; i < cards.length; i++) {
cards[i].front.visible = false;
cards[i].back.visible = true;
cards[i].state = 'hidden';
cards[i].scaleX = 1;
cards[i].scaleY = 1;
}
// Remove timer texts
for (var i = 0; i < timerTexts.length; i++) {
if (timerTexts[i].parent) timerTexts[i].parent.removeChild(timerTexts[i]);
timerTexts[i].destroy && timerTexts[i].destroy();
}
timerTexts = [];
messageText.visible = false;
lockInput = false;
game.lockInput = false;
}, showDuration);
}
// Card tap handler
game.onCardTapped = function (card) {
if (lockInput || card.state !== 'hidden') return;
card.reveal();
revealedCards.push(card);
if (revealedCards.length === 2) {
lockInput = true;
game.lockInput = true;
var c1 = revealedCards[0],
c2 = revealedCards[1];
if (c1.fruitId === c2.fruitId) {
// Match!
LK.setTimeout(function () {
c1.match();
c2.match();
matchedPairs++;
revealedCards = [];
lockInput = false;
game.lockInput = false;
// Check win
if (matchedPairs === totalPairs) {
if (level === maxLevel) {
// Game completed!
messageText.setText('You Win!');
messageText.visible = true;
LK.setTimeout(function () {
messageText.visible = false;
LK.showYouWin();
}, 1200);
} else {
// Next level
messageText.setText('Level Complete!');
messageText.visible = true;
LK.setTimeout(function () {
messageText.visible = false;
startLevel(level + 1);
}, 1200);
}
}
}, 350);
} else {
// Not a match
LK.setTimeout(function () {
c1.hide();
c2.hide();
revealedCards = [];
lives--;
livesText.setText('Lives: ' + lives);
// Update hearts: hide one for each lost life
for (var i = 0; i < heartNodes.length; i++) {
heartNodes[i].visible = i < lives;
}
lockInput = false;
game.lockInput = false;
if (lives <= 0) {
// Game over
messageText.setText('Game Over');
messageText.visible = true;
LK.setTimeout(function () {
messageText.visible = false;
LK.showGameOver();
}, 1200);
}
}, 650);
}
}
};
// Prevent interaction when locked
game.down = function (x, y, obj) {
// No-op: all input handled by Card.down
};
game.move = function (x, y, obj) {};
game.up = function (x, y, obj) {};
// Start first level
startLevel(1);
// No need for game.update, all logic is event-driven ===================================================================
--- original.js
+++ change.js
@@ -291,29 +291,49 @@
cards.push(card);
idx++;
}
}
- // Show all cards briefly
+ // Show all cards briefly, with duration increasing by level
+ var showDuration = 1500 + (level - 1) * 500; // 1.5s + 0.5s per level
+ // Add a timer text on top of each card
+ var timerTexts = [];
+ var secondsToShow = Math.round(showDuration / 100) / 10; // e.g. 2.0, 2.5, 3.0
for (var i = 0; i < cards.length; i++) {
cards[i].front.visible = true;
cards[i].back.visible = false;
cards[i].state = 'revealed';
+ // Add timer text above the card
+ var timerText = new Text2(secondsToShow.toFixed(1) + 's', {
+ size: 60,
+ fill: "#fff"
+ });
+ timerText.anchor.set(0.5, 1);
+ timerText.x = cards[i].x;
+ timerText.y = cards[i].y - LK.getAsset('cardBack', {}).height / 2 - 10;
+ game.addChild(timerText);
+ timerTexts.push(timerText);
}
messageText.setText('Level ' + level);
messageText.visible = true;
- // After 1.5s, hide all cards and allow input
+ // After showDuration ms, hide all cards and allow input
LK.setTimeout(function () {
for (var i = 0; i < cards.length; i++) {
cards[i].front.visible = false;
cards[i].back.visible = true;
cards[i].state = 'hidden';
cards[i].scaleX = 1;
cards[i].scaleY = 1;
}
+ // Remove timer texts
+ for (var i = 0; i < timerTexts.length; i++) {
+ if (timerTexts[i].parent) timerTexts[i].parent.removeChild(timerTexts[i]);
+ timerTexts[i].destroy && timerTexts[i].destroy();
+ }
+ timerTexts = [];
messageText.visible = false;
lockInput = false;
game.lockInput = false;
- }, 1500);
+ }, showDuration);
}
// Card tap handler
game.onCardTapped = function (card) {
if (lockInput || card.state !== 'hidden') return;
watermelon. In-Game asset. 2d. High contrast. No shadows
strawberry. In-Game asset. 2d. High contrast. No shadows
banana. In-Game asset. 2d. High contrast. No shadows
lemon. In-Game asset. 2d. High contrast. No shadows
Orange. In-Game asset. 2d. High contrast. No shadows
grape. In-Game asset. 2d. High contrast. No shadows
peach. In-Game asset. 2d. High contrast. No shadows
Cherry. In-Game asset. 2d. High contrast. No shadows
Heart. In-Game asset. 2d. High contrast. No shadows
avocado. In-Game asset. 2d. High contrast. No shadows
Coconut. In-Game asset. 2d. High contrast. No shadows
Pineapple. In-Game asset. 2d. High contrast. No shadows
Kiwi. In-Game asset. 2d. High contrast. No shadows
Apple. In-Game asset. 2d. High contrast. No shadows
Pear. In-Game asset. 2d. High contrast. No shadows
Daisy. In-Game asset. 2d. High contrast. No shadows
Bottle a water. In-Game asset. 2d. High contrast. No shadows
Rock (Gray). In-Game asset. 2d. High contrast. No shadows
Let it be a pink card, the corners are dark pink, getting lighter towards the middle. In-Game asset. 2d. High contrast. No shadows