/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1", {
highScore: 9999
});
/****
* Classes
****/
// Hafıza kartı sınıfı
var MemoryCard = Container.expand(function () {
var self = Container.call(this);
// Özellikler
self.cardIndex = 0; // 0-7 arası, kart tipi
self.isFlipped = false;
self.isMatched = false;
// Kartın ön yüzü (renkli)
self.front = self.attachAsset('card0', {
anchorX: 0.5,
anchorY: 0.5
});
// Kartın arka yüzü (gri)
self.back = self.attachAsset('cardBack', {
anchorX: 0.5,
anchorY: 0.5
});
self.front.visible = false;
self.back.visible = true;
// Kartı başlat
self.setCardIndex = function (idx) {
self.cardIndex = idx;
self.front.destroy();
self.front = self.attachAsset('card' + idx, {
anchorX: 0.5,
anchorY: 0.5
});
self.front.visible = self.isFlipped;
self.back.visible = !self.isFlipped;
};
// Kartı çevir (aç/kapat)
self.flip = function (showFront, animate, _onFinish) {
if (self.isMatched) return;
if (self.isFlipped === showFront) return;
self.isFlipped = showFront;
if (animate) {
// Flip animasyonu: önce daralt, sonra diğer yüzü gösterip genişlet
tween(self, {
scaleX: 0
}, {
duration: 120,
easing: tween.cubicIn,
onFinish: function onFinish() {
self.front.visible = showFront;
self.back.visible = !showFront;
tween(self, {
scaleX: 1
}, {
duration: 120,
easing: tween.cubicOut,
onFinish: _onFinish
});
}
});
} else {
self.front.visible = showFront;
self.back.visible = !showFront;
self.scaleX = 1;
if (_onFinish) _onFinish();
}
};
// Eşleşme animasyonu
self.playMatchEffect = function (_onFinish2) {
var effect = self.addChild(LK.getAsset('matchEffect', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0.5
}));
effect.scaleX = effect.scaleY = 0.2;
tween(effect, {
scaleX: 1.2,
scaleY: 1.2,
alpha: 0
}, {
duration: 350,
easing: tween.easeOut,
onFinish: function onFinish() {
effect.destroy();
if (_onFinish2) _onFinish2();
}
});
};
// Kart tıklama
self.down = function (x, y, obj) {
if (self.isMatched || self.isFlipped) return;
if (game.locked) return;
game.onCardClicked(self);
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x222222
});
/****
* Game Code
****/
// Oyun parametreleri
// Kartlar için farklı renklerde kutular (8 farklı renk, 16 kartlık bir seviye için yeterli)
// Kartların arka yüzü (gri)
// Eşleşme animasyonu için
// Ses efektleri
// Müzik (isteğe bağlı, başlatılmayacak)
// Infinite level config generator
function _typeof(o) {
"@babel/helpers - typeof";
return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) {
return typeof o;
} : function (o) {
return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o;
}, _typeof(o);
}
function getLevelConfig(lvl) {
// Start easy, then increase grid size and pair count
// Level 0: 2x2, Level 1: 2x4, Level 2: 3x4, Level 3: 4x4, Level 4: 4x5, Level 5: 4x6, Level 6: 5x6, Level 7: 6x6, then keep growing
// Her levelde kart sayısı artsın: 2x2, 2x4, 3x4, 4x4, 4x5, 4x6, 5x6, 6x6, 6x7, 7x7, 7x8, 8x8, ...
var baseConfigs = [{
rows: 2,
cols: 2
}, {
rows: 2,
cols: 4
}, {
rows: 3,
cols: 4
}, {
rows: 4,
cols: 4
}, {
rows: 4,
cols: 5
}, {
rows: 4,
cols: 6
}, {
rows: 5,
cols: 6
}, {
rows: 6,
cols: 6
}];
if (lvl < baseConfigs.length) {
return baseConfigs[lvl];
}
// 8x8'e kadar büyüt, sonra 8x8'de kal
var maxRows = 8,
maxCols = 8;
var growStep = lvl - (baseConfigs.length - 1);
// Her iki levelde bir satır veya sütun ekle
var rows = 6 + Math.floor(growStep / 2);
var cols = 6 + Math.ceil(growStep / 2);
rows = Math.min(rows, maxRows);
cols = Math.min(cols, maxCols);
// Kart sayısı çift olmalı
if (rows * cols % 2 !== 0) {
if (cols < maxCols) {
cols += 1;
} else if (rows < maxRows) {
rows += 1;
}
}
// Son kontrol: max sınırı aşmasın
rows = Math.min(rows, maxRows);
cols = Math.min(cols, maxCols);
return {
rows: rows,
cols: cols
};
}
// Oyun değişkenleri
var cards = [];
var flippedCards = [];
var matchedCount = 0;
var moves = 0;
var level = 0;
var locked = false;
var highScore = storage.highScore || 9999;
// Her level için can/hak sayısı: Seviye arttıkça artar, ama zorluğu bozmadan.
// Kolaydan zora: Başlangıçta az, sonra yavaşça artar, ama asla çok yüksek olmaz.
// Temel mantık: minimum 3, maksimum 2*pairCount veya 20 (hangisi küçükse)
function getLivesForLevel(lvl) {
var cfg = getLevelConfig(lvl);
var totalCards = cfg.rows * cfg.cols;
var pairCount = totalCards / 2;
// Ekranda görülen kart sayısından 3 fazla hak ver
var lives = totalCards + 3;
// Maksimum: 2*pairCount veya 30 (hangisi küçükse)
if (lives > 2 * pairCount) lives = 2 * pairCount;
if (lives > 30) lives = 30;
return lives;
}
var lives = 0;
var carryOverLives = 0; // Bir sonraki levele aktarılacak kalan haklar
// GUI elemanları
var movesText = new Text2('Moves: 0', {
size: 90,
fill: '#fff'
});
movesText.anchor.set(0.5, 0);
movesText.y = 80; // Move the moves text further down from the top
LK.gui.top.addChild(movesText);
var livesText = new Text2('Lives: --', {
size: 70,
fill: '#ff4d4d'
});
livesText.anchor.set(0.5, 0);
livesText.y = 180; // Moves'ın biraz altında
LK.gui.top.addChild(livesText);
var levelText = new Text2('Level: 1', {
size: 70,
fill: '#fff'
});
levelText.anchor.set(0.5, 0);
LK.gui.top.addChild(levelText);
var highScoreText = new Text2('Best: --', {
size: 60,
fill: '#FFD700'
});
highScoreText.anchor.set(1, 0);
LK.gui.topRight.addChild(highScoreText);
// Oyun kilitli mi? (kartlar animasyon sırasında tıklanamaz)
game.locked = false;
// Basit, sade ve geçişli arka plan renkleri üretici
function getBackgroundColorForLevel(lvl) {
// Renkler: pastel ve sade, HSV üzerinden döndürülerek
// Hue: 180-360 arası döngü, Saturation: 0.25-0.45, Value: 0.92-0.98
var hue = 180 + lvl * 37 % 180; // 180-360 arası
var sat = 0.25 + lvl * 13 % 20 / 100; // 0.25-0.45
var val = 0.92 - lvl * 7 % 7 / 100; // 0.92-0.86
// HSV to RGB
var c = val * sat;
var x = c * (1 - Math.abs(hue / 60 % 2 - 1));
var m = val - c;
var r = 0,
g = 0,
b = 0;
if (hue < 60) {
r = c;
g = x;
b = 0;
} else if (hue < 120) {
r = x;
g = c;
b = 0;
} else if (hue < 180) {
r = 0;
g = c;
b = x;
} else if (hue < 240) {
r = 0;
g = x;
b = c;
} else if (hue < 300) {
r = x;
g = 0;
b = c;
} else {
r = c;
g = 0;
b = x;
}
var rr = Math.round((r + m) * 255);
var gg = Math.round((g + m) * 255);
var bb = Math.round((b + m) * 255);
return rr << 16 | gg << 8 | bb;
}
// Oyun başlat
function startGame(startLevel) {
// Temizle
for (var i = 0; i < cards.length; ++i) cards[i].destroy();
cards = [];
flippedCards = [];
matchedCount = 0;
moves = 0;
level = startLevel || 0;
// Her levelde sade, geçişli yeni bir arka plan rengi uygula
game.setBackgroundColor(getBackgroundColorForLevel(level));
game.locked = false;
locked = false;
// Can/hak sayısını başlat
lives = getLivesForLevel(level);
// Eğer önceki levelden kalan hak varsa, üstüne ekle
if (typeof carryOverLives === "number" && carryOverLives > 0) {
lives += carryOverLives;
// Maksimum limiti aşmasın
var maxLives = getLivesForLevel(level);
if (lives > maxLives) lives = maxLives;
carryOverLives = 0;
}
// Update GUI
movesText.setText('Moves: 0');
levelText.setText('Level: ' + (level + 1));
livesText.setText('Lives: ' + lives);
highScore = storage.highScore || 9999;
highScoreText.setText('Best: ' + (highScore === 9999 ? '--' : highScore));
// Kartları oluştur
createLevel(level);
}
// Seviye oluştur
function createLevel(lvl) {
var cfg = getLevelConfig(lvl);
var totalCards = cfg.rows * cfg.cols;
var pairCount = totalCards / 2;
// Kart tiplerini seç (döngüyle 0-7 arası, fazlası için tekrar)
var cardTypes = [];
for (var i = 0; i < pairCount; ++i) cardTypes.push(i % 8);
var allTypes = cardTypes.concat(cardTypes); // Çiftler
// Karıştır
for (var i = allTypes.length - 1; i > 0; --i) {
var j = Math.floor(Math.random() * (i + 1));
var tmp = allTypes[i];
allTypes[i] = allTypes[j];
allTypes[j] = tmp;
}
// Izgara boyutları
var gridW = cfg.cols * 300;
var gridH = cfg.rows * 380;
var startX = (2048 - gridW) / 2 + 150;
var startY = (2732 - gridH) / 2 + 120;
// Kartları yerleştir
for (var r = 0; r < cfg.rows; ++r) {
for (var c = 0; c < cfg.cols; ++c) {
var idx = r * cfg.cols + c;
var card = new MemoryCard();
card.setCardIndex(allTypes[idx]);
card.x = startX + c * 300;
card.y = startY + r * 380;
card.scaleX = card.scaleY = 1;
card.isFlipped = false;
card.isMatched = false;
card.front.visible = false;
card.back.visible = true;
cards.push(card);
game.addChild(card);
}
}
}
// Kart tıklama işlemi
game.onCardClicked = function (card) {
if (locked) return;
if (card.isFlipped || card.isMatched) return;
if (flippedCards.length >= 2) return;
locked = true;
game.locked = true;
card.flip(true, true, function () {
LK.getSound('flip').play();
flippedCards.push(card);
if (flippedCards.length === 2) {
moves++;
movesText.setText('Moves: ' + moves);
// Eşleşme kontrolü
if (flippedCards[0].cardIndex === flippedCards[1].cardIndex) {
// Eşleşti
flippedCards[0].isMatched = true;
flippedCards[1].isMatched = true;
LK.getSound('match').play();
flippedCards[0].playMatchEffect();
// Particle effect: spawn particles at both matched cards
if (_typeof(LK.effects) === "object" && typeof LK.effects.particles === "function") {
// Use a simple burst of yellow-white particles
LK.effects.particles({
x: flippedCards[0].x,
y: flippedCards[0].y,
count: 18,
color: 0xffff99,
speed: 7,
life: 420,
size: 32,
spread: Math.PI * 2,
gravity: 0.12
}, flippedCards[0].parent);
LK.effects.particles({
x: flippedCards[1].x,
y: flippedCards[1].y,
count: 18,
color: 0xffff99,
speed: 7,
life: 420,
size: 32,
spread: Math.PI * 2,
gravity: 0.12
}, flippedCards[1].parent);
}
flippedCards[1].playMatchEffect(function () {
// Emoji ve tebrik mesajı göster
var congratsText = new Text2('🎉 Bravo! Eşleşme! 🎉', {
size: 120,
fill: '#ffe066',
font: "Arial"
});
congratsText.anchor.set(0.5, 0.5);
congratsText.x = 2048 / 2;
congratsText.y = 2732 / 2 - 100;
LK.gui.center.addChild(congratsText);
// Emoji animasyonu (yukarıdan aşağıya zıplat)
congratsText.alpha = 0;
congratsText.scaleX = congratsText.scaleY = 0.7;
tween(congratsText, {
alpha: 1,
scaleX: 1.1,
scaleY: 1.1
}, {
duration: 180,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(congratsText, {
scaleX: 1,
scaleY: 1
}, {
duration: 120,
onFinish: function onFinish() {
// Biraz beklet, sonra kaybolsun
LK.setTimeout(function () {
tween(congratsText, {
alpha: 0
}, {
duration: 350,
onFinish: function onFinish() {
congratsText.destroy();
}
});
}, 700);
}
});
}
});
flippedCards = [];
matchedCount += 2;
locked = false;
game.locked = false;
// Seviye bitti mi?
if (matchedCount === cards.length) {
// Kalan hakları bir sonraki levele aktar
carryOverLives = lives;
LK.getSound('levelup').play();
LK.effects.flashScreen(0x00FF00, 600);
LK.setTimeout(function () {
// Sonsuz seviye: Her zaman bir sonraki seviyeye geç
level++;
startGame(level);
}, 900);
}
});
} else {
// Eşleşmedi
LK.getSound('fail').play();
// Canı azalt
lives--;
livesText.setText('Lives: ' + lives);
// Oyun bitti mi?
if (lives <= 0) {
// Kartları kapatmadan önce kısa bir bekleme
LK.setTimeout(function () {
// Tüm kartları kapat
flippedCards[0].flip(false, true);
flippedCards[1].flip(false, true, function () {
flippedCards = [];
locked = true;
game.locked = true;
// Kırmızı ekran efekti
LK.effects.flashScreen(0xFF0000, 800);
// Skoru güncelle
if (moves < highScore) {
storage.highScore = moves;
}
// Oyun bitti popup
LK.setTimeout(function () {
LK.showGameOver();
}, 900);
});
}, 650);
} else {
LK.setTimeout(function () {
flippedCards[0].flip(false, true);
flippedCards[1].flip(false, true, function () {
flippedCards = [];
locked = false;
game.locked = false;
});
}, 650);
}
}
} else {
locked = false;
game.locked = false;
}
});
};
// Oyun güncellemesi (gerekmiyor ama ileride animasyonlar için kullanılabilir)
game.update = function () {
// Boş
};
// Oyun başlat
startGame(0); /****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1", {
highScore: 9999
});
/****
* Classes
****/
// Hafıza kartı sınıfı
var MemoryCard = Container.expand(function () {
var self = Container.call(this);
// Özellikler
self.cardIndex = 0; // 0-7 arası, kart tipi
self.isFlipped = false;
self.isMatched = false;
// Kartın ön yüzü (renkli)
self.front = self.attachAsset('card0', {
anchorX: 0.5,
anchorY: 0.5
});
// Kartın arka yüzü (gri)
self.back = self.attachAsset('cardBack', {
anchorX: 0.5,
anchorY: 0.5
});
self.front.visible = false;
self.back.visible = true;
// Kartı başlat
self.setCardIndex = function (idx) {
self.cardIndex = idx;
self.front.destroy();
self.front = self.attachAsset('card' + idx, {
anchorX: 0.5,
anchorY: 0.5
});
self.front.visible = self.isFlipped;
self.back.visible = !self.isFlipped;
};
// Kartı çevir (aç/kapat)
self.flip = function (showFront, animate, _onFinish) {
if (self.isMatched) return;
if (self.isFlipped === showFront) return;
self.isFlipped = showFront;
if (animate) {
// Flip animasyonu: önce daralt, sonra diğer yüzü gösterip genişlet
tween(self, {
scaleX: 0
}, {
duration: 120,
easing: tween.cubicIn,
onFinish: function onFinish() {
self.front.visible = showFront;
self.back.visible = !showFront;
tween(self, {
scaleX: 1
}, {
duration: 120,
easing: tween.cubicOut,
onFinish: _onFinish
});
}
});
} else {
self.front.visible = showFront;
self.back.visible = !showFront;
self.scaleX = 1;
if (_onFinish) _onFinish();
}
};
// Eşleşme animasyonu
self.playMatchEffect = function (_onFinish2) {
var effect = self.addChild(LK.getAsset('matchEffect', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0.5
}));
effect.scaleX = effect.scaleY = 0.2;
tween(effect, {
scaleX: 1.2,
scaleY: 1.2,
alpha: 0
}, {
duration: 350,
easing: tween.easeOut,
onFinish: function onFinish() {
effect.destroy();
if (_onFinish2) _onFinish2();
}
});
};
// Kart tıklama
self.down = function (x, y, obj) {
if (self.isMatched || self.isFlipped) return;
if (game.locked) return;
game.onCardClicked(self);
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x222222
});
/****
* Game Code
****/
// Oyun parametreleri
// Kartlar için farklı renklerde kutular (8 farklı renk, 16 kartlık bir seviye için yeterli)
// Kartların arka yüzü (gri)
// Eşleşme animasyonu için
// Ses efektleri
// Müzik (isteğe bağlı, başlatılmayacak)
// Infinite level config generator
function _typeof(o) {
"@babel/helpers - typeof";
return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) {
return typeof o;
} : function (o) {
return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o;
}, _typeof(o);
}
function getLevelConfig(lvl) {
// Start easy, then increase grid size and pair count
// Level 0: 2x2, Level 1: 2x4, Level 2: 3x4, Level 3: 4x4, Level 4: 4x5, Level 5: 4x6, Level 6: 5x6, Level 7: 6x6, then keep growing
// Her levelde kart sayısı artsın: 2x2, 2x4, 3x4, 4x4, 4x5, 4x6, 5x6, 6x6, 6x7, 7x7, 7x8, 8x8, ...
var baseConfigs = [{
rows: 2,
cols: 2
}, {
rows: 2,
cols: 4
}, {
rows: 3,
cols: 4
}, {
rows: 4,
cols: 4
}, {
rows: 4,
cols: 5
}, {
rows: 4,
cols: 6
}, {
rows: 5,
cols: 6
}, {
rows: 6,
cols: 6
}];
if (lvl < baseConfigs.length) {
return baseConfigs[lvl];
}
// 8x8'e kadar büyüt, sonra 8x8'de kal
var maxRows = 8,
maxCols = 8;
var growStep = lvl - (baseConfigs.length - 1);
// Her iki levelde bir satır veya sütun ekle
var rows = 6 + Math.floor(growStep / 2);
var cols = 6 + Math.ceil(growStep / 2);
rows = Math.min(rows, maxRows);
cols = Math.min(cols, maxCols);
// Kart sayısı çift olmalı
if (rows * cols % 2 !== 0) {
if (cols < maxCols) {
cols += 1;
} else if (rows < maxRows) {
rows += 1;
}
}
// Son kontrol: max sınırı aşmasın
rows = Math.min(rows, maxRows);
cols = Math.min(cols, maxCols);
return {
rows: rows,
cols: cols
};
}
// Oyun değişkenleri
var cards = [];
var flippedCards = [];
var matchedCount = 0;
var moves = 0;
var level = 0;
var locked = false;
var highScore = storage.highScore || 9999;
// Her level için can/hak sayısı: Seviye arttıkça artar, ama zorluğu bozmadan.
// Kolaydan zora: Başlangıçta az, sonra yavaşça artar, ama asla çok yüksek olmaz.
// Temel mantık: minimum 3, maksimum 2*pairCount veya 20 (hangisi küçükse)
function getLivesForLevel(lvl) {
var cfg = getLevelConfig(lvl);
var totalCards = cfg.rows * cfg.cols;
var pairCount = totalCards / 2;
// Ekranda görülen kart sayısından 3 fazla hak ver
var lives = totalCards + 3;
// Maksimum: 2*pairCount veya 30 (hangisi küçükse)
if (lives > 2 * pairCount) lives = 2 * pairCount;
if (lives > 30) lives = 30;
return lives;
}
var lives = 0;
var carryOverLives = 0; // Bir sonraki levele aktarılacak kalan haklar
// GUI elemanları
var movesText = new Text2('Moves: 0', {
size: 90,
fill: '#fff'
});
movesText.anchor.set(0.5, 0);
movesText.y = 80; // Move the moves text further down from the top
LK.gui.top.addChild(movesText);
var livesText = new Text2('Lives: --', {
size: 70,
fill: '#ff4d4d'
});
livesText.anchor.set(0.5, 0);
livesText.y = 180; // Moves'ın biraz altında
LK.gui.top.addChild(livesText);
var levelText = new Text2('Level: 1', {
size: 70,
fill: '#fff'
});
levelText.anchor.set(0.5, 0);
LK.gui.top.addChild(levelText);
var highScoreText = new Text2('Best: --', {
size: 60,
fill: '#FFD700'
});
highScoreText.anchor.set(1, 0);
LK.gui.topRight.addChild(highScoreText);
// Oyun kilitli mi? (kartlar animasyon sırasında tıklanamaz)
game.locked = false;
// Basit, sade ve geçişli arka plan renkleri üretici
function getBackgroundColorForLevel(lvl) {
// Renkler: pastel ve sade, HSV üzerinden döndürülerek
// Hue: 180-360 arası döngü, Saturation: 0.25-0.45, Value: 0.92-0.98
var hue = 180 + lvl * 37 % 180; // 180-360 arası
var sat = 0.25 + lvl * 13 % 20 / 100; // 0.25-0.45
var val = 0.92 - lvl * 7 % 7 / 100; // 0.92-0.86
// HSV to RGB
var c = val * sat;
var x = c * (1 - Math.abs(hue / 60 % 2 - 1));
var m = val - c;
var r = 0,
g = 0,
b = 0;
if (hue < 60) {
r = c;
g = x;
b = 0;
} else if (hue < 120) {
r = x;
g = c;
b = 0;
} else if (hue < 180) {
r = 0;
g = c;
b = x;
} else if (hue < 240) {
r = 0;
g = x;
b = c;
} else if (hue < 300) {
r = x;
g = 0;
b = c;
} else {
r = c;
g = 0;
b = x;
}
var rr = Math.round((r + m) * 255);
var gg = Math.round((g + m) * 255);
var bb = Math.round((b + m) * 255);
return rr << 16 | gg << 8 | bb;
}
// Oyun başlat
function startGame(startLevel) {
// Temizle
for (var i = 0; i < cards.length; ++i) cards[i].destroy();
cards = [];
flippedCards = [];
matchedCount = 0;
moves = 0;
level = startLevel || 0;
// Her levelde sade, geçişli yeni bir arka plan rengi uygula
game.setBackgroundColor(getBackgroundColorForLevel(level));
game.locked = false;
locked = false;
// Can/hak sayısını başlat
lives = getLivesForLevel(level);
// Eğer önceki levelden kalan hak varsa, üstüne ekle
if (typeof carryOverLives === "number" && carryOverLives > 0) {
lives += carryOverLives;
// Maksimum limiti aşmasın
var maxLives = getLivesForLevel(level);
if (lives > maxLives) lives = maxLives;
carryOverLives = 0;
}
// Update GUI
movesText.setText('Moves: 0');
levelText.setText('Level: ' + (level + 1));
livesText.setText('Lives: ' + lives);
highScore = storage.highScore || 9999;
highScoreText.setText('Best: ' + (highScore === 9999 ? '--' : highScore));
// Kartları oluştur
createLevel(level);
}
// Seviye oluştur
function createLevel(lvl) {
var cfg = getLevelConfig(lvl);
var totalCards = cfg.rows * cfg.cols;
var pairCount = totalCards / 2;
// Kart tiplerini seç (döngüyle 0-7 arası, fazlası için tekrar)
var cardTypes = [];
for (var i = 0; i < pairCount; ++i) cardTypes.push(i % 8);
var allTypes = cardTypes.concat(cardTypes); // Çiftler
// Karıştır
for (var i = allTypes.length - 1; i > 0; --i) {
var j = Math.floor(Math.random() * (i + 1));
var tmp = allTypes[i];
allTypes[i] = allTypes[j];
allTypes[j] = tmp;
}
// Izgara boyutları
var gridW = cfg.cols * 300;
var gridH = cfg.rows * 380;
var startX = (2048 - gridW) / 2 + 150;
var startY = (2732 - gridH) / 2 + 120;
// Kartları yerleştir
for (var r = 0; r < cfg.rows; ++r) {
for (var c = 0; c < cfg.cols; ++c) {
var idx = r * cfg.cols + c;
var card = new MemoryCard();
card.setCardIndex(allTypes[idx]);
card.x = startX + c * 300;
card.y = startY + r * 380;
card.scaleX = card.scaleY = 1;
card.isFlipped = false;
card.isMatched = false;
card.front.visible = false;
card.back.visible = true;
cards.push(card);
game.addChild(card);
}
}
}
// Kart tıklama işlemi
game.onCardClicked = function (card) {
if (locked) return;
if (card.isFlipped || card.isMatched) return;
if (flippedCards.length >= 2) return;
locked = true;
game.locked = true;
card.flip(true, true, function () {
LK.getSound('flip').play();
flippedCards.push(card);
if (flippedCards.length === 2) {
moves++;
movesText.setText('Moves: ' + moves);
// Eşleşme kontrolü
if (flippedCards[0].cardIndex === flippedCards[1].cardIndex) {
// Eşleşti
flippedCards[0].isMatched = true;
flippedCards[1].isMatched = true;
LK.getSound('match').play();
flippedCards[0].playMatchEffect();
// Particle effect: spawn particles at both matched cards
if (_typeof(LK.effects) === "object" && typeof LK.effects.particles === "function") {
// Use a simple burst of yellow-white particles
LK.effects.particles({
x: flippedCards[0].x,
y: flippedCards[0].y,
count: 18,
color: 0xffff99,
speed: 7,
life: 420,
size: 32,
spread: Math.PI * 2,
gravity: 0.12
}, flippedCards[0].parent);
LK.effects.particles({
x: flippedCards[1].x,
y: flippedCards[1].y,
count: 18,
color: 0xffff99,
speed: 7,
life: 420,
size: 32,
spread: Math.PI * 2,
gravity: 0.12
}, flippedCards[1].parent);
}
flippedCards[1].playMatchEffect(function () {
// Emoji ve tebrik mesajı göster
var congratsText = new Text2('🎉 Bravo! Eşleşme! 🎉', {
size: 120,
fill: '#ffe066',
font: "Arial"
});
congratsText.anchor.set(0.5, 0.5);
congratsText.x = 2048 / 2;
congratsText.y = 2732 / 2 - 100;
LK.gui.center.addChild(congratsText);
// Emoji animasyonu (yukarıdan aşağıya zıplat)
congratsText.alpha = 0;
congratsText.scaleX = congratsText.scaleY = 0.7;
tween(congratsText, {
alpha: 1,
scaleX: 1.1,
scaleY: 1.1
}, {
duration: 180,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(congratsText, {
scaleX: 1,
scaleY: 1
}, {
duration: 120,
onFinish: function onFinish() {
// Biraz beklet, sonra kaybolsun
LK.setTimeout(function () {
tween(congratsText, {
alpha: 0
}, {
duration: 350,
onFinish: function onFinish() {
congratsText.destroy();
}
});
}, 700);
}
});
}
});
flippedCards = [];
matchedCount += 2;
locked = false;
game.locked = false;
// Seviye bitti mi?
if (matchedCount === cards.length) {
// Kalan hakları bir sonraki levele aktar
carryOverLives = lives;
LK.getSound('levelup').play();
LK.effects.flashScreen(0x00FF00, 600);
LK.setTimeout(function () {
// Sonsuz seviye: Her zaman bir sonraki seviyeye geç
level++;
startGame(level);
}, 900);
}
});
} else {
// Eşleşmedi
LK.getSound('fail').play();
// Canı azalt
lives--;
livesText.setText('Lives: ' + lives);
// Oyun bitti mi?
if (lives <= 0) {
// Kartları kapatmadan önce kısa bir bekleme
LK.setTimeout(function () {
// Tüm kartları kapat
flippedCards[0].flip(false, true);
flippedCards[1].flip(false, true, function () {
flippedCards = [];
locked = true;
game.locked = true;
// Kırmızı ekran efekti
LK.effects.flashScreen(0xFF0000, 800);
// Skoru güncelle
if (moves < highScore) {
storage.highScore = moves;
}
// Oyun bitti popup
LK.setTimeout(function () {
LK.showGameOver();
}, 900);
});
}, 650);
} else {
LK.setTimeout(function () {
flippedCards[0].flip(false, true);
flippedCards[1].flip(false, true, function () {
flippedCards = [];
locked = false;
game.locked = false;
});
}, 650);
}
}
} else {
locked = false;
game.locked = false;
}
});
};
// Oyun güncellemesi (gerekmiyor ama ileride animasyonlar için kullanılabilir)
game.update = function () {
// Boş
};
// Oyun başlat
startGame(0);
Elon Musk. In-Game asset. 2d. High contrast. No shadows
Bill Gates. In-Game asset. 2d. High contrast. No shadows
Donald Trump. In-Game asset. 2d. High contrast. No shadows
Xi Jinping. In-Game asset. 2d. High contrast. No shadows
Cristiano Ronaldo. In-Game asset. 2d. High contrast. No shadows
Lionel Messi. In-Game asset. 2d. High contrast. No shadows
Oprah Winfrey. In-Game asset. 2d. High contrast. No shadows
Pope Francis. In-Game asset. 2d. High contrast. No shadows
card back celebrity. In-Game asset. 2d. High contrast. No shadows