User prompt
Zor seviyenin süresini 2 dakikaya düşür.
User prompt
Kaç puan kazandığı skor yazısının üstünde olsun.
User prompt
Oyuncunun kaç puan kazandığı "+X" şeklinde gözüksün.
User prompt
Seviye seçme butonları köşeli olmasın. Oval olsun.
User prompt
Seviye seçme butonlarına biraz border-radius ekle
User prompt
En sonki oyun skoru da farklı bi renkle "Last Score:" olarak gözüksün.
User prompt
Oyun sonu skora (kalan saniye * 1.5) ekle kuralı kolay seviyede aynı kalsın. Orta seviyede (kalan saniye * 1.2), zor zeviyede ise direkt kalan saniye eklensin.
User prompt
(Eşleşme sayısı * 100 / hamle) + mevcut skor değeri formülü kolay seviyede aynı kalsın. Orta seviyede (Eşleşme sayısı * 150 / hamle) + mevcut skor değeri, zor seviyede ise (Eşleşme sayısı * 200 / hamle) + mevcut skor değeri olsun.
User prompt
High Score yerine Highest Score yazsın
User prompt
Şimdi oyuncunun en yüksek skor değerini kaydedelim ve sadece ana menüde görsün. ↪💡 Consider importing and using the following plugins: @upit/storage.v1
User prompt
Oyun kazanıldığında hemen bitirme. Kullanıcı zamanı sayesinde gelen puanı görsün. Ondan sonra oyunu bitir.
User prompt
Oyun sonu skora (kalan saniye * 1.5) ekle.
User prompt
Şimdi skor algoritması şöyle olacak: Skor değeri "string" değil "number" olacak. (Eşleşme sayısı * 100 / hamle) + mevcut skor değeri.
User prompt
Please fix the bug: 'Timeout.tick error: Cannot read properties of undefined (reading 'replace')' in or related to this line: 'var currentScore = parseInt(currentScoreText.replace('Score: ', '')) || 0;' Line Number: 878
User prompt
Hesaplamayı yanlış yapıyorsun. Diyelim kullanıcının puanı X, ve bir eşleşme daha bildi. Tekrardan matched pairs * 100 / moves formülünü yapıp X ile toplayıp çıkan sonucu skor olarak güncelleyeceksin.
User prompt
Please fix the bug: 'Timeout.tick error: Cannot read properties of undefined (reading 'replace')' in or related to this line: 'var existingScore = parseInt(scoreText.text.replace('Score: ', '')) || 0;' Line Number: 877
User prompt
Ama sonraki eşleşmelerde skorun üzerine ekle lütfen.
User prompt
Skor algoritması şöyle olacak: Eşleşen pair sayısı * 100 / moves
User prompt
Şimdi oyunun en alt kısmına "Score: 0" yazısı ekleyelim.
User prompt
Zor seviyenin süresi 150 saniye olsun.
User prompt
Orta seviyenin süresi 90 saniye olsun.
User prompt
Hala düzelmedi. Oyun esnasında menü butonuna basınca sağ yukarıda herhangi bir butonun kalmaması lazım!
User prompt
Bu sefer sadece menü butonu kalıyor. Düzelt.
User prompt
Oyun esnasında menüye tıklayınca menü ve restart butonları gitmiyor. Bunu düzelt.
User prompt
Kolay seviyesi butonu sarı, orta seviye butonu kırmızı, zor seviye butonu lacivert olsun.
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/****
* Classes
****/
var Card = Container.expand(function (cardType) {
var self = Container.call(this);
self.cardType = cardType;
self.isFlipped = false;
self.isMatched = false;
self.isAnimating = false;
var cardBackAsset = 'cardBack';
var cardFrontAsset = 'cardFront' + cardType;
self.backGraphics = self.attachAsset(cardBackAsset, {
anchorX: 0.5,
anchorY: 0.5
});
self.frontGraphics = self.attachAsset(cardFrontAsset, {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0
});
self.flip = function (showFront) {
if (self.isAnimating) return;
self.isAnimating = true;
// Play cardFlip sound only when showing front (opening cards), not when closing
if (showFront) {
LK.getSound('cardFlip').play();
}
// First half of flip animation - scale to 0 on X axis
tween(self, {
scaleX: 0
}, {
duration: 150,
easing: tween.easeIn,
onFinish: function onFinish() {
// Switch visibility
if (showFront) {
self.backGraphics.alpha = 0;
self.frontGraphics.alpha = 1;
self.isFlipped = true;
} else {
self.backGraphics.alpha = 1;
self.frontGraphics.alpha = 0;
self.isFlipped = false;
}
// Second half of flip animation - scale back to 1
tween(self, {
scaleX: 1
}, {
duration: 150,
easing: tween.easeOut,
onFinish: function onFinish() {
self.isAnimating = false;
}
});
}
});
};
self.setMatched = function () {
self.isMatched = true;
// Slightly fade matched cards
tween(self, {
alpha: 0.7
}, {
duration: 300
});
};
self.throwAway = function () {
if (self.isAnimating) return;
self.isAnimating = true;
// Random direction for throwing
var randomDirection = Math.random() > 0.5 ? 1 : -1;
var throwDistance = 500 + Math.random() * 300;
var targetX = self.x + randomDirection * throwDistance;
var targetY = self.y - 200 - Math.random() * 200;
// Throw animation with rotation and scaling
tween(self, {
x: targetX,
y: targetY,
rotation: randomDirection * (Math.PI + Math.random() * Math.PI),
scaleX: 0.3,
scaleY: 0.3,
alpha: 0
}, {
duration: 800,
easing: tween.easeOut,
onFinish: function onFinish() {
self.destroy();
}
});
};
self.down = function (x, y, obj) {
if (!gameStarted) return;
if (self.isAnimating || self.isFlipped || self.isMatched) return;
if (flippedCards.length >= 2) return;
self.flip(true);
flippedCards.push(self);
if (flippedCards.length === 2) {
moves++;
movesText.setText('Moves: ' + moves);
LK.setTimeout(function () {
checkMatch();
}, 1000);
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x2d3436
});
/****
* Game Code
****/
var gridRows = 3;
var gridCols = 4;
var totalPairs = gridRows * gridCols / 2;
var cards = [];
var flippedCards = [];
var matchedPairs = 0;
var moves = 0;
var wrongMatches = 0;
var wrongMatchCount = 0; // Track consecutive wrong matches
var gameStarted = false;
var selectedLevel = null;
var isFirstAttempt = true; // Track if this is the first matching attempt
var consecutiveSuccessfulMatches = 0; // Track consecutive successful matches
var totalMoveAttempts = 0; // Track total move attempts to limit special text after 3rd attempt
var gameTimer = 0; // Game timer in seconds
var maxGameTime = 0; // Maximum time allowed for current level
var timerInterval = null; // Timer interval reference
// Create UI elements
var titleText = new Text2('Memory Match', {
size: 120,
fill: 0xFFFFFF
});
titleText.anchor.set(0.5, 0);
LK.gui.top.addChild(titleText);
titleText.y = 150;
var movesText = new Text2('Moves: 0', {
size: 50,
fill: 0xFFFFFF
});
movesText.anchor.set(0.5, 0);
LK.gui.top.addChild(movesText);
movesText.y = 320;
var pairsText = new Text2('Pairs: 0/' + totalPairs, {
size: 50,
fill: 0xFFFFFF
});
pairsText.anchor.set(0.5, 0);
LK.gui.top.addChild(pairsText);
pairsText.y = 420;
var timerText = new Text2('Time: 0:00', {
size: 50,
fill: 0xFFFFFF
});
timerText.anchor.set(0.5, 0);
LK.gui.top.addChild(timerText);
timerText.y = 620;
var scoreText = new Text2('Score: 0', {
size: 50,
fill: 0xFFFFFF
});
scoreText.anchor.set(0.5, 1);
LK.gui.bottom.addChild(scoreText);
scoreText.y = -50;
// Create "What A Luck" text for first match success
var whatALuckText = new Text2('What A Luck!', {
size: 120,
fill: 0xFFD700
});
whatALuckText.anchor.set(0.5, 0.5);
whatALuckText.alpha = 0;
whatALuckText.scaleX = 0;
whatALuckText.scaleY = 0;
LK.gui.center.addChild(whatALuckText);
// Create "Play The Lotto" text for two consecutive successful matches
var playTheLotoText = new Text2('Play The Lotto!', {
size: 120,
fill: 0x00FF00
});
playTheLotoText.anchor.set(0.5, 0.5);
playTheLotoText.alpha = 0;
playTheLotoText.scaleX = 0;
playTheLotoText.scaleY = 0;
LK.gui.center.addChild(playTheLotoText);
// Hide game UI initially
movesText.alpha = 0;
pairsText.alpha = 0;
timerText.alpha = 0; // Hidden initially
scoreText.alpha = 0; // Hidden initially
// Create pause/menu button
var menuButton = LK.getAsset('menuButtonShape', {
anchorX: 0.5,
anchorY: 0.5
});
menuButton.x = 2048 - 150;
menuButton.y = 150;
menuButton.scaleX = 1.2;
menuButton.scaleY = 0.6;
menuButton.alpha = 0; // Hidden initially
game.addChild(menuButton);
var menuButtonText = new Text2('MENU', {
size: 35,
fill: 0xFFFFFF
});
menuButtonText.anchor.set(0.5, 0.5);
menuButtonText.x = menuButton.x;
menuButtonText.y = menuButton.y;
menuButtonText.alpha = 0; // Hidden initially
game.addChild(menuButtonText);
// Menu button hover handlers
menuButton.move = function () {
if (!gameStarted) return;
};
menuButton.up = function () {
if (!gameStarted) return;
};
// Menu button click handler
menuButton.down = function () {
if (!gameStarted) return;
returnToLevelSelect();
};
// Create restart button
var restartButton = LK.getAsset('restartButtonShape', {
anchorX: 0.5,
anchorY: 0.5
});
restartButton.x = 2048 - 450;
restartButton.y = 150;
restartButton.scaleX = 1.2;
restartButton.scaleY = 0.6;
restartButton.alpha = 0; // Hidden initially
game.addChild(restartButton);
var restartButtonText = new Text2('RESTART', {
size: 35,
fill: 0xFFFFFF
});
restartButtonText.anchor.set(0.5, 0.5);
restartButtonText.x = restartButton.x;
restartButtonText.y = restartButton.y;
restartButtonText.alpha = 0; // Hidden initially
game.addChild(restartButtonText);
// Restart button hover handlers
restartButton.move = function () {
if (!gameStarted) return;
};
restartButton.up = function () {
if (!gameStarted) return;
};
// Restart button click handler
restartButton.down = function () {
if (!gameStarted) return;
restartCurrentGame();
};
// Create level selection screen
var levelSelectText = new Text2('Select Difficulty', {
size: 100,
fill: 0xFFFFFF
});
levelSelectText.anchor.set(0.5, 0.5);
levelSelectText.x = 2048 / 2;
levelSelectText.y = 1000;
game.addChild(levelSelectText);
// Create high score display
var highScore = storage.highScore || 0;
var highScoreText = new Text2('Highest Score: ' + highScore, {
size: 60,
fill: 0xFFD700
});
highScoreText.anchor.set(0.5, 0.5);
highScoreText.x = 2048 / 2;
highScoreText.y = 800;
game.addChild(highScoreText);
// Create level buttons with random colors
var easyButtonColors = [0xFF6B6B, 0x4ECDC4, 0x45B7D1, 0x96CEB4, 0xFECB57, 0xFF9FF3];
var easyButtonColor = easyButtonColors[Math.floor(Math.random() * easyButtonColors.length)];
var easyButton = LK.getAsset('easyButtonShape', {
anchorX: 0.5,
anchorY: 0.5
});
easyButton.x = 2048 / 2;
easyButton.y = 1300;
game.addChild(easyButton);
var easyButtonText = new Text2('EASY', {
size: 70,
fill: 0xFFFFFF,
fontWeight: 'bolder'
});
var easyCardText = new Text2('12 Cards', {
size: 40,
fill: 0xFFFFFF
});
easyButtonText.anchor.set(0.5, 0.5);
easyButtonText.x = easyButton.x;
easyButtonText.y = easyButton.y - 40;
game.addChild(easyButtonText);
easyCardText.anchor.set(0.5, 0.5);
easyCardText.x = easyButton.x;
easyCardText.y = easyButton.y + 45;
game.addChild(easyCardText);
var mediumButtonColors = [0xFF6B6B, 0x4ECDC4, 0x45B7D1, 0x96CEB4, 0xFECB57, 0xFF9FF3];
var mediumButtonColor = mediumButtonColors[Math.floor(Math.random() * mediumButtonColors.length)];
var mediumButton = LK.getAsset('mediumButtonShape', {
anchorX: 0.5,
anchorY: 0.5
});
mediumButton.x = 2048 / 2;
mediumButton.y = 1650;
game.addChild(mediumButton);
var mediumButtonText = new Text2('MEDIUM', {
size: 70,
fill: 0xFFFFFF,
fontWeight: 'bolder'
});
var mediumCardText = new Text2('20 Cards', {
size: 40,
fill: 0xFFFFFF
});
mediumButtonText.anchor.set(0.5, 0.5);
mediumButtonText.x = mediumButton.x;
mediumButtonText.y = mediumButton.y - 40;
game.addChild(mediumButtonText);
mediumCardText.anchor.set(0.5, 0.5);
mediumCardText.x = mediumButton.x;
mediumCardText.y = mediumButton.y + 45;
game.addChild(mediumCardText);
var hardButtonColors = [0xFF6B6B, 0x4ECDC4, 0x45B7D1, 0x96CEB4, 0xFECB57, 0xFF9FF3];
var hardButtonColor = hardButtonColors[Math.floor(Math.random() * hardButtonColors.length)];
var hardButton = LK.getAsset('hardButtonShape', {
anchorX: 0.5,
anchorY: 0.5
});
hardButton.x = 2048 / 2;
hardButton.y = 2000;
game.addChild(hardButton);
var hardButtonText = new Text2('HARD', {
size: 70,
fill: 0xFFFFFF,
fontWeight: 'bolder'
});
var hardCardText = new Text2('28 Cards', {
size: 40,
fill: 0xFFFFFF
});
hardButtonText.anchor.set(0.5, 0.5);
hardButtonText.x = hardButton.x;
hardButtonText.y = hardButton.y - 40;
game.addChild(hardButtonText);
hardCardText.anchor.set(0.5, 0.5);
hardCardText.x = hardButton.x;
hardCardText.y = hardButton.y + 45;
game.addChild(hardCardText);
// Button hover handlers
var easyButtonHovered = false;
var mediumButtonHovered = false;
var hardButtonHovered = false;
var menuButtonHovered = false;
var restartButtonHovered = false;
easyButton.move = function () {
// Remove hover detection from individual button handler
};
easyButton.up = function () {
if (gameStarted) return;
};
// Button click handlers
easyButton.down = function () {
if (gameStarted) return;
startGame('easy');
};
mediumButton.move = function () {
// Remove hover detection from individual button handler
};
mediumButton.up = function () {
if (gameStarted) return;
};
mediumButton.down = function () {
if (gameStarted) return;
startGame('medium');
};
hardButton.move = function () {
// Remove hover detection from individual button handler
};
hardButton.up = function () {
if (gameStarted) return;
};
hardButton.down = function () {
if (gameStarted) return;
startGame('hard');
};
function startGame(level) {
gameStarted = true;
selectedLevel = level;
// Set grid dimensions based on level
if (level === 'easy') {
gridRows = 3;
gridCols = 4;
} else if (level === 'medium') {
gridRows = 4;
gridCols = 5;
} else if (level === 'hard') {
gridRows = 4;
gridCols = 7;
}
totalPairs = gridRows * gridCols / 2;
// Remove level selection UI from game scene
game.removeChild(levelSelectText);
game.removeChild(easyButton);
game.removeChild(easyButtonText);
game.removeChild(easyCardText);
game.removeChild(mediumButton);
game.removeChild(mediumButtonText);
game.removeChild(mediumCardText);
game.removeChild(hardButton);
game.removeChild(hardButtonText);
game.removeChild(hardCardText);
game.removeChild(highScoreText);
// Show game UI
movesText.alpha = 1;
pairsText.alpha = 1;
pairsText.setText('Pairs: 0/' + totalPairs);
timerText.alpha = 1;
scoreText.alpha = 1;
updateTimerDisplay();
// Start game timer
timerInterval = LK.setInterval(function () {
gameTimer--;
updateTimerDisplay();
if (gameTimer <= 0) {
// Time's up - show you lost
LK.clearInterval(timerInterval);
LK.showGameOver();
}
}, 1000);
// Reset first attempt flag
isFirstAttempt = true;
consecutiveSuccessfulMatches = 0;
totalMoveAttempts = 0; // Reset total move attempts
// Initialize score
LK.setScore(0);
scoreText.setText('Score: 0');
// Set timer based on difficulty level and adjust timer position
if (level === 'easy') {
maxGameTime = 45; // 45 seconds
timerText.y = 620; // Keep original position for easy
} else if (level === 'medium') {
maxGameTime = 90; // 90 seconds
timerText.y = 570; // Move timer up for medium difficulty with proper spacing
} else if (level === 'hard') {
maxGameTime = 150; // 2.5 minutes
timerText.y = 570; // Move timer up for hard difficulty with proper spacing
}
gameTimer = maxGameTime;
// Update timer display immediately after setting gameTimer
updateTimerDisplay();
// Re-add and show menu and restart buttons
game.addChild(menuButton);
game.addChild(menuButtonText);
game.addChild(restartButton);
game.addChild(restartButtonText);
menuButton.alpha = 1;
menuButtonText.alpha = 1;
restartButton.alpha = 1;
restartButtonText.alpha = 1;
// Generate card types for pairs
var cardTypes = [];
for (var i = 1; i <= totalPairs; i++) {
cardTypes.push(i);
cardTypes.push(i); // Add each type twice for pairs
}
// Shuffle the card types
cardTypes = shuffleArray(cardTypes);
// Calculate grid positioning
var originalCardWidth = 220;
var originalCardHeight = 280;
var cardWidth = 220;
var cardHeight = 280;
var cardSpacing = 50;
var scaleX = 1;
var scaleY = 1;
// Adjust card size for different levels
if (level === 'hard') {
cardWidth = 180;
cardHeight = 230;
cardSpacing = 60;
scaleX = cardWidth / originalCardWidth;
scaleY = cardHeight / originalCardHeight;
} else if (level === 'medium') {
cardWidth = 200;
cardHeight = 255;
cardSpacing = 45;
scaleX = cardWidth / originalCardWidth;
scaleY = cardHeight / originalCardHeight;
}
var gridWidth = cardWidth * gridCols + cardSpacing * (gridCols - 1);
var gridHeight = cardHeight * gridRows + cardSpacing * (gridRows - 1);
var startX = (2048 - gridWidth) / 2 + cardWidth / 2;
var startY = (2732 - gridHeight) / 2 + cardHeight / 2 + 200; // Offset for UI
// Create and position cards
var cardIndex = 0;
for (var row = 0; row < gridRows; row++) {
for (var col = 0; col < gridCols; col++) {
var card = new Card(cardTypes[cardIndex]);
card.scaleX = scaleX;
card.scaleY = scaleY;
var cardX = startX + col * (cardWidth + cardSpacing);
var cardY = startY + row * (cardHeight + cardSpacing);
card.x = cardX;
card.y = cardY;
// Set initial state for entrance animation
card.alpha = 0;
card.scaleX = 0;
card.scaleY = 0;
cards.push(card);
game.addChild(card);
// Animate card entrance with staggered timing using IIFE to capture card reference
var animationDelay = cardIndex * 80; // 80ms delay between each card
(function (currentCard, targetScaleX, targetScaleY) {
LK.setTimeout(function () {
// Animate alpha to 1 and scale to target size
tween(currentCard, {
alpha: 1,
scaleX: targetScaleX,
scaleY: targetScaleY
}, {
duration: 400,
easing: tween.easeOut
});
}, animationDelay);
})(card, scaleX, scaleY);
cardIndex++;
}
}
}
// Shuffle function
function updateTimerDisplay() {
var minutes = Math.floor(gameTimer / 60);
var seconds = gameTimer % 60;
var secondsStr = seconds < 10 ? '0' + seconds : seconds.toString();
timerText.setText('Time: ' + minutes + ':' + secondsStr);
// Change only timer text color to red when less than 10 seconds remaining and game has started
if (gameStarted && gameTimer < 10) {
timerText.tint = 0xFF0000;
// Play low timer music when entering danger zone
if (gameTimer === 9) {
LK.playMusic('lowTimerMusic');
}
// Add left-right shake animation to timer text when in danger zone
tween.stop(timerText, {
x: true
}); // Stop any existing position tweens
// Store original position if not already stored
if (!timerText.originalX) {
timerText.originalX = timerText.x;
}
tween(timerText, {
x: timerText.originalX + 20
}, {
duration: 200,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(timerText, {
x: timerText.originalX - 20
}, {
duration: 200,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(timerText, {
x: timerText.originalX
}, {
duration: 200,
easing: tween.easeInOut,
onFinish: function onFinish() {
// Restart the shake animation if still under 10 seconds
if (gameStarted && gameTimer < 10) {
updateTimerDisplay();
}
}
});
}
});
}
});
} else {
// Reset timer text to white if time is above 10 seconds
timerText.tint = 0xFFFFFF;
// Stop any shake animation and reset position
tween.stop(timerText, {
x: true
});
if (timerText.originalX) {
timerText.x = timerText.originalX;
}
}
}
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;
}
function returnToLevelSelect() {
// Reset game state
gameStarted = false;
selectedLevel = null;
moves = 0;
wrongMatches = 0;
wrongMatchCount = 0; // Reset consecutive wrong match counter
matchedPairs = 0;
flippedCards = [];
isFirstAttempt = true;
consecutiveSuccessfulMatches = 0;
totalMoveAttempts = 0; // Reset total move attempts
// Reset score
LK.setScore(0);
// Clear timer
if (timerInterval) {
LK.clearInterval(timerInterval);
timerInterval = null;
}
gameTimer = 0;
// Stop low timer music when returning to level select
LK.stopMusic();
// Clear all cards
for (var i = cards.length - 1; i >= 0; i--) {
cards[i].destroy();
}
cards = [];
// Hide game UI
movesText.alpha = 0;
pairsText.alpha = 0;
timerText.alpha = 0;
scoreText.alpha = 0;
// Hide menu and restart buttons completely
menuButton.alpha = 0;
menuButtonText.alpha = 0;
restartButton.alpha = 0;
restartButtonText.alpha = 0;
// Also remove them from the game to ensure they don't interfere
game.removeChild(menuButton);
game.removeChild(menuButtonText);
game.removeChild(restartButton);
game.removeChild(restartButtonText);
// Re-add and show level selection UI
game.addChild(levelSelectText);
game.addChild(easyButton);
game.addChild(easyButtonText);
game.addChild(easyCardText);
game.addChild(mediumButton);
game.addChild(mediumButtonText);
game.addChild(mediumCardText);
game.addChild(hardButton);
game.addChild(hardButtonText);
game.addChild(hardCardText);
game.addChild(highScoreText);
levelSelectText.alpha = 1;
easyButton.alpha = 1;
easyButtonText.alpha = 1;
easyCardText.alpha = 1;
mediumButton.alpha = 1;
mediumButtonText.alpha = 1;
mediumCardText.alpha = 1;
hardButton.alpha = 1;
hardButtonText.alpha = 1;
hardCardText.alpha = 1;
highScoreText.alpha = 1;
// Update high score display
var currentHighScore = storage.highScore || 0;
highScoreText.setText('Highest Score: ' + currentHighScore);
}
function restartCurrentGame() {
if (!selectedLevel) return;
// Clear current game
for (var i = cards.length - 1; i >= 0; i--) {
cards[i].destroy();
}
cards = [];
// Reset game variables
moves = 0;
wrongMatches = 0;
wrongMatchCount = 0; // Reset consecutive wrong match counter
matchedPairs = 0;
flippedCards = [];
isFirstAttempt = true;
consecutiveSuccessfulMatches = 0;
totalMoveAttempts = 0; // Reset total move attempts
// Reset score
LK.setScore(0);
// Clear existing timer
if (timerInterval) {
LK.clearInterval(timerInterval);
timerInterval = null;
}
gameTimer = 0;
// Stop low timer music when restarting
LK.stopMusic();
movesText.setText('Moves: 0');
// Restart with same level
var levelToRestart = selectedLevel;
gameStarted = false; // Temporarily set to false for startGame function
startGame(levelToRestart);
}
function checkMatch() {
if (flippedCards.length !== 2) return;
var card1 = flippedCards[0];
var card2 = flippedCards[1];
totalMoveAttempts++; // Increment total move attempts
if (card1.cardType === card2.cardType) {
// Match found
wrongMatchCount = 0;
consecutiveSuccessfulMatches++;
// Calculate and update score with difficulty-based multiplier: (matches * multiplier / moves) + current score
var currentScore = LK.getScore();
var multiplier = 100; // Default for easy
if (selectedLevel === 'medium') {
multiplier = 150;
} else if (selectedLevel === 'hard') {
multiplier = 200;
}
var newScore = currentScore + Math.round((matchedPairs + 1) * multiplier / moves);
LK.setScore(newScore);
scoreText.setText('Score: ' + newScore);
// Show special text based on consecutive successful matches (only for first 2 attempts)
if (consecutiveSuccessfulMatches === 2 && totalMoveAttempts <= 2) {
// Show "Play The Lotto" for two consecutive successful matches
// Dim all cards when Play The Loto appears
for (var i = 0; i < cards.length; i++) {
if (!cards[i].isMatched) {
tween(cards[i], {
alpha: 0.3
}, {
duration: 300,
easing: tween.easeOut
});
}
}
// Animate the "Play The Lotto" text
tween(playTheLotoText, {
alpha: 1,
scaleX: 1.2,
scaleY: 1.2
}, {
duration: 600,
easing: tween.bounceOut,
onFinish: function onFinish() {
// Hold for a moment then fade out
LK.setTimeout(function () {
tween(playTheLotoText, {
alpha: 0,
scaleX: 0,
scaleY: 0
}, {
duration: 400,
easing: tween.easeIn,
onFinish: function onFinish() {
// Restore card alpha when Play The Lotto animation finishes
for (var i = 0; i < cards.length; i++) {
if (!cards[i].isMatched) {
tween(cards[i], {
alpha: 1
}, {
duration: 300,
easing: tween.easeOut
});
}
}
}
});
}, 1000);
}
});
} else if (isFirstAttempt && totalMoveAttempts <= 2) {
// Show "What A Luck" if this is the first attempt
// Dim all cards when What A Luck appears
for (var i = 0; i < cards.length; i++) {
if (!cards[i].isMatched) {
tween(cards[i], {
alpha: 0.3
}, {
duration: 300,
easing: tween.easeOut
});
}
}
// Animate the "What A Luck" text
tween(whatALuckText, {
alpha: 1,
scaleX: 1.2,
scaleY: 1.2
}, {
duration: 600,
easing: tween.bounceOut,
onFinish: function onFinish() {
// Hold for a moment then fade out
LK.setTimeout(function () {
tween(whatALuckText, {
alpha: 0,
scaleX: 0,
scaleY: 0
}, {
duration: 400,
easing: tween.easeIn,
onFinish: function onFinish() {
// Restore card alpha when What A Luck animation finishes
for (var i = 0; i < cards.length; i++) {
if (!cards[i].isMatched) {
tween(cards[i], {
alpha: 1
}, {
duration: 300,
easing: tween.easeOut
});
}
}
}
});
}, 1000);
}
});
}
LK.getSound('match').play();
// Throw away matched cards with animation
LK.setTimeout(function () {
card1.throwAway();
card2.throwAway();
}, 300);
matchedPairs++;
pairsText.setText('Pairs: ' + matchedPairs + '/' + totalPairs);
// Check for win condition
if (matchedPairs === totalPairs) {
// Clear timer when game is won
if (timerInterval) {
LK.clearInterval(timerInterval);
timerInterval = null;
}
// Stop low timer music when game is won
LK.stopMusic();
// Add end-of-game bonus with difficulty-based multiplier
var timeBonusMultiplier = 1.5; // Default for easy
if (selectedLevel === 'medium') {
timeBonusMultiplier = 1.2;
} else if (selectedLevel === 'hard') {
timeBonusMultiplier = 1;
}
var timeBonus = Math.round(gameTimer * timeBonusMultiplier);
var currentScore = LK.getScore();
var finalScore = currentScore + timeBonus;
LK.setScore(finalScore);
// Check and update high score
var currentHighScore = storage.highScore || 0;
if (finalScore > currentHighScore) {
storage.highScore = finalScore;
}
// Create and show time bonus text
var timeBonusText = new Text2('Time Bonus: +' + timeBonus, {
size: 80,
fill: 0x00FF00
});
timeBonusText.anchor.set(0.5, 0.5);
timeBonusText.alpha = 0;
timeBonusText.scaleX = 0;
timeBonusText.scaleY = 0;
LK.gui.center.addChild(timeBonusText);
// Animate the time bonus text
tween(timeBonusText, {
alpha: 1,
scaleX: 1.2,
scaleY: 1.2
}, {
duration: 600,
easing: tween.bounceOut,
onFinish: function onFinish() {
// Update score display after showing bonus
scoreText.setText('Score: ' + finalScore);
// Hold for a moment then show you win
LK.setTimeout(function () {
LK.showYouWin();
}, 1500);
}
});
}
} else {
// No match - reset consecutive successful matches
consecutiveSuccessfulMatches = 0;
LK.getSound('noMatch').play();
// Increment consecutive wrong matches
wrongMatchCount++;
card1.flip(false);
card2.flip(false);
}
flippedCards = [];
// After any match attempt (successful or not), it's no longer the first attempt
isFirstAttempt = false;
}
// Global move handler to detect cursor over buttons
game.move = function (x, y, obj) {
if (gameStarted) {
// Check if cursor is over menu button
var isOverMenuButton = x >= menuButton.x - menuButton.width * menuButton.scaleX / 2 && x <= menuButton.x + menuButton.width * menuButton.scaleX / 2 && y >= menuButton.y - menuButton.height * menuButton.scaleY / 2 && y <= menuButton.y + menuButton.height * menuButton.scaleY / 2;
// Handle menu button hover enter
if (!menuButtonHovered && isOverMenuButton) {
menuButtonHovered = true;
// Animate opacity to 0.5 when hovering
tween(menuButton, {
alpha: 0.5
}, {
duration: 200,
easing: tween.easeOut
});
}
// Handle menu button hover leave
if (menuButtonHovered && !isOverMenuButton) {
menuButtonHovered = false;
// Animate opacity back to 1 when leaving hover
tween(menuButton, {
alpha: 1
}, {
duration: 200,
easing: tween.easeOut
});
}
// Check if cursor is over restart button
var isOverRestartButton = x >= restartButton.x - restartButton.width * restartButton.scaleX / 2 && x <= restartButton.x + restartButton.width * restartButton.scaleX / 2 && y >= restartButton.y - restartButton.height * restartButton.scaleY / 2 && y <= restartButton.y + restartButton.height * restartButton.scaleY / 2;
// Handle restart button hover enter
if (!restartButtonHovered && isOverRestartButton) {
restartButtonHovered = true;
// Animate opacity to 0.5 when hovering
tween(restartButton, {
alpha: 0.5
}, {
duration: 200,
easing: tween.easeOut
});
}
// Handle restart button hover leave
if (restartButtonHovered && !isOverRestartButton) {
restartButtonHovered = false;
// Animate opacity back to 1 when leaving hover
tween(restartButton, {
alpha: 1
}, {
duration: 200,
easing: tween.easeOut
});
}
return;
}
// Check if cursor is over easy button
var isOverEasyButton = x >= easyButton.x - easyButton.width * easyButton.scaleX / 2 && x <= easyButton.x + easyButton.width * easyButton.scaleX / 2 && y >= easyButton.y - easyButton.height * easyButton.scaleY / 2 && y <= easyButton.y + easyButton.height * easyButton.scaleY / 2;
// Handle easy button hover enter
if (!easyButtonHovered && isOverEasyButton) {
easyButtonHovered = true;
// Animate opacity to 0.5 when hovering
tween(easyButton, {
alpha: 0.5
}, {
duration: 200,
easing: tween.easeOut
});
}
// Handle easy button hover leave
if (easyButtonHovered && !isOverEasyButton) {
easyButtonHovered = false;
// Animate opacity back to 1 when leaving hover
tween(easyButton, {
alpha: 1
}, {
duration: 200,
easing: tween.easeOut
});
}
// Check if cursor is over medium button
var isOverMediumButton = x >= mediumButton.x - mediumButton.width * mediumButton.scaleX / 2 && x <= mediumButton.x + mediumButton.width * mediumButton.scaleX / 2 && y >= mediumButton.y - mediumButton.height * mediumButton.scaleY / 2 && y <= mediumButton.y + mediumButton.height * mediumButton.scaleY / 2;
// Handle medium button hover enter
if (!mediumButtonHovered && isOverMediumButton) {
mediumButtonHovered = true;
// Animate opacity to 0.5 when hovering
tween(mediumButton, {
alpha: 0.5
}, {
duration: 200,
easing: tween.easeOut
});
}
// Handle medium button hover leave
if (mediumButtonHovered && !isOverMediumButton) {
mediumButtonHovered = false;
// Animate opacity back to 1 when leaving hover
tween(mediumButton, {
alpha: 1
}, {
duration: 200,
easing: tween.easeOut
});
}
// Check if cursor is over hard button
var isOverHardButton = x >= hardButton.x - hardButton.width * hardButton.scaleX / 2 && x <= hardButton.x + hardButton.width * hardButton.scaleX / 2 && y >= hardButton.y - hardButton.height * hardButton.scaleY / 2 && y <= hardButton.y + hardButton.height * hardButton.scaleY / 2;
// Handle hard button hover enter
if (!hardButtonHovered && isOverHardButton) {
hardButtonHovered = true;
// Animate opacity to 0.5 when hovering
tween(hardButton, {
alpha: 0.5
}, {
duration: 200,
easing: tween.easeOut
});
}
// Handle hard button hover leave
if (hardButtonHovered && !isOverHardButton) {
hardButtonHovered = false;
// Animate opacity back to 1 when leaving hover
tween(hardButton, {
alpha: 1
}, {
duration: 200,
easing: tween.easeOut
});
}
};
game.update = function () {
// Game logic is handled by card interactions and timeouts
}; ===================================================================
--- original.js
+++ change.js
@@ -847,10 +847,16 @@
timerInterval = null;
}
// Stop low timer music when game is won
LK.stopMusic();
- // Add end-of-game bonus: remaining time * 1.5
- var timeBonus = Math.round(gameTimer * 1.5);
+ // Add end-of-game bonus with difficulty-based multiplier
+ var timeBonusMultiplier = 1.5; // Default for easy
+ if (selectedLevel === 'medium') {
+ timeBonusMultiplier = 1.2;
+ } else if (selectedLevel === 'hard') {
+ timeBonusMultiplier = 1;
+ }
+ var timeBonus = Math.round(gameTimer * timeBonusMultiplier);
var currentScore = LK.getScore();
var finalScore = currentScore + timeBonus;
LK.setScore(finalScore);
// Check and update high score
Modern App Store icon, high definition, square with rounded corners, for a game titled "Memory Match Cards" and with the description "A classic memory card game where players flip cards to find matching pairs. Tap cards to reveal them and match identical pairs to clear the board.". No text on icon!
Cute elephant. In-Game asset. 2d. High contrast. No shadows
Cute tiger. In-Game asset. 2d. High contrast. No shadows
Cute dog. In-Game asset. 2d. High contrast. No shadows
Cute cat. In-Game asset. 2d. High contrast. No shadows
Cute snake. In-Game asset. 2d. High contrast. No shadows
Cute giraffe. In-Game asset. 2d. High contrast. No shadows
Cute zebra. In-Game asset. 2d. High contrast. No shadows
cute monkey. In-Game asset. 2d. High contrast. No shadows
cute honey badger. In-Game asset. 2d. High contrast. No shadows
cute koala. In-Game asset. 2d. High contrast. No shadows
cute bear. In-Game asset. 2d. High contrast. No shadows
cute panda. In-Game asset. 2d. High contrast. No shadows
cute eagle. In-Game asset. 2d. High contrast. No shadows
cute lion. In-Game asset. 2d. High contrast. No shadows