/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x000000 // Black background }); /**** * Game Code ****/ // --- GLOBALS --- var puansayisi = 0; // Total score var timeLeft; // Declare timeLeft for countdown timer if (typeof timeLeft === "undefined") { timeLeft = 50; // Only initialize to 50 if never defined } var tapCount = 0; // Counts taps until "Tebrikler" is shown var countingDirection = 1; // 1: up, -1: down var startNumber = 0; var targetNumber = 10; var currentNumber = 0; var gameStarted = false; var puanText = null; // Global reference to puan text var congratsText = null; // Global reference to congratulations text // --- LANGUAGE SUPPORT --- var LANGUAGES = [{ code: "en", label: "English" }, { code: "tr", label: "Türkçe" }]; var lang = "tr"; // default language // Localization dictionary var L10N = { tr: { increase: "Artarak", decrease: "Azalarak", selectTarget: "Hedef Seç", selectDirection: "Yön Seç", win: "Tebrikler!", tapToCount: "Ekrana tıkla", numberReading: function numberReading(n) { return getNumberReadingTR(n); } }, en: { increase: "Increasing", decrease: "Decreasing", selectTarget: "Select Target", selectDirection: "Select Direction", win: "Congratulations!", tapToCount: "Tap to count", numberReading: function numberReading(n) { return getNumberReadingEN(n); } } }; // UI elements var numberText = null; var numberReadingText = null; var infoText = null; var optionButtons = []; var directionButtons = []; var selectedTarget = null; var selectedDirection = null; var langButtons = []; var selectText = null; // Make selectText global for cleanup // --- UI HELPERS --- // Create a button as a colored box with text, returns a Container function createButton(label, x, y, width, height, color, onTap) { var btn = new Container(); var box = btn.attachAsset('buttonBox', { width: width, height: height, color: color, anchorX: 0.5, anchorY: 0.5 }); var txt = new Text2(label, { size: 80, fill: 0xFFFFFF }); txt.anchor.set(0.5, 0.5); txt.x = 0; txt.y = 0; btn.addChild(txt); btn.x = x; btn.y = y; btn.interactive = true; btn.down = function (x, y, obj) { if (onTap) { onTap(); } }; return btn; } // --- GAME SETUP --- // Helper to check if a number is prime function isPrime(n) { if (n < 2) return false; for (var i = 2; i * i <= n; i++) { if (n % i === 0) return false; } return true; } // Show a random two-digit number (10-99) above 'Sayıyı bul' var randomNumber; // Generate a random number that is a multiple of one of the available targets (1-25) var possibleMultiples = []; for (var mult = 1; mult <= 25; mult++) { for (var factor = 2; factor <= 9; factor++) { var product = mult * factor; if (product >= 10 && product <= 99) { possibleMultiples.push(product); } } } randomNumber = possibleMultiples[Math.floor(Math.random() * possibleMultiples.length)]; var randomNumberText = new Text2("" + randomNumber, { size: 120, fill: 0xFFFFFF }); randomNumberText.anchor.set(0.5, 1); randomNumberText.x = 2048 / 2; // Move the bottom section higher up (e.g. 350px from bottom instead of 120px) randomNumberText.y = 2732 - 350; game.addChild(randomNumberText); // Add 'Sayısı Hangi Sayının Katıdır?' text just below the random number var findNumberLabel = lang === "en" ? "Which number is this a multiple of?" : "Sayısı Hangi Sayının Katıdır?"; var findNumberText = new Text2(findNumberLabel, { size: 80, fill: 0xFFFFFF }); findNumberText.anchor.set(0.5, 0); findNumberText.x = 2048 / 2; findNumberText.y = randomNumberText.y + 20; game.addChild(findNumberText); // Show the pre-game menu: select target number and direction function showMenu() { gameStarted = false; selectedTarget = null; selectedDirection = null; // Remove previous UI if any if (numberText) { numberText.destroy(); numberText = null; } if (numberReadingText) { numberReadingText.destroy(); numberReadingText = null; } if (infoText) { infoText.destroy(); infoText = null; } for (var i = 0; i < optionButtons.length; i++) { optionButtons[i].destroy(); } optionButtons = []; for (var i = 0; i < directionButtons.length; i++) { if (directionButtons[i]) { directionButtons[i].destroy(); } } directionButtons = []; for (var i = 0; i < langButtons.length; i++) { langButtons[i].destroy(); } langButtons = []; // Remove infoText usage, but keep for cleanup infoText = null; // Remove back button if it exists (should not be visible in menu) if (typeof backButton !== "undefined" && backButton) { backButton.destroy(); backButton = null; } // --- LANGUAGE BUTTONS --- var langBtnW = 320, langBtnH = 100, langBtnGap = 40; var langBtnStartX = (2048 - (LANGUAGES.length * langBtnW + (LANGUAGES.length - 1) * langBtnGap)) / 2 + langBtnW / 2; var langBtnY = 120; for (var i = 0; i < LANGUAGES.length; i++) { (function (idx) { var l = LANGUAGES[idx]; var btn = createButton(l.label, langBtnStartX + idx * (langBtnW + langBtnGap), langBtnY, langBtnW, langBtnH, 0x888888, function () { lang = l.code; // Update the question text when language changes if (findNumberText) { var findNumberLabel = lang === "en" ? "Which number is this a multiple of?" : "Sayısı Hangi Sayının Katıdır?"; findNumberText.setText(findNumberLabel); } showMenu(); }); // Highlight selected language btn.children[0].tint = lang === l.code ? 0xff0000 : 0xffffff; langButtons.push(btn); game.addChild(btn); })(i); } // --- HEADER RECTANGLE --- var headerHeight = 320; // Increased height for a more vertically extended header var headerY = 420; // Moved header further down var headerAssetId = lang === "en" ? "centerCircle1" : "centerCircle"; var headerRect = game.attachAsset(headerAssetId, { width: 720, // 10% smaller than 800 height: headerHeight, anchorX: 0.5, anchorY: 0.5, x: 2048 / 2, y: headerY }); // So it gets cleaned up with the rest of the menu // Target number options (1-25) as a 5x5 grid var targets = []; for (var i = 1; i <= 25; i++) { targets.push(i); } var btnW = 220 * 1.1, // 10% larger btnH = 220 * 1.1; // 10% larger, keep square var gapX = 40; var gapY = 40; var gridCols = 5; var gridRows = 5; // Calculate total grid width and height var gridTotalWidth = gridCols * btnW + (gridCols - 1) * gapX; var gridTotalHeight = gridRows * btnH + (gridRows - 1) * gapY; // Center grid on screen var gridStartX = (2048 - gridTotalWidth) / 2 + btnW / 2; var gridStartY = (2732 - gridTotalHeight) / 2 + btnH / 2; for (var i = 0; i < targets.length; i++) { (function (idx) { var t = targets[idx]; var col = idx % gridCols; var row = Math.floor(idx / gridCols); var x = gridStartX + col * (btnW + gapX); var y = gridStartY + row * (btnH + gapY); var btn = createButton("" + t, x, y, btnW, btnH, 0x4a90e2, function () { selectTarget(t, idx); }); // If this target was previously selected, keep it red if (selectedTarget !== null && selectedTarget === idx) { btn.children[0].tint = 0xff0000; } optionButtons.push(btn); game.addChild(btn); })(i); } // (Removed 'Saymak istediğimiz sayıyı seçelim' text below the grid) // No direction buttons on the first page } // When a target number is selected function selectTarget(t, idx) { LK.getSound('click').play(); targetNumber = t; selectedTarget = idx; // Highlight selected for (var i = 0; i < optionButtons.length; i++) { // Make selected target button red, others white optionButtons[i].children[0].tint = i === idx ? 0xff0000 : 0xffffff; } // Animate selected button: jump up and down once var btn = optionButtons[idx]; tween.stop(btn, { y: true }); var originalY = btn.y; tween(btn, { y: originalY - 80 }, { duration: 240, easing: tween.cubicOut, onFinish: function onFinish() { tween(btn, { y: originalY }, { duration: 360, easing: tween.bounceOut }); } }); // Enable direction buttons after a target is selected for (var i = 0; i < directionButtons.length; i++) { directionButtons[i].directionActive = true; directionButtons[i].alpha = 1; } // Go to 2nd page (gameplay) immediately when a target is tapped startGame(); } // When a direction is selected function selectDirection(dir, idx) { LK.getSound('click').play(); countingDirection = dir; selectedDirection = idx; // Highlight selected for (var i = 0; i < directionButtons.length; i++) { // Make selected direction button red, others white directionButtons[i].children[0].tint = i === idx ? 0xff0000 : 0xffffff; // Animate selected direction button with jump effect if (i === idx) { tween.stop(directionButtons[i], { y: true }); var originalY = directionButtons[i].y; tween(directionButtons[i], { y: originalY - 80 }, { duration: 320, easing: tween.cubicOut, onFinish: function (btn, oy) { return function () { tween(btn, { y: oy }, { duration: 420, easing: tween.bounceOut }); }; }(directionButtons[i], originalY) }); } } // If target already selected, start game after 1 second if (selectedTarget !== null) { LK.setTimeout(function () { startGame(); }, 1000); } } // --- GAMEPLAY --- function startGame() { // Remove menu UI if (infoText) { infoText.destroy(); infoText = null; } for (var i = 0; i < optionButtons.length; i++) { optionButtons[i].destroy(); } optionButtons = []; for (var i = 0; i < directionButtons.length; i++) { directionButtons[i].destroy(); } directionButtons = []; // (tapCountText cleanup removed - not used anymore) // Remove "Saymak istediğimiz sayıyı seçelim" text if it exists if (typeof selectText !== "undefined" && selectText) { selectText.destroy(); selectText = null; } // Always start from 0, regardless of direction startNumber = 0; currentNumber = startNumber; tapCount = 0; // Reset tap count for new game // Show current number // Calculate size to cover 50% of the screen height (2732 * 0.5 = 1366px) // Text2 size is font size, so we estimate a bit smaller to fit: try 1200px numberText = new Text2("" + currentNumber, { size: 1200, fill: 0xFFFFFF }); numberText.anchor.set(0.5, 0.5); numberText.x = 2048 / 2; numberText.y = 2732 / 2; game.addChild(numberText); // --- GAMEPLAY --- if (numberReadingText) { numberReadingText.destroy(); numberReadingText = null; } // Dynamically fit numberReadingText to always fit on screen var readingString = L10N[lang].numberReading(currentNumber); var maxWidth = 2048 * 0.9; // 90% of screen width var maxHeight = 220; // Max font size var minFontSize = 80; var fontSize = maxHeight; var testText = null; do { if (testText) testText.destroy(); testText = new Text2(readingString, { size: fontSize, fill: 0xFFFFFF }); testText.anchor.set(0.5, 0); } while ((testText.width > maxWidth || testText.height > 300) && fontSize-- > minFontSize); if (testText) testText.destroy(); numberReadingText = new Text2(readingString, { size: fontSize, fill: 0xFFFFFF }); numberReadingText.anchor.set(0.5, 0); numberReadingText.x = 2048 / 2; // Move the number reading text higher up (was: numberText.y + numberText.height / 2 + 40) numberReadingText.y = numberText.y + numberText.height / 2 - 120; game.addChild(numberReadingText); gameStarted = true; // --- Add 'İleri' and 'Geri' overlays --- var ileriLabel = lang === "en" ? "Forward" : "İleri"; var ileriText = new Text2(ileriLabel, { size: 120, fill: 0xffffff }); ileriText.anchor.set(0.5, 0.5); ileriText.x = 2048 * 0.75; ileriText.y = 2732 / 2; game.addChild(ileriText); var geriLabel = lang === "en" ? "Back" : "Geri"; var geriText = new Text2(geriLabel, { size: 180, fill: 0xffffff }); geriText.anchor.set(0.5, 0.5); geriText.x = 2048 * 0.25; geriText.y = 2732 / 2; game.addChild(geriText); // Store for later removal game._ileriText = ileriText; game._geriText = geriText; // --- DIRECTION BUTTONS REMOVED FROM GAMEPLAY --- // No direction buttons in gameplay directionButtons = []; // --- BACK BUTTON IN GAMEPLAY --- var backButton = null; // Declare backButton variable first if (backButton) { backButton.destroy(); backButton = null; } var backButtonLabel = lang === "en" ? "Back" : "Anasayfa"; var langBtnW = 320, langBtnH = 100; // match language button size // Create the back button using the same font size as 'Yeniden Başla' (54) // puansayisi is already defined globally, no need to redefine // Back button (Anasayfa) var backButton = new Container(); var backBox = backButton.attachAsset('buttonBox', { width: langBtnW, height: langBtnH, color: 0x888888, anchorX: 0.5, anchorY: 0.5 }); var backTxt = new Text2(backButtonLabel, { size: 70, // Increased font size for better visibility fill: 0xFFFFFF }); backTxt.anchor.set(0.5, 0.5); backTxt.x = 0; backTxt.y = 0; backButton.addChild(backTxt); backButton.x = 2048 - 100 - langBtnW / 2; backButton.y = 100 + langBtnH / 2; backButton.interactive = true; backButton.down = function (x, y, obj) { // Defensive: prevent double tap if (!gameStarted) return; gameStarted = false; // Clean up gameplay UI if (numberText) { numberText.destroy(); numberText = null; } if (numberReadingText) { numberReadingText.destroy(); numberReadingText = null; } for (var i = 0; i < directionButtons.length; i++) { if (directionButtons[i]) directionButtons[i].destroy(); } directionButtons = []; if (typeof backButton !== "undefined" && backButton) { backButton.destroy(); backButton = null; } if (puanText) { puanText.destroy(); puanText = null; } // Clean up congratulations text if (congratsText) { congratsText.destroy(); congratsText = null; } // Clean up timer if (game._timerInterval) { LK.clearInterval(game._timerInterval); game._timerInterval = null; } if (game._timerContainer) { game._timerContainer.destroy(); game._timerContainer = null; } // Do NOT reset timeLeft here; keep its value for next gameplay showMenu(); }; backButton.children[0].tint = 0xffffff; game.addChild(backButton); // Add 'Puan: <puansayisi>' text below the Anasayfa button if (puanText) { puanText.destroy(); puanText = null; } var puanLabel = lang === "en" ? "Score: " : "Puan: "; puanText = new Text2(puanLabel + puansayisi, { size: 80, fill: 0xffffff }); puanText.anchor.set(0.5, 0); puanText.x = backButton.x; puanText.y = backButton.y + langBtnH / 2 + 16; game.addChild(puanText); // Add circular countdown timer below puan text var timerContainer = new Container(); timerContainer.x = puanText.x; timerContainer.y = puanText.y + 250; // Moved timer even lower game.addChild(timerContainer); // Store reference for access in other scopes game._timerContainer = timerContainer; // Create circular background var timerBg = timerContainer.attachAsset('centerCircle2', { width: 150, height: 150, anchorX: 0.5, anchorY: 0.5, tint: 0x333333 }); // Create timer text var timerText = new Text2("" + timeLeft, { size: 60, fill: 0xffffff }); timerText.anchor.set(0.5, 0.5); timerContainer.addChild(timerText); // Start countdown using global timeLeft and timerInterval // Only reset timeLeft to 50 on very first gameplay entry if (typeof timeLeft === "undefined" || timeLeft === null || timeLeft === 50) { timeLeft = 50; } if (game._timerInterval) { LK.clearInterval(game._timerInterval); game._timerInterval = null; } game._timerInterval = LK.setInterval(function () { timeLeft--; if (timeLeft >= 0) { timerText.setText("" + timeLeft); // Pulse animation when time is running low if (timeLeft <= 5) { if (timerContainer) { tween(timerContainer, { scaleX: 1.2, scaleY: 1.2 }, { duration: 300, easing: tween.easeOut, onFinish: function onFinish() { if (timerContainer) { tween(timerContainer, { scaleX: 1, scaleY: 1 }, { duration: 300, easing: tween.easeIn }); } } }); } // Change color to red when low on time timerText.tint = 0xff0000; } } else { // Time's up LK.clearInterval(game._timerInterval); game._timerInterval = null; // Clear all game elements if (numberText) { numberText.destroy(); numberText = null; } if (numberReadingText) { numberReadingText.destroy(); numberReadingText = null; } if (typeof backButton !== "undefined" && backButton) { backButton.destroy(); backButton = null; } if (game._ileriText) { game._ileriText.destroy(); game._ileriText = null; } if (game._geriText) { game._geriText.destroy(); game._geriText = null; } if (timerContainer) { timerContainer.destroy(); timerContainer = null; } // Hide puan text if (puanText) { puanText.destroy(); puanText = null; } // Hide random number and "whose multiple" text if (randomNumberText) { randomNumberText.visible = false; } if (findNumberText) { findNumberText.visible = false; } // Show only score and congratulations var finalScoreText = new Text2("" + puansayisi, { size: 300, fill: 0xffffff }); finalScoreText.anchor.set(0.5, 0.5); finalScoreText.x = 2048 / 2; finalScoreText.y = 2732 / 2 - 200; game.addChild(finalScoreText); var congratsText = new Text2(L10N[lang].win, { size: 220, fill: 0x00ff00 }); congratsText.anchor.set(0.5, 0.5); congratsText.x = 2048 / 2; congratsText.y = 2732 / 2 + 200; game.addChild(congratsText); // Show game over after 2 seconds LK.setTimeout(function () { LK.showGameOver(); }, 2000); } }, 1000); // Store timer references for cleanup game._timerContainer = timerContainer; } // --- Number Reading Helper (Turkish) --- function getNumberReadingTR(n) { // Only works for 0-250, but covers all gameplay needs var birler = ["", "BİR", "İKİ", "ÜÇ", "DÖRT", "BEŞ", "ALTI", "YEDİ", "SEKİZ", "DOKUZ"]; var onlar = ["", "ON", "YİRMİ", "OTUZ", "KIRK", "ELLİ", "ALTMIŞ", "YETMİŞ", "SEKSEN", "DOKSAN"]; var yuzler = ["", "YÜZ", "İKİYÜZ"]; n = Math.floor(n); if (n < 0) { return ""; } if (n === 0) { return "SIFIR"; } if (n > 250) { return "" + n; } // fallback var y = Math.floor(n / 100); var o = Math.floor(n % 100 / 10); var b = n % 10; var parts = []; if (y > 0) { if (y === 1) { parts.push("YÜZ"); } else { parts.push(birler[y] + " YÜZ"); } } if (o > 0) { parts.push(onlar[o]); } if (b > 0) { parts.push(birler[b]); } return parts.join(" "); } // --- Number Reading Helper (English) --- function getNumberReadingEN(n) { // Only works for 0-250, covers all gameplay needs var ones = ["", "ONE", "TWO", "THREE", "FOUR", "FIVE", "SIX", "SEVEN", "EIGHT", "NINE"]; var tens = ["", "TEN", "TWENTY", "THIRTY", "FORTY", "FIFTY", "SIXTY", "SEVENTY", "EIGHTY", "NINETY"]; var hundreds = ["", "ONE HUNDRED", "TWO HUNDRED"]; n = Math.floor(n); if (n < 0) { return ""; } if (n === 0) { return "ZERO"; } if (n > 250) { return "" + n; } // fallback var y = Math.floor(n / 100); var o = Math.floor(n % 100 / 10); var b = n % 10; var parts = []; if (y > 0) { if (y === 1 && o === 0 && b === 0) { parts.push("ONE HUNDRED"); } else { parts.push(ones[y] + " HUNDRED"); } } if (o > 0) { parts.push(tens[o]); } if (b > 0) { parts.push(ones[b]); } return parts.join(" "); } // --- GAME INTERACTION --- // On tap/click anywhere, increment or decrement number game.down = function (x, y, obj) { if (!gameStarted) { // Start countdown on first tap if (!game._timerInterval) { game._timerInterval = LK.setInterval(function () { timeLeft--; if (timeLeft >= 0) { if (game._timerContainer && game._timerContainer.children[1]) { game._timerContainer.children[1].setText("" + timeLeft); } if (timeLeft <= 5) { if (game._timerContainer) { tween(game._timerContainer, { scaleX: 1.2, scaleY: 1.2 }, { duration: 300, easing: tween.easeOut, onFinish: function onFinish() { if (game._timerContainer) { tween(game._timerContainer, { scaleX: 1, scaleY: 1 }, { duration: 300, easing: tween.easeIn }); } } }); } if (game._timerContainer && game._timerContainer.children[1]) { game._timerContainer.children[1].tint = 0xff0000; } } } else { LK.clearInterval(game._timerInterval); if (numberText) { numberText.destroy(); numberText = null; } if (numberReadingText) { numberReadingText.destroy(); numberReadingText = null; } if (typeof backButton !== "undefined" && backButton) { backButton.destroy(); backButton = null; } if (game._ileriText) { game._ileriText.destroy(); game._ileriText = null; } if (game._geriText) { game._geriText.destroy(); game._geriText = null; } if (game._timerContainer) { game._timerContainer.destroy(); game._timerContainer = null; } // Hide puan text if (puanText) { puanText.destroy(); puanText = null; } // Hide random number and "whose multiple" text if (randomNumberText) { randomNumberText.visible = false; } if (findNumberText) { findNumberText.visible = false; } var finalScoreText = new Text2("" + puansayisi, { size: 300, fill: 0xffffff }); finalScoreText.anchor.set(0.5, 0.5); finalScoreText.x = 2048 / 2; finalScoreText.y = 2732 / 2 - 200; game.addChild(finalScoreText); var congratsText = new Text2(L10N[lang].win, { size: 220, fill: 0x00ff00 }); congratsText.anchor.set(0.5, 0.5); congratsText.x = 2048 / 2; congratsText.y = 2732 / 2 + 200; game.addChild(congratsText); LK.setTimeout(function () { LK.showGameOver(); }, 2000); } }, 1000); } return; } // Remove 'İleri' and 'Geri' overlays on first tap if (game._ileriText) { game._ileriText.destroy(); game._ileriText = null; } if (game._geriText) { game._geriText.destroy(); game._geriText = null; } LK.getSound('click').play(); // --- TAP COUNT: Increase tap count only in gameplay (2nd screen) --- if (gameStarted) { tapCount = tapCount + 1; } // Increment if tapped on right half, decrement if tapped on left half if (x > 2048 / 2) { currentNumber += targetNumber; } else { currentNumber -= targetNumber; if (currentNumber < 0) { currentNumber = 0; } } // Animate numberText (scale up and back) only if numberText exists if (numberText) { tween(numberText, { scaleX: 1.2, scaleY: 1.2 }, { duration: 80, easing: tween.easeOut, onFinish: function onFinish() { if (numberText) { tween(numberText, { scaleX: 1, scaleY: 1 }, { duration: 80, easing: tween.easeIn }); } } }); } // Animate selected target button (jump effect) on every tap if (selectedTarget !== null && Array.isArray(optionButtons) && optionButtons[selectedTarget] && typeof optionButtons[selectedTarget].y !== "undefined") { var btn = optionButtons[selectedTarget]; tween.stop(btn, { y: true }); var originalY = btn.y; tween(btn, { y: originalY - 80 }, { duration: 240, easing: tween.cubicOut, onFinish: function onFinish() { tween(btn, { y: originalY }, { duration: 360, easing: tween.bounceOut }); } }); } // (Handled above with tapCount logic) if (numberText) { numberText.setText("" + currentNumber); } // Update number reading text if (numberReadingText) { // Dynamically fit numberReadingText to always fit on screen after increment/decrement var readingString = L10N[lang].numberReading(currentNumber); var maxWidth = 2048 * 0.9; var maxHeight = 220; var minFontSize = 80; var fontSize = maxHeight; var testText = null; do { if (testText) testText.destroy(); testText = new Text2(readingString, { size: fontSize, fill: 0xFFFFFF }); testText.anchor.set(0.5, 0); } while ((testText.width > maxWidth || testText.height > 300) && fontSize-- > minFontSize); if (testText) testText.destroy(); numberReadingText.setStyle({ size: fontSize }); numberReadingText.setText(readingString); } if (currentNumber === randomNumber) { // Clean up any existing congratulations text if (congratsText) { congratsText.destroy(); congratsText = null; } // Show 'Tebrikler!' (Congratulations!) in the center of the screen congratsText = new Text2(L10N[lang].win, { size: 220, fill: 0x00ff00 }); congratsText.anchor.set(0.5, 0.5); congratsText.x = 2048 / 2; congratsText.y = 2732 / 2 - 600; game.addChild(congratsText); // --- SCORE CALCULATION: Add (100 - tapCount) to puansayisi --- var scoreToAdd = 100 - tapCount; puansayisi = puansayisi + scoreToAdd; // Update puan text display if (puanText) { var puanLabel = lang === "en" ? "Score: " : "Puan: "; puanText.setText(puanLabel + puansayisi); } // Reset tap count for next round tapCount = 0; // Do NOT reset timer when target is reached - just continue with current time // Optionally, fade out after 2 seconds, but do NOT reset game automatically tween(congratsText, { alpha: 0 }, { duration: 1800, delay: 1200, onFinish: function onFinish() { if (congratsText) { congratsText.destroy(); congratsText = null; } // Do not destroy kalanText here, keep it visible // Do not call showMenu(); user must press back to return } }); // Refresh the random number and update its text after congrats (always two-digit) // Generate a random number that is a multiple of one of the available targets (1-25) var possibleMultiples = []; for (var mult = 1; mult <= 25; mult++) { for (var factor = 2; factor <= 9; factor++) { var product = mult * factor; if (product >= 10 && product <= 99) { possibleMultiples.push(product); } } } randomNumber = possibleMultiples[Math.floor(Math.random() * possibleMultiples.length)]; if (randomNumberText) { randomNumberText.setText("" + randomNumber); } } }; // --- GAME RESET --- // When game is reset, show menu again game.on('reset', function () { // Reset all global variables and UI state countingDirection = 1; startNumber = 0; targetNumber = 10; currentNumber = 0; gameStarted = false; selectedTarget = null; selectedDirection = null; // Reset all selections selectedTarget = null; selectedDirection = null; // Clean up UI elements if any remain if (numberText) { numberText.destroy(); numberText = null; } if (numberReadingText) { numberReadingText.destroy(); numberReadingText = null; } if (infoText) { infoText.destroy(); infoText = null; } for (var i = 0; i < optionButtons.length; i++) { if (optionButtons[i]) { optionButtons[i].destroy(); } } optionButtons = []; for (var i = 0; i < directionButtons.length; i++) { if (directionButtons[i]) { directionButtons[i].destroy(); } } directionButtons = []; game._congratsShown = false; showMenu(); }); // --- INITIALIZE --- showMenu(); // Play the start sound only once at the start of the game LK.getSound('startbeep').play(); ; // Play background music (loops by default) LK.playMusic('bgmusic');
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x000000 // Black background
});
/****
* Game Code
****/
// --- GLOBALS ---
var puansayisi = 0; // Total score
var timeLeft; // Declare timeLeft for countdown timer
if (typeof timeLeft === "undefined") {
timeLeft = 50; // Only initialize to 50 if never defined
}
var tapCount = 0; // Counts taps until "Tebrikler" is shown
var countingDirection = 1; // 1: up, -1: down
var startNumber = 0;
var targetNumber = 10;
var currentNumber = 0;
var gameStarted = false;
var puanText = null; // Global reference to puan text
var congratsText = null; // Global reference to congratulations text
// --- LANGUAGE SUPPORT ---
var LANGUAGES = [{
code: "en",
label: "English"
}, {
code: "tr",
label: "Türkçe"
}];
var lang = "tr"; // default language
// Localization dictionary
var L10N = {
tr: {
increase: "Artarak",
decrease: "Azalarak",
selectTarget: "Hedef Seç",
selectDirection: "Yön Seç",
win: "Tebrikler!",
tapToCount: "Ekrana tıkla",
numberReading: function numberReading(n) {
return getNumberReadingTR(n);
}
},
en: {
increase: "Increasing",
decrease: "Decreasing",
selectTarget: "Select Target",
selectDirection: "Select Direction",
win: "Congratulations!",
tapToCount: "Tap to count",
numberReading: function numberReading(n) {
return getNumberReadingEN(n);
}
}
};
// UI elements
var numberText = null;
var numberReadingText = null;
var infoText = null;
var optionButtons = [];
var directionButtons = [];
var selectedTarget = null;
var selectedDirection = null;
var langButtons = [];
var selectText = null; // Make selectText global for cleanup
// --- UI HELPERS ---
// Create a button as a colored box with text, returns a Container
function createButton(label, x, y, width, height, color, onTap) {
var btn = new Container();
var box = btn.attachAsset('buttonBox', {
width: width,
height: height,
color: color,
anchorX: 0.5,
anchorY: 0.5
});
var txt = new Text2(label, {
size: 80,
fill: 0xFFFFFF
});
txt.anchor.set(0.5, 0.5);
txt.x = 0;
txt.y = 0;
btn.addChild(txt);
btn.x = x;
btn.y = y;
btn.interactive = true;
btn.down = function (x, y, obj) {
if (onTap) {
onTap();
}
};
return btn;
}
// --- GAME SETUP ---
// Helper to check if a number is prime
function isPrime(n) {
if (n < 2) return false;
for (var i = 2; i * i <= n; i++) {
if (n % i === 0) return false;
}
return true;
}
// Show a random two-digit number (10-99) above 'Sayıyı bul'
var randomNumber;
// Generate a random number that is a multiple of one of the available targets (1-25)
var possibleMultiples = [];
for (var mult = 1; mult <= 25; mult++) {
for (var factor = 2; factor <= 9; factor++) {
var product = mult * factor;
if (product >= 10 && product <= 99) {
possibleMultiples.push(product);
}
}
}
randomNumber = possibleMultiples[Math.floor(Math.random() * possibleMultiples.length)];
var randomNumberText = new Text2("" + randomNumber, {
size: 120,
fill: 0xFFFFFF
});
randomNumberText.anchor.set(0.5, 1);
randomNumberText.x = 2048 / 2;
// Move the bottom section higher up (e.g. 350px from bottom instead of 120px)
randomNumberText.y = 2732 - 350;
game.addChild(randomNumberText);
// Add 'Sayısı Hangi Sayının Katıdır?' text just below the random number
var findNumberLabel = lang === "en" ? "Which number is this a multiple of?" : "Sayısı Hangi Sayının Katıdır?";
var findNumberText = new Text2(findNumberLabel, {
size: 80,
fill: 0xFFFFFF
});
findNumberText.anchor.set(0.5, 0);
findNumberText.x = 2048 / 2;
findNumberText.y = randomNumberText.y + 20;
game.addChild(findNumberText);
// Show the pre-game menu: select target number and direction
function showMenu() {
gameStarted = false;
selectedTarget = null;
selectedDirection = null;
// Remove previous UI if any
if (numberText) {
numberText.destroy();
numberText = null;
}
if (numberReadingText) {
numberReadingText.destroy();
numberReadingText = null;
}
if (infoText) {
infoText.destroy();
infoText = null;
}
for (var i = 0; i < optionButtons.length; i++) {
optionButtons[i].destroy();
}
optionButtons = [];
for (var i = 0; i < directionButtons.length; i++) {
if (directionButtons[i]) {
directionButtons[i].destroy();
}
}
directionButtons = [];
for (var i = 0; i < langButtons.length; i++) {
langButtons[i].destroy();
}
langButtons = [];
// Remove infoText usage, but keep for cleanup
infoText = null;
// Remove back button if it exists (should not be visible in menu)
if (typeof backButton !== "undefined" && backButton) {
backButton.destroy();
backButton = null;
}
// --- LANGUAGE BUTTONS ---
var langBtnW = 320,
langBtnH = 100,
langBtnGap = 40;
var langBtnStartX = (2048 - (LANGUAGES.length * langBtnW + (LANGUAGES.length - 1) * langBtnGap)) / 2 + langBtnW / 2;
var langBtnY = 120;
for (var i = 0; i < LANGUAGES.length; i++) {
(function (idx) {
var l = LANGUAGES[idx];
var btn = createButton(l.label, langBtnStartX + idx * (langBtnW + langBtnGap), langBtnY, langBtnW, langBtnH, 0x888888, function () {
lang = l.code;
// Update the question text when language changes
if (findNumberText) {
var findNumberLabel = lang === "en" ? "Which number is this a multiple of?" : "Sayısı Hangi Sayının Katıdır?";
findNumberText.setText(findNumberLabel);
}
showMenu();
});
// Highlight selected language
btn.children[0].tint = lang === l.code ? 0xff0000 : 0xffffff;
langButtons.push(btn);
game.addChild(btn);
})(i);
}
// --- HEADER RECTANGLE ---
var headerHeight = 320; // Increased height for a more vertically extended header
var headerY = 420; // Moved header further down
var headerAssetId = lang === "en" ? "centerCircle1" : "centerCircle";
var headerRect = game.attachAsset(headerAssetId, {
width: 720,
// 10% smaller than 800
height: headerHeight,
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2,
y: headerY
});
// So it gets cleaned up with the rest of the menu
// Target number options (1-25) as a 5x5 grid
var targets = [];
for (var i = 1; i <= 25; i++) {
targets.push(i);
}
var btnW = 220 * 1.1,
// 10% larger
btnH = 220 * 1.1; // 10% larger, keep square
var gapX = 40;
var gapY = 40;
var gridCols = 5;
var gridRows = 5;
// Calculate total grid width and height
var gridTotalWidth = gridCols * btnW + (gridCols - 1) * gapX;
var gridTotalHeight = gridRows * btnH + (gridRows - 1) * gapY;
// Center grid on screen
var gridStartX = (2048 - gridTotalWidth) / 2 + btnW / 2;
var gridStartY = (2732 - gridTotalHeight) / 2 + btnH / 2;
for (var i = 0; i < targets.length; i++) {
(function (idx) {
var t = targets[idx];
var col = idx % gridCols;
var row = Math.floor(idx / gridCols);
var x = gridStartX + col * (btnW + gapX);
var y = gridStartY + row * (btnH + gapY);
var btn = createButton("" + t, x, y, btnW, btnH, 0x4a90e2, function () {
selectTarget(t, idx);
});
// If this target was previously selected, keep it red
if (selectedTarget !== null && selectedTarget === idx) {
btn.children[0].tint = 0xff0000;
}
optionButtons.push(btn);
game.addChild(btn);
})(i);
}
// (Removed 'Saymak istediğimiz sayıyı seçelim' text below the grid)
// No direction buttons on the first page
}
// When a target number is selected
function selectTarget(t, idx) {
LK.getSound('click').play();
targetNumber = t;
selectedTarget = idx;
// Highlight selected
for (var i = 0; i < optionButtons.length; i++) {
// Make selected target button red, others white
optionButtons[i].children[0].tint = i === idx ? 0xff0000 : 0xffffff;
}
// Animate selected button: jump up and down once
var btn = optionButtons[idx];
tween.stop(btn, {
y: true
});
var originalY = btn.y;
tween(btn, {
y: originalY - 80
}, {
duration: 240,
easing: tween.cubicOut,
onFinish: function onFinish() {
tween(btn, {
y: originalY
}, {
duration: 360,
easing: tween.bounceOut
});
}
});
// Enable direction buttons after a target is selected
for (var i = 0; i < directionButtons.length; i++) {
directionButtons[i].directionActive = true;
directionButtons[i].alpha = 1;
}
// Go to 2nd page (gameplay) immediately when a target is tapped
startGame();
}
// When a direction is selected
function selectDirection(dir, idx) {
LK.getSound('click').play();
countingDirection = dir;
selectedDirection = idx;
// Highlight selected
for (var i = 0; i < directionButtons.length; i++) {
// Make selected direction button red, others white
directionButtons[i].children[0].tint = i === idx ? 0xff0000 : 0xffffff;
// Animate selected direction button with jump effect
if (i === idx) {
tween.stop(directionButtons[i], {
y: true
});
var originalY = directionButtons[i].y;
tween(directionButtons[i], {
y: originalY - 80
}, {
duration: 320,
easing: tween.cubicOut,
onFinish: function (btn, oy) {
return function () {
tween(btn, {
y: oy
}, {
duration: 420,
easing: tween.bounceOut
});
};
}(directionButtons[i], originalY)
});
}
}
// If target already selected, start game after 1 second
if (selectedTarget !== null) {
LK.setTimeout(function () {
startGame();
}, 1000);
}
}
// --- GAMEPLAY ---
function startGame() {
// Remove menu UI
if (infoText) {
infoText.destroy();
infoText = null;
}
for (var i = 0; i < optionButtons.length; i++) {
optionButtons[i].destroy();
}
optionButtons = [];
for (var i = 0; i < directionButtons.length; i++) {
directionButtons[i].destroy();
}
directionButtons = [];
// (tapCountText cleanup removed - not used anymore)
// Remove "Saymak istediğimiz sayıyı seçelim" text if it exists
if (typeof selectText !== "undefined" && selectText) {
selectText.destroy();
selectText = null;
}
// Always start from 0, regardless of direction
startNumber = 0;
currentNumber = startNumber;
tapCount = 0; // Reset tap count for new game
// Show current number
// Calculate size to cover 50% of the screen height (2732 * 0.5 = 1366px)
// Text2 size is font size, so we estimate a bit smaller to fit: try 1200px
numberText = new Text2("" + currentNumber, {
size: 1200,
fill: 0xFFFFFF
});
numberText.anchor.set(0.5, 0.5);
numberText.x = 2048 / 2;
numberText.y = 2732 / 2;
game.addChild(numberText);
// --- GAMEPLAY ---
if (numberReadingText) {
numberReadingText.destroy();
numberReadingText = null;
}
// Dynamically fit numberReadingText to always fit on screen
var readingString = L10N[lang].numberReading(currentNumber);
var maxWidth = 2048 * 0.9; // 90% of screen width
var maxHeight = 220; // Max font size
var minFontSize = 80;
var fontSize = maxHeight;
var testText = null;
do {
if (testText) testText.destroy();
testText = new Text2(readingString, {
size: fontSize,
fill: 0xFFFFFF
});
testText.anchor.set(0.5, 0);
} while ((testText.width > maxWidth || testText.height > 300) && fontSize-- > minFontSize);
if (testText) testText.destroy();
numberReadingText = new Text2(readingString, {
size: fontSize,
fill: 0xFFFFFF
});
numberReadingText.anchor.set(0.5, 0);
numberReadingText.x = 2048 / 2;
// Move the number reading text higher up (was: numberText.y + numberText.height / 2 + 40)
numberReadingText.y = numberText.y + numberText.height / 2 - 120;
game.addChild(numberReadingText);
gameStarted = true;
// --- Add 'İleri' and 'Geri' overlays ---
var ileriLabel = lang === "en" ? "Forward" : "İleri";
var ileriText = new Text2(ileriLabel, {
size: 120,
fill: 0xffffff
});
ileriText.anchor.set(0.5, 0.5);
ileriText.x = 2048 * 0.75;
ileriText.y = 2732 / 2;
game.addChild(ileriText);
var geriLabel = lang === "en" ? "Back" : "Geri";
var geriText = new Text2(geriLabel, {
size: 180,
fill: 0xffffff
});
geriText.anchor.set(0.5, 0.5);
geriText.x = 2048 * 0.25;
geriText.y = 2732 / 2;
game.addChild(geriText);
// Store for later removal
game._ileriText = ileriText;
game._geriText = geriText;
// --- DIRECTION BUTTONS REMOVED FROM GAMEPLAY ---
// No direction buttons in gameplay
directionButtons = [];
// --- BACK BUTTON IN GAMEPLAY ---
var backButton = null; // Declare backButton variable first
if (backButton) {
backButton.destroy();
backButton = null;
}
var backButtonLabel = lang === "en" ? "Back" : "Anasayfa";
var langBtnW = 320,
langBtnH = 100; // match language button size
// Create the back button using the same font size as 'Yeniden Başla' (54)
// puansayisi is already defined globally, no need to redefine
// Back button (Anasayfa)
var backButton = new Container();
var backBox = backButton.attachAsset('buttonBox', {
width: langBtnW,
height: langBtnH,
color: 0x888888,
anchorX: 0.5,
anchorY: 0.5
});
var backTxt = new Text2(backButtonLabel, {
size: 70,
// Increased font size for better visibility
fill: 0xFFFFFF
});
backTxt.anchor.set(0.5, 0.5);
backTxt.x = 0;
backTxt.y = 0;
backButton.addChild(backTxt);
backButton.x = 2048 - 100 - langBtnW / 2;
backButton.y = 100 + langBtnH / 2;
backButton.interactive = true;
backButton.down = function (x, y, obj) {
// Defensive: prevent double tap
if (!gameStarted) return;
gameStarted = false;
// Clean up gameplay UI
if (numberText) {
numberText.destroy();
numberText = null;
}
if (numberReadingText) {
numberReadingText.destroy();
numberReadingText = null;
}
for (var i = 0; i < directionButtons.length; i++) {
if (directionButtons[i]) directionButtons[i].destroy();
}
directionButtons = [];
if (typeof backButton !== "undefined" && backButton) {
backButton.destroy();
backButton = null;
}
if (puanText) {
puanText.destroy();
puanText = null;
}
// Clean up congratulations text
if (congratsText) {
congratsText.destroy();
congratsText = null;
}
// Clean up timer
if (game._timerInterval) {
LK.clearInterval(game._timerInterval);
game._timerInterval = null;
}
if (game._timerContainer) {
game._timerContainer.destroy();
game._timerContainer = null;
}
// Do NOT reset timeLeft here; keep its value for next gameplay
showMenu();
};
backButton.children[0].tint = 0xffffff;
game.addChild(backButton);
// Add 'Puan: <puansayisi>' text below the Anasayfa button
if (puanText) {
puanText.destroy();
puanText = null;
}
var puanLabel = lang === "en" ? "Score: " : "Puan: ";
puanText = new Text2(puanLabel + puansayisi, {
size: 80,
fill: 0xffffff
});
puanText.anchor.set(0.5, 0);
puanText.x = backButton.x;
puanText.y = backButton.y + langBtnH / 2 + 16;
game.addChild(puanText);
// Add circular countdown timer below puan text
var timerContainer = new Container();
timerContainer.x = puanText.x;
timerContainer.y = puanText.y + 250; // Moved timer even lower
game.addChild(timerContainer);
// Store reference for access in other scopes
game._timerContainer = timerContainer;
// Create circular background
var timerBg = timerContainer.attachAsset('centerCircle2', {
width: 150,
height: 150,
anchorX: 0.5,
anchorY: 0.5,
tint: 0x333333
});
// Create timer text
var timerText = new Text2("" + timeLeft, {
size: 60,
fill: 0xffffff
});
timerText.anchor.set(0.5, 0.5);
timerContainer.addChild(timerText);
// Start countdown using global timeLeft and timerInterval
// Only reset timeLeft to 50 on very first gameplay entry
if (typeof timeLeft === "undefined" || timeLeft === null || timeLeft === 50) {
timeLeft = 50;
}
if (game._timerInterval) {
LK.clearInterval(game._timerInterval);
game._timerInterval = null;
}
game._timerInterval = LK.setInterval(function () {
timeLeft--;
if (timeLeft >= 0) {
timerText.setText("" + timeLeft);
// Pulse animation when time is running low
if (timeLeft <= 5) {
if (timerContainer) {
tween(timerContainer, {
scaleX: 1.2,
scaleY: 1.2
}, {
duration: 300,
easing: tween.easeOut,
onFinish: function onFinish() {
if (timerContainer) {
tween(timerContainer, {
scaleX: 1,
scaleY: 1
}, {
duration: 300,
easing: tween.easeIn
});
}
}
});
}
// Change color to red when low on time
timerText.tint = 0xff0000;
}
} else {
// Time's up
LK.clearInterval(game._timerInterval);
game._timerInterval = null;
// Clear all game elements
if (numberText) {
numberText.destroy();
numberText = null;
}
if (numberReadingText) {
numberReadingText.destroy();
numberReadingText = null;
}
if (typeof backButton !== "undefined" && backButton) {
backButton.destroy();
backButton = null;
}
if (game._ileriText) {
game._ileriText.destroy();
game._ileriText = null;
}
if (game._geriText) {
game._geriText.destroy();
game._geriText = null;
}
if (timerContainer) {
timerContainer.destroy();
timerContainer = null;
}
// Hide puan text
if (puanText) {
puanText.destroy();
puanText = null;
}
// Hide random number and "whose multiple" text
if (randomNumberText) {
randomNumberText.visible = false;
}
if (findNumberText) {
findNumberText.visible = false;
}
// Show only score and congratulations
var finalScoreText = new Text2("" + puansayisi, {
size: 300,
fill: 0xffffff
});
finalScoreText.anchor.set(0.5, 0.5);
finalScoreText.x = 2048 / 2;
finalScoreText.y = 2732 / 2 - 200;
game.addChild(finalScoreText);
var congratsText = new Text2(L10N[lang].win, {
size: 220,
fill: 0x00ff00
});
congratsText.anchor.set(0.5, 0.5);
congratsText.x = 2048 / 2;
congratsText.y = 2732 / 2 + 200;
game.addChild(congratsText);
// Show game over after 2 seconds
LK.setTimeout(function () {
LK.showGameOver();
}, 2000);
}
}, 1000);
// Store timer references for cleanup
game._timerContainer = timerContainer;
}
// --- Number Reading Helper (Turkish) ---
function getNumberReadingTR(n) {
// Only works for 0-250, but covers all gameplay needs
var birler = ["", "BİR", "İKİ", "ÜÇ", "DÖRT", "BEŞ", "ALTI", "YEDİ", "SEKİZ", "DOKUZ"];
var onlar = ["", "ON", "YİRMİ", "OTUZ", "KIRK", "ELLİ", "ALTMIŞ", "YETMİŞ", "SEKSEN", "DOKSAN"];
var yuzler = ["", "YÜZ", "İKİYÜZ"];
n = Math.floor(n);
if (n < 0) {
return "";
}
if (n === 0) {
return "SIFIR";
}
if (n > 250) {
return "" + n;
} // fallback
var y = Math.floor(n / 100);
var o = Math.floor(n % 100 / 10);
var b = n % 10;
var parts = [];
if (y > 0) {
if (y === 1) {
parts.push("YÜZ");
} else {
parts.push(birler[y] + " YÜZ");
}
}
if (o > 0) {
parts.push(onlar[o]);
}
if (b > 0) {
parts.push(birler[b]);
}
return parts.join(" ");
}
// --- Number Reading Helper (English) ---
function getNumberReadingEN(n) {
// Only works for 0-250, covers all gameplay needs
var ones = ["", "ONE", "TWO", "THREE", "FOUR", "FIVE", "SIX", "SEVEN", "EIGHT", "NINE"];
var tens = ["", "TEN", "TWENTY", "THIRTY", "FORTY", "FIFTY", "SIXTY", "SEVENTY", "EIGHTY", "NINETY"];
var hundreds = ["", "ONE HUNDRED", "TWO HUNDRED"];
n = Math.floor(n);
if (n < 0) {
return "";
}
if (n === 0) {
return "ZERO";
}
if (n > 250) {
return "" + n;
} // fallback
var y = Math.floor(n / 100);
var o = Math.floor(n % 100 / 10);
var b = n % 10;
var parts = [];
if (y > 0) {
if (y === 1 && o === 0 && b === 0) {
parts.push("ONE HUNDRED");
} else {
parts.push(ones[y] + " HUNDRED");
}
}
if (o > 0) {
parts.push(tens[o]);
}
if (b > 0) {
parts.push(ones[b]);
}
return parts.join(" ");
}
// --- GAME INTERACTION ---
// On tap/click anywhere, increment or decrement number
game.down = function (x, y, obj) {
if (!gameStarted) {
// Start countdown on first tap
if (!game._timerInterval) {
game._timerInterval = LK.setInterval(function () {
timeLeft--;
if (timeLeft >= 0) {
if (game._timerContainer && game._timerContainer.children[1]) {
game._timerContainer.children[1].setText("" + timeLeft);
}
if (timeLeft <= 5) {
if (game._timerContainer) {
tween(game._timerContainer, {
scaleX: 1.2,
scaleY: 1.2
}, {
duration: 300,
easing: tween.easeOut,
onFinish: function onFinish() {
if (game._timerContainer) {
tween(game._timerContainer, {
scaleX: 1,
scaleY: 1
}, {
duration: 300,
easing: tween.easeIn
});
}
}
});
}
if (game._timerContainer && game._timerContainer.children[1]) {
game._timerContainer.children[1].tint = 0xff0000;
}
}
} else {
LK.clearInterval(game._timerInterval);
if (numberText) {
numberText.destroy();
numberText = null;
}
if (numberReadingText) {
numberReadingText.destroy();
numberReadingText = null;
}
if (typeof backButton !== "undefined" && backButton) {
backButton.destroy();
backButton = null;
}
if (game._ileriText) {
game._ileriText.destroy();
game._ileriText = null;
}
if (game._geriText) {
game._geriText.destroy();
game._geriText = null;
}
if (game._timerContainer) {
game._timerContainer.destroy();
game._timerContainer = null;
}
// Hide puan text
if (puanText) {
puanText.destroy();
puanText = null;
}
// Hide random number and "whose multiple" text
if (randomNumberText) {
randomNumberText.visible = false;
}
if (findNumberText) {
findNumberText.visible = false;
}
var finalScoreText = new Text2("" + puansayisi, {
size: 300,
fill: 0xffffff
});
finalScoreText.anchor.set(0.5, 0.5);
finalScoreText.x = 2048 / 2;
finalScoreText.y = 2732 / 2 - 200;
game.addChild(finalScoreText);
var congratsText = new Text2(L10N[lang].win, {
size: 220,
fill: 0x00ff00
});
congratsText.anchor.set(0.5, 0.5);
congratsText.x = 2048 / 2;
congratsText.y = 2732 / 2 + 200;
game.addChild(congratsText);
LK.setTimeout(function () {
LK.showGameOver();
}, 2000);
}
}, 1000);
}
return;
}
// Remove 'İleri' and 'Geri' overlays on first tap
if (game._ileriText) {
game._ileriText.destroy();
game._ileriText = null;
}
if (game._geriText) {
game._geriText.destroy();
game._geriText = null;
}
LK.getSound('click').play();
// --- TAP COUNT: Increase tap count only in gameplay (2nd screen) ---
if (gameStarted) {
tapCount = tapCount + 1;
}
// Increment if tapped on right half, decrement if tapped on left half
if (x > 2048 / 2) {
currentNumber += targetNumber;
} else {
currentNumber -= targetNumber;
if (currentNumber < 0) {
currentNumber = 0;
}
}
// Animate numberText (scale up and back) only if numberText exists
if (numberText) {
tween(numberText, {
scaleX: 1.2,
scaleY: 1.2
}, {
duration: 80,
easing: tween.easeOut,
onFinish: function onFinish() {
if (numberText) {
tween(numberText, {
scaleX: 1,
scaleY: 1
}, {
duration: 80,
easing: tween.easeIn
});
}
}
});
}
// Animate selected target button (jump effect) on every tap
if (selectedTarget !== null && Array.isArray(optionButtons) && optionButtons[selectedTarget] && typeof optionButtons[selectedTarget].y !== "undefined") {
var btn = optionButtons[selectedTarget];
tween.stop(btn, {
y: true
});
var originalY = btn.y;
tween(btn, {
y: originalY - 80
}, {
duration: 240,
easing: tween.cubicOut,
onFinish: function onFinish() {
tween(btn, {
y: originalY
}, {
duration: 360,
easing: tween.bounceOut
});
}
});
}
// (Handled above with tapCount logic)
if (numberText) {
numberText.setText("" + currentNumber);
}
// Update number reading text
if (numberReadingText) {
// Dynamically fit numberReadingText to always fit on screen after increment/decrement
var readingString = L10N[lang].numberReading(currentNumber);
var maxWidth = 2048 * 0.9;
var maxHeight = 220;
var minFontSize = 80;
var fontSize = maxHeight;
var testText = null;
do {
if (testText) testText.destroy();
testText = new Text2(readingString, {
size: fontSize,
fill: 0xFFFFFF
});
testText.anchor.set(0.5, 0);
} while ((testText.width > maxWidth || testText.height > 300) && fontSize-- > minFontSize);
if (testText) testText.destroy();
numberReadingText.setStyle({
size: fontSize
});
numberReadingText.setText(readingString);
}
if (currentNumber === randomNumber) {
// Clean up any existing congratulations text
if (congratsText) {
congratsText.destroy();
congratsText = null;
}
// Show 'Tebrikler!' (Congratulations!) in the center of the screen
congratsText = new Text2(L10N[lang].win, {
size: 220,
fill: 0x00ff00
});
congratsText.anchor.set(0.5, 0.5);
congratsText.x = 2048 / 2;
congratsText.y = 2732 / 2 - 600;
game.addChild(congratsText);
// --- SCORE CALCULATION: Add (100 - tapCount) to puansayisi ---
var scoreToAdd = 100 - tapCount;
puansayisi = puansayisi + scoreToAdd;
// Update puan text display
if (puanText) {
var puanLabel = lang === "en" ? "Score: " : "Puan: ";
puanText.setText(puanLabel + puansayisi);
}
// Reset tap count for next round
tapCount = 0;
// Do NOT reset timer when target is reached - just continue with current time
// Optionally, fade out after 2 seconds, but do NOT reset game automatically
tween(congratsText, {
alpha: 0
}, {
duration: 1800,
delay: 1200,
onFinish: function onFinish() {
if (congratsText) {
congratsText.destroy();
congratsText = null;
}
// Do not destroy kalanText here, keep it visible
// Do not call showMenu(); user must press back to return
}
});
// Refresh the random number and update its text after congrats (always two-digit)
// Generate a random number that is a multiple of one of the available targets (1-25)
var possibleMultiples = [];
for (var mult = 1; mult <= 25; mult++) {
for (var factor = 2; factor <= 9; factor++) {
var product = mult * factor;
if (product >= 10 && product <= 99) {
possibleMultiples.push(product);
}
}
}
randomNumber = possibleMultiples[Math.floor(Math.random() * possibleMultiples.length)];
if (randomNumberText) {
randomNumberText.setText("" + randomNumber);
}
}
};
// --- GAME RESET ---
// When game is reset, show menu again
game.on('reset', function () {
// Reset all global variables and UI state
countingDirection = 1;
startNumber = 0;
targetNumber = 10;
currentNumber = 0;
gameStarted = false;
selectedTarget = null;
selectedDirection = null;
// Reset all selections
selectedTarget = null;
selectedDirection = null;
// Clean up UI elements if any remain
if (numberText) {
numberText.destroy();
numberText = null;
}
if (numberReadingText) {
numberReadingText.destroy();
numberReadingText = null;
}
if (infoText) {
infoText.destroy();
infoText = null;
}
for (var i = 0; i < optionButtons.length; i++) {
if (optionButtons[i]) {
optionButtons[i].destroy();
}
}
optionButtons = [];
for (var i = 0; i < directionButtons.length; i++) {
if (directionButtons[i]) {
directionButtons[i].destroy();
}
}
directionButtons = [];
game._congratsShown = false;
showMenu();
});
// --- INITIALIZE ---
showMenu();
// Play the start sound only once at the start of the game
LK.getSound('startbeep').play();
;
// Play background music (loops by default)
LK.playMusic('bgmusic');