User prompt
partikül efeckt kullan
User prompt
ekranda gördüğün kart sayısından 3 fazla hak ver
User prompt
oyuncu haklarını kullanmadıysa bir sonraki levele aktarılsın
User prompt
her levelde arkaplan farklı bir renk olsun geçişli ama sade renkler
User prompt
lives 10 ile başlasın + olarak kaç tane kart varsa üstüne eklensin
User prompt
kullanıcı doğru bilince emojilerle ve tebrik mesajları göster
User prompt
başlangıçta 10 hak ver level arttıkça + olarak ekle kart sayısını
User prompt
başlangıçta oyuncunun 10 hakkı olsun level artıkca bunun üstüne eklensin
User prompt
level arttıkca hak sayısı artmalı ama zorluğu bozmıcak şekilde
User prompt
kullanıcın her level belli bir hakkı olmalı
User prompt
leveli sonsuz yap kolaydan zora doğu gitsin
User prompt
moves yazısını biraz aşağıya al
User prompt
ingilizce yap oyunu
User prompt
yazılar birbirine giriyor düzelt ve ingilizce yap oyunu
Code edit (1 edits merged)
Please save this source code
User prompt
Hafıza Kartı: Seviye Seviye Eşleştir!
Initial prompt
// ============================================================================= // 1. GAME CONFIGURATION (OYUN AYARLARI) // Oyunun tüm sabitlerini ve ayarlarını burada tanımlıyoruz. // Bu, oyunun davranışını kolayca ayarlamamızı sağlar. // ============================================================================= const GAME_CONFIG = { SCREEN_WIDTH: 1024, SCREEN_HEIGHT: 768, CARD_WIDTH: 150, CARD_HEIGHT: 150, CARD_MARGIN: 20, FLIP_SPEED_MS: 150, // Kart çevirme animasyon hızı FLIP_BACK_DELAY_MS: 1000, // Eşleşmeyen kartların kapanma süresi LEVEL_DATA: [ // Her seviye için kart ızgarası ve değerleri { id: 1, cols: 4, rows: 3, uniqueValues: 6 }, // 12 kart { id: 2, cols: 4, rows: 4, uniqueValues: 8 }, // 16 kart { id: 3, cols: 5, rows: 4, uniqueValues: 10 }, // 20 kart { id: 4, cols: 6, rows: 4, uniqueValues: 12 }, // 24 kart { id: 5, cols: 6, rows: 5, uniqueValues: 15 } // 30 kart ], MAX_LEVEL: 5, SCORE_PER_MATCH: 100, BONUS_PER_LEVEL: 500, BACKGROUND_COLOR: 0x2c3e50, // Koyu mavi CARD_BACK_COLOR: 0x3498db, // Mavi CARD_FRONT_COLOR: 0xecf0f1, // Açık gri MATCHED_CARD_COLOR: 0x2ecc71, // Yeşil TEXT_COLOR_CARD_VALUE: 0x2c3e50, // Koyu mavi (kart değerleri için) TEXT_COLOR_GUI: 0xffffff, // Beyaz (skor/hamle için) TEXT_COLOR_WIN: 0xf1c40f, // Sarı TEXT_COLOR_LOSE: 0xe74c3c, // Kırmızı SOUND_FLIP: 'flip', SOUND_MATCH: 'match', SOUND_MISMATCH: 'mismatch', SOUND_WIN: 'win', SOUND_BUTTON_CLICK: 'button_click' }; // ============================================================================= // 2. ASSETS (VARLIKLAR) // Oyunun ihtiyaç duyduğu tüm görselleri ve sesleri burada yüklüyoruz. // ============================================================================= LK.init.shape('card_back_shape', { width: GAME_CONFIG.CARD_WIDTH, height: GAME_CONFIG.CARD_HEIGHT, color: GAME_CONFIG.CARD_BACK_COLOR, shape: 'box', radius: 15 }); LK.init.shape('card_front_shape', { width: GAME_CONFIG.CARD_WIDTH - 10, height: GAME_CONFIG.CARD_HEIGHT - 10, color: GAME_CONFIG.CARD_FRONT_COLOR, shape: 'box', radius: 10 }); LK.init.shape('button_shape', { width: 250, height: 80, color: 0x34495e, // Koyu gri shape: 'box', radius: 10 }); LK.init.sound('flip'); LK.init.sound('match'); LK.init.sound('mismatch'); LK.init.sound('win'); LK.init.sound('button_click'); // ============================================================================= // 3. PLUGINS (EKLENTİLER) // Oyunun kullandığı harici kütüphaneleri burada import ediyoruz. // ============================================================================= var tween = LK.import("@upit/tween.v1"); var storage = LK.import("@upit/storage.v1"); // Yüksek skoru kaydetmek için // ============================================================================= // 4. CLASSES (SINIFLAR) // Oyunun temel bileşenlerini temsil eden sınıflar. // ============================================================================= /** * @class Card * @description Hafıza oyunundaki tek bir kartı temsil eder. * Kendi görsel durumunu (açık/kapalı, eşleşmiş) yönetir ve tıklama olaylarını yayar. */ var Card = Container.expand(function (value) { var self = Container.call(this); self.value = value; // Kartın değeri (örneğin 'A', 'B', '1') self.isFaceUp = false; // Kart açık mı? self.isMatched = false; // Kart eşleşti mi? // Kartın arka yüzü görseli self.cardBackSprite = self.attachAsset('card_back_shape', { anchorX: 0.5, anchorY: 0.5 }); // Kartın ön yüzü görseli self.cardFrontSprite = self.attachAsset('card_front_shape', { anchorX: 0.5, anchorY: 0.5 }); self.cardFrontSprite.visible = false; // Başlangıçta gizli // Kartın değeri (metin olarak) self.valueText = new Text2(String(self.value), { size: 80, fill: GAME_CONFIG.TEXT_COLOR_CARD_VALUE, align: 'center' }); self.valueText.anchor.set(0.5, 0.5); self.valueText.visible = false; // Başlangıçta gizli self.addChild(self.valueText); // Kartın tıklanabilirliğini ayarlar self.setInteractive = function(interactive) { self.interactive = interactive; self.buttonMode = interactive; // İmlecin el simgesine dönüşmesini sağlar }; // Kartı çevirme (açma) animasyonu ve mantığı self.flipUp = function () { if (self.isFaceUp || self.isMatched) return; self.isFaceUp = true; LK.getSound(GAME_CONFIG.SOUND_FLIP).play(); // Kartı yatayda küçültme animasyonu (arka yüzü gizleme) tween(self.cardBackSprite, { scaleX: 0 }, { duration: GAME_CONFIG.FLIP_SPEED_MS, easing: tween.easeOut, onFinish: function () { self.cardBackSprite.visible = false; self.cardFrontSprite.visible = true; self.valueText.visible = true; // Kartı yatayda büyütme animasyonu (ön yüzü gösterme) tween(self.cardFrontSprite, { scaleX: 1 }, { duration: GAME_CONFIG.FLIP_SPEED_MS, easing: tween.easeOut }); } }); }; // Kartı çevirme (kapama) animasyonu ve mantığı self.flipDown = function () { if (!self.isFaceUp || self.isMatched) return; self.isFaceUp = false; // Kartı yatayda küçültme animasyonu (ön yüzü gizleme) tween(self.cardFrontSprite, { scaleX: 0 }, { duration: GAME_CONFIG.FLIP_SPEED_MS, easing: tween.easeOut, onFinish: function () { self.cardFrontSprite.visible = false; self.valueText.visible = false; self.cardBackSprite.visible = true; // Kartı yatayda büyütme animasyonu (arka yüzü gösterme) tween(self.cardBackSprite, { scaleX: 1 }, { duration: GAME_CONFIG.FLIP_SPEED_MS, easing: tween.easeOut }); } }); }; // Kartı eşleşmiş olarak işaretler self.match = function () { self.isMatched = true; self.isFaceUp = true; // Eşleşince açık kalır self.cardFrontSprite.tint = GAME_CONFIG.MATCHED_CARD_COLOR; // Eşleşen kartın rengini değiştir self.setInteractive(false); // Eşleşen kart tıklanamaz LK.getSound(GAME_CONFIG.SOUND_MATCH).play(); }; // Kartın tıklama olayını dinler ve bir olay yayar self.onTap = function() { // Kartın kendisini ve değerini içeren bir olay yayar LK.emit('card_clicked', self); }; // Başlangıçta tıklanabilir yap self.setInteractive(true); return self; }); /** * @class Button * @description Yeniden kullanılabilir bir düğme bileşeni. * Metin, renk ve tıklama işlevselliği içerir. */ var Button = Container.expand(function (text, onClickCallback) { var self = Container.call(this); self.buttonSprite = self.attachAsset('button_shape', { anchorX: 0.5, anchorY: 0.5 }); self.buttonText = new Text2(text, { size: 40, fill: GAME_CONFIG.GUI_TEXT_COLOR, align: 'center' }); self.buttonText.anchor.set(0.5, 0.5); self.addChild(self.buttonText); self.interactive = true; self.buttonMode = true; self.onTap = function() { LK.getSound(GAME_CONFIG.SOUND_BUTTON_CLICK).play(); if (onClickCallback) { onClickCallback(); } }; // Fare üzerine gelince rengi değiştir self.on('pointerover', function() { self.buttonSprite.tint = 0x556677; // Hafif koyu }); // Fare çekilince rengi geri al self.on('pointerout', function() { self.buttonSprite.tint = 0x34495e; // Orijinal renk }); return self; }); // ============================================================================= // 5. SCENES (SAHNELER) // Oyunun farklı ekranlarını (menü, oyun, oyun bitti) temsil eden sınıflar. // ============================================================================= /** * @class BaseScene * @description Tüm sahneler için temel sınıf. Ortak işlevsellikleri sağlar. */ var BaseScene = Container.expand(function () { var self = Container.call(this); self.name = "BaseScene"; // Sahnelerin adını takip etmek için self.onEnter = function() { // Sahneye girildiğinde çalışacak kod (override edilecek) self.visible = true; }; self.onExit = function() { // Sahneden çıkıldığında çalışacak kod (override edilecek) self.visible = false; }; self.update = function(dt) { // Sahne güncellendiğinde çalışacak kod (override edilecek) }; return self; }); /** * @class MainMenuScene * @description Ana menü ekranını yönetir. */ var MainMenuScene = BaseScene.expand(function () { var self = BaseScene.call(this); self.name = "MainMenuScene"; // Başlık self.titleText = new Text2('Hafıza Oyunu', { size: 100, fill: GAME_CONFIG.TEXT_COLOR_GUI }); self.titleText.anchor.set(0.5, 0.5); self.titleText.x = GAME_CONFIG.SCREEN_WIDTH / 2; self.titleText.y = GAME_CONFIG.SCREEN_HEIGHT / 2 - 150; self.addChild(self.titleText); // Başlat düğmesi self.startButton = new Button('OYUNU BAŞLAT', function() { LK.emit('start_game'); // Oyun başlatma olayını yay }); self.startButton.x = GAME_CONFIG.SCREEN_WIDTH / 2; self.startButton.y = GAME_CONFIG.SCREEN_HEIGHT / 2; self.addChild(self.startButton); // Yüksek skor metni self.highScoreText = new Text2('Yüksek Skor: ' + (storage.highScore || 0), { size: 40, fill: GAME_CONFIG.TEXT_COLOR_GUI }); self.highScoreText.anchor.set(0.5, 0.5); self.highScoreText.x = GAME_CONFIG.SCREEN_WIDTH / 2; self.highScoreText.y = GAME_CONFIG.SCREEN_HEIGHT / 2 + 100; self.addChild(self.highScoreText); self.onEnter = function() { BaseScene.prototype.onEnter.call(self); self.highScoreText.setText('Yüksek Skor: ' + (storage.highScore || 0)); // Menüye dönüldüğünde skoru güncelle }; return self; }); /** * @class GameScene * @description Asıl hafıza oyunu mantığını yönetir. */ var GameScene = BaseScene.expand(function () { var self = BaseScene.call(this); self.name = "GameScene"; self.cards = []; self.firstCardClicked = null; self.secondCardClicked = null; self.canClick = true; // Oyuncunun tıklayıp tıklayamayacağını kontrol eder self.matchesFound = 0; self.totalMoves = 0; self.currentLevel = 1; // GUI öğeleri self.movesTxt = new Text2('Hamle: 0', { size: 50, fill: GAME_CONFIG.GUI_TEXT_COLOR }); self.movesTxt.anchor.set(0, 0); self.movesTxt.x = 20; self.movesTxt.y = 20; self.addChild(self.movesTxt); self.levelTxt = new Text2('Seviye: 1', { size: 50, fill: GAME_CONFIG.GUI_TEXT_COLOR }); self.levelTxt.anchor.set(1, 0); self.levelTxt.x = GAME_CONFIG.SCREEN_WIDTH - 20; self.levelTxt.y = 20; self.addChild(self.levelTxt); self.onEnter = function(level = 1) { BaseScene.prototype.onEnter.call(self); self.currentLevel = level; self.setupLevel(self.currentLevel); // Kart tıklama olayını dinlemeye başla LK.on('card_clicked', self.handleCardClick.bind(self)); }; self.onExit = function() { BaseScene.prototype.onExit.call(self); // Kart tıklama olayını dinlemeyi bırak LK.off('card_clicked', self.handleCardClick.bind(self)); self.clearCards(); // Sahneler arası geçişte kartları temizle }; self.setupLevel = function(level) { self.clearCards(); // Önceki seviyenin kartlarını temizle self.firstCardClicked = null; self.secondCardClicked = null; self.canClick = true; self.matchesFound = 0; self.totalMoves = 0; const levelData = GAME_CONFIG.LEVEL_DATA[level - 1]; if (!levelData) { console.error("Geçersiz seviye verisi:", level); LK.emit('game_over', { win: true, score: self.totalMoves }); // Tüm seviyeler bittiyse kazanma ekranına git return; } self.createCardGrid(levelData.cols, levelData.rows, levelData.uniqueValues); self.updateGUI(); }; self.clearCards = function() { self.cards.forEach(card => card.destroy()); self.cards = []; }; self.createCardGrid = function (cols, rows, uniqueValues) { const totalCards = cols * rows; const cardValues = []; for (let i = 0; i < uniqueValues; i++) { const charCode = 'A'.charCodeAt(0) + i; const value = String.fromCharCode(charCode); cardValues.push(value, value); } // Kartları karıştır for (let i = cardValues.length - 1; i > 0; i--) { const j = Math.floor(Math.random() * (i + 1)); [cardValues[i], cardValues[j]] = [cardValues[j], cardValues[i]]; } // Kartları oluştur ve ızgaraya yerleştir const gridWidth = cols * (GAME_CONFIG.CARD_WIDTH + GAME_CONFIG.CARD_MARGIN) - GAME_CONFIG.CARD_MARGIN; const gridHeight = rows * (GAME_CONFIG.CARD_HEIGHT + GAME_CONFIG.CARD_MARGIN) - GAME_CONFIG.CARD_MARGIN; const startX = (GAME_CONFIG.SCREEN_WIDTH - gridWidth) / 2 + GAME_CONFIG.CARD_WIDTH / 2; const startY = (GAME_CONFIG.SCREEN_HEIGHT - gridHeight) / 2 + GAME_CONFIG.CARD_HEIGHT / 2; for (let row = 0; row < rows; row++) { for (let col = 0; col < cols; col++) { const cardValue = cardValues.pop(); const card = new Card(cardValue); card.x = startX + col * (GAME_CONFIG.CARD_WIDTH + GAME_CONFIG.CARD_MARGIN); card.y = startY + row * (GAME_CONFIG.CARD_HEIGHT + GAME_CONFIG.CARD_MARGIN); self.addChild(card); self.cards.push(card); } } }; self.handleCardClick = function (card) { if (!self.canClick || card.isFaceUp || card.isMatched) { return; } card.flipUp(); if (!self.firstCardClicked) { self.firstCardClicked = card; } else { self.secondCardClicked = card; self.canClick = false; // Yeni tıklamaları engelle self.totalMoves++; self.updateGUI(); LK.setTimeout(self.checkForMatch.bind(self), GAME_CONFIG.FLIP_BACK_DELAY_MS); } }; self.checkForMatch = function () { if (self.firstCardClicked.value === self.secondCardClicked.value) { // Eşleşme var! self.firstCardClicked.match(); self.secondCardClicked.match(); self.matchesFound++; self.firstCardClicked = null; self.secondCardClicked = null; self.canClick = true; self.checkWinCondition(); } else { // Eşleşme yok LK.getSound(GAME_CONFIG.SOUND_MISMATCH).play(); self.firstCardClicked.flipDown(); self.secondCardClicked.flipDown(); self.firstCardClicked = null; self.secondCardClicked = null; self.canClick = true; } }; self.checkWinCondition = function () { const levelData = GAME_CONFIG.LEVEL_DATA[self.currentLevel - 1]; if (self.matchesFound === levelData.uniqueValues) { LK.getSound(GAME_CONFIG.SOUND_WIN).play(); // Seviye tamamlandı, bir sonraki seviyeye geç veya oyunu bitir if (self.currentLevel < GAME_CONFIG.MAX_LEVEL) { LK.emit('level_cleared', { level: self.currentLevel, score: self.totalMoves }); } else { LK.emit('game_over', { win: true, score: self.totalMoves }); // Tüm seviyeler tamamlandı } } }; self.updateGUI = function () { self.movesTxt.setText('Hamle: ' + self.totalMoves); self.levelTxt.setText('Seviye: ' + self.currentLevel); }; return self; }); /** * @class GameOverScene * @description Oyun bitti ekranını yönetir (kazanma/kaybetme). */ var GameOverScene = BaseScene.expand(function () { var self = BaseScene.call(this); self.name = "GameOverScene"; self.resultText = new Text2('', { size: 90, fill: GAME_CONFIG.TEXT_COLOR_GUI }); self.resultText.anchor.set(0.5, 0.5); self.resultText.x = GAME_CONFIG.SCREEN_WIDTH / 2; self.resultText.y = GAME_CONFIG.SCREEN_HEIGHT / 2 - 150; self.addChild(self.resultText); self.scoreText = new Text2('', { size: 60, fill: GAME_CONFIG.TEXT_COLOR_GUI }); self.scoreText.anchor.set(0.5, 0.5); self.scoreText.x = GAME_CONFIG.SCREEN_WIDTH / 2; self.scoreText.y = GAME_CONFIG.SCREEN_HEIGHT / 2 - 50; self.addChild(self.scoreText); self.highScoreText = new Text2('', { size: 50, fill: GAME_CONFIG.TEXT_COLOR_GUI }); self.highScoreText.anchor.set(0.5, 0.5); self.highScoreText.x = GAME_CONFIG.SCREEN_WIDTH / 2; self.highScoreText.y = GAME_CONFIG.SCREEN_HEIGHT / 2 + 20; self.addChild(self.highScoreText); self.playAgainButton = new Button('YENİDEN OYNA', function() { LK.emit('start_game'); // Oyunu yeniden başlatma olayını yay }); self.playAgainButton.x = GAME_CONFIG.SCREEN_WIDTH / 2; self.playAgainButton.y = GAME_CONFIG.SCREEN_HEIGHT / 2 + 150; self.addChild(self.playAgainButton); self.mainMenuButton = new Button('ANA MENÜ', function() { LK.emit('go_to_main_menu'); // Ana menüye gitme olayını yay }); self.mainMenuButton.x = GAME_CONFIG.SCREEN_WIDTH / 2; self.mainMenuButton.y = GAME_CONFIG.SCREEN_HEIGHT / 2 + 250; self.addChild(self.mainMenuButton); self.onEnter = function(data) { BaseScene.prototype.onEnter.call(self); const finalScore = data.score; const didWin = data.win; if (didWin) { self.resultText.setText('TEBRİKLER! KAZANDIN!'); self.resultText.fill = GAME_CONFIG.TEXT_COLOR_WIN; } else { self.resultText.setText('OYUN BİTTİ!'); self.resultText.fill = GAME_CONFIG.TEXT_COLOR_LOSE; } self.scoreText.setText('Toplam Hamle: ' + finalScore); let currentHighScore = storage.highScore || 999999; // Daha az hamle daha iyi skor if (finalScore < currentHighScore) { storage.highScore = finalScore; currentHighScore = finalScore; self.highScoreText.setText('YENİ YÜKSEK SKOR!'); self.highScoreText.fill = GAME_CONFIG.TEXT_COLOR_WIN; } else { self.highScoreText.setText('Yüksek Skor: ' + currentHighScore); self.highScoreText.fill = GAME_CONFIG.TEXT_COLOR_GUI; } }; return self; }); // ============================================================================= // 6. GAMECONTROLLER (OYUN KONTROLÖRÜ) // Oyunun ana beyni. Sahne geçişlerini ve genel oyun akışını yönetir. // ============================================================================= var GameController = { currentScene: null, mainMenuScene: null, gameScene: null, gameOverScene: null, currentLevel: 1, // Oyuncunun mevcut seviyesi init: function () { // LK.js oyun tuvalini başlat new LK.Game({ backgroundColor: GAME_CONFIG.BACKGROUND_COLOR, width: GAME_CONFIG.SCREEN_WIDTH, height: GAME_CONFIG.SCREEN_HEIGHT }); // Sahneleri oluştur this.mainMenuScene = new MainMenuScene(); this.gameScene = new GameScene(); this.gameOverScene = new GameOverScene(); // Tüm sahneleri sahneye ekle ama başlangıçta gizle LK.add(this.mainMenuScene); LK.add(this.gameScene); LK.add(this.gameOverScene); this.mainMenuScene.visible = false; this.gameScene.visible = false; this.gameOverScene.visible = false; // Oyun olaylarını dinle LK.on('start_game', this.handleStartGame.bind(this)); LK.on('level_cleared', this.handleLevelCleared.bind(this)); LK.on('game_over', this.handleGameOver.bind(this)); LK.on('go_to_main_menu', this.handleGoToMainMenu.bind(this)); // Başlangıç sahnesini ayarla this.changeScene(this.mainMenuScene); // Oyun döngüsünü başlat (sahnelerin update metodunu çağıracak) LK.onUpdate(this.update.bind(this)); }, /** * Sahne değiştirme mantığı. Mevcut sahneden çıkar, yeni sahneye girer. * @param {BaseScene} newScene - Geçiş yapılacak yeni sahne objesi. * @param {Object} [data] - Yeni sahneye aktarılacak opsiyonel veri. */ changeScene: function (newScene, data = {}) { if (this.currentScene) { this.currentScene.onExit(); // Mevcut sahneden çıkış } this.currentScene = newScene; this.currentScene.onEnter(data); // Yeni sahneye giriş console.log(`Sahne değişti: ${this.currentScene.name}`); }, // Olay işleyicileri handleStartGame: function () { this.currentLevel = 1; // Oyunu başlatırken seviyeyi sıfırla this.changeScene(this.gameScene, this.currentLevel); }, handleLevelCleared: function (data) { console.log(`Seviye ${data.level} tamamlandı!`); this.currentLevel++; // Bir sonraki seviyeye geç if (this.currentLevel <= GAME_CONFIG.MAX_LEVEL) { this.changeScene(this.gameScene, this.currentLevel); } else { // Tüm seviyeler tamamlandı, oyunu kazanma ekranına git this.changeScene(this.gameOverScene, { win: true, score: data.score }); } }, handleGameOver: function (data) { console.log(`Oyun Bitti! Kazanma Durumu: ${data.win}, Hamle: ${data.score}`); this.changeScene(this.gameOverScene, data); }, handleGoToMainMenu: function() { this.changeScene(this.mainMenuScene); }, // Ana oyun döngüsü update: function (dt) { if (this.currentScene && this.currentScene.update) { this.currentScene.update(dt); // Mevcut sahnenin update metodunu çağır } } }; // LK hazır olduğunda GameController'ı başlat LK.ready(() => { GameController.init(); });
/**** * 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 ****/ // Infinite level config generator // Müzik (isteğe bağlı, başlatılmayacak) // Ses efektleri // Eşleşme animasyonu için // Kartların arka yüzü (gri) // Kartlar için farklı renklerde kutular (8 farklı renk, 16 kartlık bir seviye için yeterli) // Oyun parametreleri 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; // Başlangıçta 10 hak, her seviye için +1 ekle var lives = 10 + lvl; // 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; // 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; // 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; game.locked = false; locked = false; // Can/hak sayısını başlat lives = getLivesForLevel(level); // 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(); flippedCards[1].playMatchEffect(function () { flippedCards = []; matchedCount += 2; locked = false; game.locked = false; // Seviye bitti mi? if (matchedCount === cards.length) { 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);
===================================================================
--- original.js
+++ change.js
@@ -119,8 +119,9 @@
// Oyun parametreleri
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
}, {
@@ -147,19 +148,28 @@
}];
if (lvl < baseConfigs.length) {
return baseConfigs[lvl];
}
- // After level 7, increase grid size every 2 levels, up to a max reasonable size (e.g. 8x8)
+ // 8x8'e kadar büyüt, sonra 8x8'de kal
var maxRows = 8,
maxCols = 8;
- var growStep = Math.floor((lvl - 7) / 2);
- var rows = Math.min(6 + growStep, maxRows);
- var cols = Math.min(6 + growStep, maxCols);
- // Always keep even number of cards
+ 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) {
- cols += 1;
- if (cols > maxCols) cols = maxCols;
+ 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
};
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