User prompt
Remove a proper starting overlay screen that disappears on tap and then starts the game
User prompt
Doğru şekilde yapar mısın peki
User prompt
Oyuna giriş ekranını kaldır oyunu bozdu
User prompt
Oyuna başlamak için dokun dedikten sonra oyuna start ver
User prompt
Başlamak için dokunun dediğimde başlamıyor sade ai animasyonunu görüyorum başka bir şey yok
User prompt
Oyuna giriş ekranı yapabilir misin ama mevcut oyunu bozmani istemiyorum
User prompt
Play 'oyunahosgeldin' sound once at the start of the game one seconds later
User prompt
When I log in to the game, a welcome sound should play. Sound name oyunahosgeldin
User prompt
Ben ses dosyasını ekledim sende oyuna ekle sesin adı oyunahosgeldin
User prompt
Play 'sonbirdakika' sound when only 1 minutes remain on the timer
User prompt
Time left de son 2 dakika kalınca sesli olarak son 2 dakika desin ses dosyasının ismi sonikidakika
User prompt
Son ekledigim sesleri ekle sayılar çıktığında sesli söyleyecek
User prompt
Please fix the bug: 'Uncaught ReferenceError: timeLeft is not defined' in or related to this line: 'timeLeft[p] += 1000;' Line Number: 296
User prompt
Reduce the scale pulse effect when a called number matches a cell (so the size increase is less dramatic)
User prompt
Çıkan sayıları kacirdigim zaman size büyümesin bu kadar biraz küçült
User prompt
Aiplayer animasyon pozsiyonunu kartları üst ortasına yerlestir
User prompt
Kartlar küçük oldu ekrana göre bence büyütelim
User prompt
2 bingo kartı daha ekle aşağıya aynı hizalarda yapay zeka oynasın onuda Aiplayer
User prompt
Çok büyük oldu düşür
User prompt
Sayı tablosu size i sayı çıktığında efekt ↪💡 Consider importing and using the following plugins: @upit/tween.v1
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var storage = LK.import("@upit/storage.v1"); /**** * Classes ****/ // AI Robot: Animated character that dances in place (no left/right movement) var AIRobot = Container.expand(function () { var self = Container.call(this); // Attach a robot body (use aiIndicator image as the robot's head/body) var robotBody = self.attachAsset('aiIndicator', { anchorX: 0.5, anchorY: 0.5 }); // Add two "eyes" using small ellipses var leftEye = self.attachAsset('freeSpace', { width: 24, height: 24, color: 0xffffff, anchorX: 0.5, anchorY: 0.5 }); var rightEye = self.attachAsset('freeSpace', { width: 24, height: 24, color: 0xffffff, anchorX: 0.5, anchorY: 0.5 }); leftEye.x = -36; leftEye.y = -20; rightEye.x = 36; rightEye.y = -20; // Animation state self.danceTick = 0; // Initial position self.x = 2048 * 3 / 4; self.y = 2732 - 180; // Update method for in-place dance animation self.update = function () { // Dance in place: gentle rotation and scale pulse self.danceTick++; // Rotate gently back and forth self.rotation = Math.sin(self.danceTick / 30) * 0.18; // Scale up and down for a "bounce" effect var scalePulse = 1 + Math.sin(self.danceTick / 18) * 0.07; self.scale.x = scalePulse; self.scale.y = 1 - Math.sin(self.danceTick / 18) * 0.04; // Eyes: blink or wiggle in place var eyeWiggle = Math.sin(self.danceTick / 10) * 2; leftEye.x = -36 + eyeWiggle; rightEye.x = 36 - eyeWiggle; }; return self; }); // BingoCell: Represents a single cell on the bingo card var BingoCell = Container.expand(function () { var self = Container.call(this); // Properties self.number = 0; self.marked = false; // --- New theme: deep navy background, blue border, and subtle star/planet decor --- var cellBg = self.attachAsset('Background', { width: cellSize, height: cellSize, color: 0x181c24, // Deep navy anchorX: 0.5, anchorY: 0.5 }); cellBg.radius = cellSize * 0.22; // Simulate rounded corners (if supported by engine) // Add a subtle blue border for effect var border = self.attachAsset('Background', { width: cellSize * 0.98, height: cellSize * 0.98, color: 0x3e8ed0, // Blue border anchorX: 0.5, anchorY: 0.5 }); border.radius = cellSize * 0.19; border.alpha = 0.7; // No decorative stars or planet for plain black cell self.stars = []; // Number text var numberText = new Text2('', { size: Math.floor(cellSize * 0.45), fill: 0xff0000 // Red for card numbers }); numberText.anchor.set(0.5, 0.5); self.addChild(numberText); // --- Mark overlay: blue ellipse, hidden by default --- var markOverlay = self.attachAsset('winHighlight', { width: cellSize * 0.82, height: cellSize * 0.82, anchorX: 0.5, anchorY: 0.5 }); markOverlay.alpha = 0; markOverlay.color = 0xff69b4; // Pink for new theme self.markOverlay = markOverlay; // --- Glow effect: subtle blue glow when marked --- var glow = self.attachAsset('freeSpace', { width: cellSize * 1.18, height: cellSize * 1.18, color: 0x3e8ed0, // Blue glow anchorX: 0.5, anchorY: 0.5 }); glow.alpha = 0; self.glow = glow; // Set number and update text self.setNumber = function (num) { self.number = num; numberText.setText(num > 0 ? num : ''); }; // Mark/unmark cell self.setMarked = function (val) { self.marked = val; if (val) { // Animate mark overlay in markOverlay.alpha = 1; // Animate glow in tween(glow, { alpha: 0.22 }, { duration: 200, easing: tween.easeOut }); numberText.setText(self.number); numberText.setStyle({ fill: 0xff0000 // Red for marked number }); } else { // Animate mark overlay out markOverlay.alpha = 0; // Animate glow out tween(glow, { alpha: 0 }, { duration: 200, easing: tween.easeOut }); numberText.setStyle({ fill: 0xff0000 // Red for unmarked number }); } }; // Touch event self.down = function (x, y, obj) { // Play click sound on any cell tap LK.getSound('Click').play(); if (self.marked) return; if (game.state !== 'playing') return; var p = self.playerIndex !== undefined ? self.playerIndex : 0; if (self.number === game.currentNumber && p === currentPlayer) { self.setMarked(true); // Flash with yellow and pulse LK.effects.flashObject(self, 0xfff200, 200); tween(self.scale, { x: 1.13, y: 1.13 }, { duration: 120, yoyo: true, repeat: 1, easing: tween.easeOut }); // Streak logic if (typeof streak !== "undefined") { streak[p]++; if (streak[p] > 1) { timeLeft[p] += 1000; } } game.checkWin(); } else { if (typeof streak !== "undefined") { streak[p] = 0; } LK.effects.flashObject(self, 0x8b0000, 200); } }; // Always update lastX and lastY at the end self.lastX = self.x; self.lastY = self.y; return self; }); // CalledNumberBall: Shows a called number as a round ball var CalledNumberBall = Container.expand(function () { var self = Container.call(this); // Ball background var ball = self.attachAsset('bingoBall', { anchorX: 0.5, anchorY: 0.5 }); // Number text var numberText = new Text2('', { size: 60, fill: 0x000000 }); numberText.anchor.set(0.5, 0.5); numberText.x = 0; numberText.y = 0; self.addChild(numberText); self.setNumber = function (num) { numberText.setText(num); }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x101218 // Even darker navy for dark theme }); /**** * Game Code ****/ // Ses assets for ses1 to ses40 // Deep green // Sunlight // Forest green // Fern green // Pale green // Sunlight // Light moss // Sunlight // Light brown // Fern green // Forest green // Pale green // Mushroom cap // Forest flower // Blue pond // Deep green // Light brown // Pale green overlay // Deep green // Forest green // Fern swirl // Pale green bg // Sunlight free space // Forest green // Pale green // Fern green // Light brown confetti // Sunlight confetti // Deep green border // Pale green // Deep green pressed // Fern green hover // Light moss cell // Forest green ball // Candy pink // Candy orange // Candy pink // Mint green // Light pink // Pastel yellow // Pastel orange // Candy pink // Candy orange // Mint green // Candy pink // Light pink // Candy pink // Pastel purple // Pastel blue // Mint green // Pastel orange // Light pink // Candy orange // Candy pink // Mint green // Light pink // Candy orange // Candy pink // Light pink // Mint green // Candy orange // Candy pink // Mint green // Light pink // Candy orange // Mint green // Pastel orange // Candy pink // Neon pink // Neon yellow // Neon pink // Neon cyan // Purple // Neon yellow // Deep retro blue // Neon pink // Neon yellow // Neon cyan // Neon pink // Purple // Neon yellow // Neon pink // Neon cyan // Neon cyan // Deep retro blue // Purple // Neon yellow // Neon pink // Neon cyan // Deep retro blue // Neon yellow // Neon pink // Purple // Neon cyan // Neon yellow // Neon pink // Neon cyan // Purple // Neon yellow // Neon cyan // Deep retro blue // Neon pink // Sounds // Images (IDs are placeholders, replace with real asset IDs as needed) // Space/galaxy themed power-up icons // Space/galaxy themed overlays for cards // Space/galaxy decorative shapes // Space/Galaxy themed assets for richer visuals // Star yellow // Star yellow // Deep blue // Neon green // Space shadow // Space black // Neon green // Neon cyan // Space shadow // Light blue // Star yellow // Neon green // Galaxy border // Space black // Dark blue for pressed // Cyan for hover // Deep space blue // Neon blue planet // Sounds // New image assets for polish (IDs are placeholders, replace with real IDs if available) // Images // New shapes for improved UI // Bingo game shapes // --- Hint Power-Up Button --- // --- Functions --- // --- Kaydet (Save) Functionality --- // Save the current game state (called numbers, card numbers, marked cells, time left, streaks) // --- Added ses41 to ses75 sound assets (IDs to be filled by asset loader) --- function kaydetOyunu() { // Prepare save data var saveData = { calledNumbers: calledNumbers.slice(), cardNumbers: [cardNumbers[0] ? cardNumbers[0].map(function (col) { return col.slice(); }) : [], cardNumbers[1] ? cardNumbers[1].map(function (col) { return col.slice(); }) : []], marked: [bingoCells[0] ? bingoCells[0].map(function (cell) { return cell.marked; }) : [], bingoCells[1] ? bingoCells[1].map(function (cell) { return cell.marked; }) : []], gameDuration: gameDuration, streak: streak.slice(), currentPlayer: currentPlayer, gameOver: gameOver, state: game.state, availableNumbers: availableNumbers.slice(), currentNumber: game.currentNumber }; storage['bingo_save'] = saveData; } // Load the saved game state (if any) function yukleOyunu() { var saveData = storage['bingo_save']; if (!saveData) return false; // Restore state calledNumbers = saveData.calledNumbers || []; cardNumbers = [saveData.cardNumbers[0] ? saveData.cardNumbers[0].map(function (col) { return col.slice(); }) : [], saveData.cardNumbers[1] ? saveData.cardNumbers[1].map(function (col) { return col.slice(); }) : []]; availableNumbers = saveData.availableNumbers ? saveData.availableNumbers.slice() : []; gameDuration = saveData.gameDuration || 180000; streak = saveData.streak ? saveData.streak.slice() : [0, 0]; currentPlayer = typeof saveData.currentPlayer === "number" ? saveData.currentPlayer : 0; gameOver = !!saveData.gameOver; game.state = saveData.state || 'playing'; game.currentNumber = typeof saveData.currentNumber === "number" ? saveData.currentNumber : null; // Re-create cards and marked cells for (var p = 0; p < playerCount; p++) { if (!cardNumbers[p] || cardNumbers[p].length === 0) continue; if (!bingoCells[p]) bingoCells[p] = []; for (var i = 0; i < bingoCells[p].length; i++) { if (bingoCells[p][i]) { bingoCells[p][i].destroy(); } } bingoCells[p] = []; } createBingoCards(); // Restore marked cells for (var p = 0; p < playerCount; p++) { if (!saveData.marked[p]) continue; for (var i = 0; i < saveData.marked[p].length; i++) { if (bingoCells[p][i]) { bingoCells[p][i].setMarked(!!saveData.marked[p][i]); } } } // Restore timers, streaks, UI if (timerInterval) LK.clearInterval(timerInterval); updateTimerText(); ensureTimerTextOnGui(); timerInterval = LK.setInterval(function () { gameDuration -= 100; if (gameDuration < 0) gameDuration = 0; updateTimerText(); if (gameDuration <= 0 && !gameOver) { endGame(false, 0); } }, 100); updateCalledBallsUI(); numberCallText.setText(game.currentNumber ? game.currentNumber : ''); return true; } // Bingo ball (yellow ellipse) // Bingo cell background (cyan box) // Mark overlay (beige box, used for marking cells) // Hint button background (green box, used for hint power-up) // Free space overlay (distinct color for center cell) // Win highlight overlay (gold ellipse for winning line) // Reveal Row button removed // Freeze Timer button and logic removed // Ses assets for ses1 to ses40 var gridSize = 5; // 5x5 bingo // Adjust cellSize and card positions for four-player mode in 2x2 grid var cellSize = 140; // px, bigger cards for better visibility var cardPadding = 20; var cardWidth = gridSize * cellSize; var cardHeight = gridSize * cellSize; var cardStartX = 2048 / 4 - cardWidth / 2; // Base X position var cardStartY = 420; // Top row Y position var cardBottomY = 1600; // Bottom row Y position var callIntervalStart = 4000; // ms (4 seconds initial call speed) var callIntervalMin = 1200; // ms (slower minimum speed) var callIntervalStep = 60; // ms, decrease per call (slower speedup) var gameDuration = 180000; // ms (3 minutes) // Timer UI // Timer UI - Simplified and moved to better position var timerBg = LK.getAsset('timerBackground', { anchorX: 0.5, anchorY: 0.5, width: 340, height: 100 }); var timerText = new Text2('', { size: 90, fill: 0xffffff // White for better visibility }); timerText.anchor.set(0.5, 0.5); function updateTimerText() { var t = Math.max(0, Math.floor(gameDuration / 1000)); var min = Math.floor(t / 60); var sec = t % 60; var secStr = sec < 10 ? '0' + sec : sec; timerText.setText(min + ':' + secStr); } function ensureTimerTextOnGui() { // Position timer at the top of the screen timerBg.x = 2048 / 2; timerBg.y = 200; // Move to top of screen timerText.x = 2048 / 2; timerText.y = 200; // Add to game instead of GUI to align with called balls if (game.children.indexOf(timerBg) === -1) { game.addChild(timerBg); } if (game.children.indexOf(timerText) === -1) { game.addChild(timerText); } } // Initialize timer position ensureTimerTextOnGui(); var numbersRange = 75; // 1-75 // --- State --- // Four player support - 1 human + 3 AI var playerCount = 4; var currentPlayer = 0; // 0 = human, 1,2,3 = AI var bingoCells = [[], [], [], []]; // bingoCells for each player var calledNumbers = []; var availableNumbers = []; var callTimer = null; var timerInterval = null; var cardNumbers = [[], [], [], []]; var gameOver = false; var playerNames = ["You", "AI 1", "AI 2", "AI 3"]; var winText = [null, null, null, null]; // Per player var streak = [0, 0, 0, 0]; var streakText = [null, null, null, null]; // --- Ava: Add timeLeft array for per-player time bonuses (fix ReferenceError) --- var timeLeft = [0, 0, 0, 0]; // Freeze Timer state arrays removed // --- Freeze Timer compatibility: define freezeTimerActive as always-false array for each player --- var freezeTimerActive = [false, false, false, false]; // --- UI Elements --- // Container for called number balls var calledBallsContainer = new Container(); calledBallsContainer.x = 2048 / 2; calledBallsContainer.y = 2732 - 120; game.addChild(calledBallsContainer); // Show the latest called numbers as balls (max 6) function updateCalledBallsUI() { // Remove old balls while (calledBallsContainer.children.length > 0) { calledBallsContainer.removeChild(calledBallsContainer.children[0]); } var maxBalls = 6; var startIdx = Math.max(0, calledNumbers.length - maxBalls); var ballsToShow = calledNumbers.slice(startIdx); var spacing = 100; var totalWidth = (ballsToShow.length - 1) * spacing; for (var i = 0; i < ballsToShow.length; i++) { var ball = new CalledNumberBall(); ball.setNumber(ballsToShow[i]); ball.x = -totalWidth / 2 + i * spacing; ball.y = 0; // Animate in the newest ball if (i === ballsToShow.length - 1) { ball.scale.x = 0.1; ball.scale.y = 0.1; tween(ball.scale, { x: 1, y: 1 }, { duration: 180, easing: tween.easeOut }); } calledBallsContainer.addChild(ball); } } var numberCallText = new Text2('', { size: 180, fill: 0x3e8ed0 // Blue for new theme }); numberCallText.anchor.set(0.5, 0.5); numberCallText.x = 2048 / 2; numberCallText.y = 2732 - 380; game.addChild(numberCallText); // Number left text UI removed var winText = new Text2('', { size: 90, fill: 0x3e8ed0 // Blue for new theme }); winText.anchor.set(0.5, 0.5); winText.x = 2048 / 2; winText.y = 2732 / 2; winText.visible = false; game.addChild(winText); // --- Functions --- // Example: Trigger action when a cell intersects with another object (e.g. another cell or a special marker) // Assume we have a global reference to a special object, e.g. specialMarker // (You would need to define specialMarker somewhere in your game if you want to use this for real) if (typeof specialMarker !== "undefined" && bingoCells && bingoCells[0]) { for (var i = 0; i < bingoCells[0].length; i++) { var cell = bingoCells[0][i]; if (cell.lastWasIntersecting === false && cell.intersects(specialMarker)) { // Place your action here, e.g. console.log("Cell just started intersecting with specialMarker!"); } cell.lastWasIntersecting = cell.intersects(specialMarker); } } // Generate a random bingo card (5x5, center is free) function generateCardNumbers() { var nums = []; var used = []; for (var col = 0; col < gridSize; col++) { var colNums = []; var min = col * 15 + 1; var max = min + 14; for (var row = 0; row < gridSize; row++) { if (col === 2 && row === 2) { colNums.push(0); // Free space continue; } var n; do { n = min + Math.floor(Math.random() * (max - min + 1)); } while (used.indexOf(n) !== -1); used.push(n); colNums.push(n); } nums.push(colNums); } return nums; } // Create bingo card UI for all four players in 2x2 grid function createBingoCards() { for (var p = 0; p < playerCount; p++) { bingoCells[p] = []; cardNumbers[p] = generateCardNumbers(); // Position cards in 2x2 grid: // Player 0 (top-left), Player 1 (top-right), Player 2 (bottom-left), Player 3 (bottom-right) var cardCenterX, cardCenterY; if (p === 0) { // Top-left (You) cardCenterX = 2048 / 4; cardCenterY = cardStartY; } else if (p === 1) { // Top-right (AI 1) cardCenterX = 2048 * 3 / 4; cardCenterY = cardStartY; } else if (p === 2) { // Bottom-left (AI 2) cardCenterX = 2048 / 4; cardCenterY = cardBottomY; } else { // Bottom-right (AI 3) cardCenterX = 2048 * 3 / 4; cardCenterY = cardBottomY; } var offsetX = cardCenterX - cardWidth / 2; var offsetY = cardCenterY; for (var col = 0; col < gridSize; col++) { for (var row = 0; row < gridSize; row++) { var cell = new BingoCell(); var x = offsetX + col * cellSize + cellSize / 2; var y = offsetY + row * cellSize + cellSize / 2; cell.x = x; cell.y = y; var num = cardNumbers[p][col][row]; cell.setNumber(num); if (col === 2 && row === 2) { cell.setMarked(true); // Free space } cell.playerIndex = p; game.addChild(cell); bingoCells[p].push(cell); } } // --- Ava: Add a fun idle animation to the player's bingo card for visual feedback --- if (p === 0) { // Animate the whole card with a gentle floating effect var floatT = { v: 0 }; var _floatCard = function floatCard() { tween(floatT, { v: 1 }, { duration: 2200 + Math.random() * 800, easing: tween.easeInOut, onUpdate: function onUpdate() { // Apply a gentle up-down float to all player cells for (var i = 0; i < bingoCells[0].length; i++) { var baseY = cardStartY + Math.floor(i / gridSize) * cellSize + cellSize / 2; bingoCells[0][i].y = baseY + Math.sin(floatT.v * Math.PI * 2) * 10; } }, onComplete: function onComplete() { floatT.v = 0; _floatCard(); } }); }; _floatCard(); // --- Ava: Add a 'You' indicator animation for the player side --- // Only add once per game start if (typeof youIndicatorInstance === "undefined" || !youIndicatorInstance) { var youIndicatorInstance = new Container(); // Add a glowing ellipse as a background var youBg = youIndicatorInstance.attachAsset('playerIndicator', { width: 250, height: 250, anchorX: 0.5, anchorY: 0.5 }); youBg.alpha = 0.22; youBg.y = 20; // Add a white ellipse for extra glow var youGlow = youIndicatorInstance.attachAsset('playerIndicator', { width: 300, height: 300, color: 0xffffff, anchorX: 0.5, anchorY: 0.5 }); youGlow.alpha = 0.09; youGlow.y = 20; // You text removed per request // Place above the player's card, centered horizontally youIndicatorInstance.x = 2048 / 4; youIndicatorInstance.y = cardStartY - 100; game.addChild(youIndicatorInstance); // Add dancing animation similar to AI robot youIndicatorInstance.danceTick = 0; youIndicatorInstance.update = function () { // Dance in place: gentle rotation and scale pulse youIndicatorInstance.danceTick++; // Rotate gently back and forth youIndicatorInstance.rotation = Math.sin(youIndicatorInstance.danceTick / 30) * 0.18; // Scale up and down for a "bounce" effect var scalePulse = 1 + Math.sin(youIndicatorInstance.danceTick / 18) * 0.07; youIndicatorInstance.scale.x = scalePulse; youIndicatorInstance.scale.y = 1 - Math.sin(youIndicatorInstance.danceTick / 18) * 0.04; // Add gentle floating motion youIndicatorInstance.y = cardStartY - 120 + Math.sin(youIndicatorInstance.danceTick / 25) * 12; }; // Animate: gentle up-down float and scale pulse var youFloatT = { v: 0 }; var _youFloat = function youFloat() { tween(youFloatT, { v: 1 }, { duration: 1800 + Math.random() * 600, easing: tween.easeInOut, onUpdate: function onUpdate() { youIndicatorInstance.y = cardStartY - 80 + Math.sin(youFloatT.v * Math.PI * 2) * 18; var scalePulse = 1 + Math.sin(youFloatT.v * Math.PI * 2) * 0.07; youIndicatorInstance.scale.x = scalePulse; youIndicatorInstance.scale.y = scalePulse; }, onComplete: function onComplete() { youFloatT.v = 0; _youFloat(); } }); }; _youFloat(); } } } } // Start a new game for two players function startGame() { // Oyun başlarken bir kez hoş geldin sesini 1 saniye gecikmeli çal LK.setTimeout(function () { var hosgeldinSound = LK.getSound('oyunahosgeldin'); if (hosgeldinSound) hosgeldinSound.play(); }, 1000); game.state = 'playing'; gameOver = false; calledNumbers = []; availableNumbers = []; for (var i = 1; i <= numbersRange; i++) availableNumbers.push(i); createBingoCards(); numberCallText.setText(''); // Per player UI and state for (var p = 0; p < playerCount; p++) { if (!winText[p]) { winText[p] = new Text2('', { size: 70, fill: 0xff6600 }); winText[p].anchor.set(0.5, 0.5); // Position win text based on player position in 2x2 grid if (p === 0) { winText[p].x = 2048 / 4; winText[p].y = 2732 / 2; } else if (p === 1) { winText[p].x = 2048 * 3 / 4; winText[p].y = 2732 / 2; } else if (p === 2) { winText[p].x = 2048 / 4; winText[p].y = 2732 / 2 + 200; } else { winText[p].x = 2048 * 3 / 4; winText[p].y = 2732 / 2 + 200; } winText[p].visible = false; game.addChild(winText[p]); } // streakText UI removed winText[p].visible = false; streak[p] = 0; // streakText UI removed } gameDuration = 180000; // Reset to 3 minutes updateTimerText(); ensureTimerTextOnGui(); if (timerInterval) LK.clearInterval(timerInterval); // --- Ava: Play 'sonikidakika' sound when 2 minutes left and 'sonbirdakika' at 1 minute left --- var sonikidakikaPlayed = false; var sonbirdakikaPlayed = false; timerInterval = LK.setInterval(function () { gameDuration -= 100; if (gameDuration < 0) gameDuration = 0; updateTimerText(); // Play 'sonikidakika' sound at exactly 2:00 left (120000 ms) if (!sonikidakikaPlayed && gameDuration <= 120000 && gameDuration > 119900) { var sonikidakikaSound = LK.getSound('Sonikidakika'); if (sonikidakikaSound) sonikidakikaSound.play(); sonikidakikaPlayed = true; } // Play 'sonbirdakika' sound at exactly 1:00 left (60000 ms) if (!sonbirdakikaPlayed && gameDuration <= 60000 && gameDuration > 59900) { var sonbirdakikaSound = LK.getSound('Sonbirdakika'); if (sonbirdakikaSound) sonbirdakikaSound.play(); sonbirdakikaPlayed = true; } if (gameDuration <= 0 && !gameOver) { endGame(false, 0); } }, 100); updateCalledBallsUI(); // Number left text UI update removed currentPlayer = 0; nextNumberCall(callIntervalStart); } // Call the next number game.currentNumber = null; function nextNumberCall(interval) { if (gameOver) return; if (availableNumbers.length === 0) { endGame(false); return; } var idx = Math.floor(Math.random() * availableNumbers.length); var num = availableNumbers[idx]; availableNumbers.splice(idx, 1); calledNumbers.push(num); game.currentNumber = num; numberCallText.setText(num); LK.effects.flashObject(numberCallText, 0xff6600, 300); // Play ses1-ses75 sound if number is in 1-75 if (num >= 1 && num <= 75) { var soundId = 'ses' + num; var sound = LK.getSound(soundId); if (sound) sound.play(); } // Update called balls UI updateCalledBallsUI(); // Animate all called balls with a gentle bounce for (var i = 0; i < calledBallsContainer.children.length; i++) { var ball = calledBallsContainer.children[i]; if (ball && ball.scale) { ball.scale.x = 1; ball.scale.y = 1; tween(ball.scale, { x: 1.15, y: 1.15 }, { duration: 120, yoyo: true, repeat: 1, easing: tween.easeOut }); } } // Number left text UI update removed // Pulse the matching cell(s) on the human player's card for (var i = 0; i < bingoCells[0].length; i++) { if (bingoCells[0][i].number === num && !bingoCells[0][i].marked) { // Flash the cell background for extra attention LK.effects.flashObject(bingoCells[0][i], 0xfff200, 220); // Pulse the cell scale - reduced size effect (less dramatic) tween(bingoCells[0][i].scale, { x: 1.07, y: 1.07 }, { duration: 140, yoyo: true, repeat: 1, easing: tween.easeOut }); // Additional glow pulse effect for more visual impact if (bingoCells[0][i].glow) { tween(bingoCells[0][i].glow, { alpha: 0.32, scaleX: 1.08, scaleY: 1.08 }, { duration: 220, yoyo: true, repeat: 1, easing: tween.easeInOut }); } } } // --- Enhanced AI for all AI players --- if (playerCount >= 2 && !gameOver) { // Process all AI players (1, 2, 3) for (var aiPlayer = 1; aiPlayer < playerCount; aiPlayer++) { var opponentIdx = aiPlayer; // Analyze opponent's board state var opponentScore = 0; var nearWinLines = []; var marked = []; // Build marked grid and count score for (var col = 0; col < gridSize; col++) { marked[col] = []; for (var row = 0; row < gridSize; row++) { var idx = col * gridSize + row; marked[col][row] = bingoCells[opponentIdx][idx].marked; if (marked[col][row]) opponentScore++; } } // Check for lines that are one cell away from winning // Check rows for (var row = 0; row < gridSize; row++) { var markedCount = 0; for (var col = 0; col < gridSize; col++) { if (marked[col][row]) markedCount++; } if (markedCount === gridSize - 1) nearWinLines.push({ type: 'row', index: row }); } // Check columns for (var col = 0; col < gridSize; col++) { var markedCount = 0; for (var row = 0; row < gridSize; row++) { if (marked[col][row]) markedCount++; } if (markedCount === gridSize - 1) nearWinLines.push({ type: 'col', index: col }); } // Check diagonals var diagCount1 = 0, diagCount2 = 0; for (var i = 0; i < gridSize; i++) { if (marked[i][i]) diagCount1++; if (marked[gridSize - 1 - i][i]) diagCount2++; } if (diagCount1 === gridSize - 1) nearWinLines.push({ type: 'diag1' }); if (diagCount2 === gridSize - 1) nearWinLines.push({ type: 'diag2' }); // Find the cell with the current number for (var i = 0; i < bingoCells[opponentIdx].length; i++) { var cell = bingoCells[opponentIdx][i]; if (cell.number === num && !cell.marked) { // Calculate AI response time based on selected difficulty var aiDelay = 0; var accuracyChance = 0.95; // Default fallback // Use selected difficulty if set, else fallback to old logic if (typeof game.selectedDifficulty !== "undefined") { // Use values set in overlay var aiAcc = typeof game.aiAccuracy !== "undefined" ? game.aiAccuracy : 0.95; var aiMin = typeof game.aiMinDelay !== "undefined" ? game.aiMinDelay : 200; var aiMax = typeof game.aiMaxDelay !== "undefined" ? game.aiMaxDelay : 800; aiDelay = aiMin + Math.random() * (aiMax - aiMin); accuracyChance = aiAcc; } else { // Factor 1: Score-based speed (the more marks, the faster) if (opponentScore < 5) { aiDelay = 800 + Math.random() * 600; accuracyChance = 0.7; } else if (opponentScore < 10) { aiDelay = 400 + Math.random() * 400; accuracyChance = 0.85; } else if (opponentScore < 15) { aiDelay = 200 + Math.random() * 300; accuracyChance = 0.92; } else { aiDelay = 100 + Math.random() * 200; accuracyChance = 0.98; } } // Factor 2: Priority boost if this cell completes a line var cellCol = Math.floor(i / gridSize); var cellRow = i % gridSize; var isPriority = false; for (var n = 0; n < nearWinLines.length; n++) { var line = nearWinLines[n]; if (line.type === 'row' && cellRow === line.index) isPriority = true;else if (line.type === 'col' && cellCol === line.index) isPriority = true;else if (line.type === 'diag1' && cellCol === cellRow) isPriority = true;else if (line.type === 'diag2' && cellCol === gridSize - 1 - cellRow) isPriority = true; } if (isPriority) { aiDelay = Math.min(aiDelay, 150 + Math.random() * 100); accuracyChance = 0.99; } // Factor 3: Occasional mistakes (miss a number) var makesMistake = Math.random() > accuracyChance; (function (cell, aiDelay, makesMistake) { LK.setTimeout(function () { if (!cell.marked && !gameOver && !makesMistake) { cell.setMarked(true); // Flash with AI indicator color LK.effects.flashObject(cell, 0x1565c0, 180); // Update streak for opponent streak[opponentIdx]++; // Time bonus removed for simplified timer // Check win for opponent var prevPlayer = currentPlayer; currentPlayer = opponentIdx; game.checkWin(); currentPlayer = prevPlayer; } else if (makesMistake && !gameOver) { // AI missed this number, reset streak streak[opponentIdx] = 0; } }, aiDelay); })(cell, aiDelay, makesMistake); } } } } // End AI players loop // Speed up calls as game progresses var nextInterval = Math.max(callIntervalMin, interval - callIntervalStep); if (callTimer) LK.clearTimeout(callTimer); callTimer = LK.setTimeout(function () { nextNumberCall(nextInterval); }, nextInterval); } // Update timer UI for the single timer // Check for win (row, col, diag) for the current player game.checkWin = function () { var p = currentPlayer; // Build marked grid var marked = []; for (var col = 0; col < gridSize; col++) { marked[col] = []; for (var row = 0; row < gridSize; row++) { var idx = col * gridSize + row; marked[col][row] = bingoCells[p][idx].marked; } } // Check rows for (var row = 0; row < gridSize; row++) { var win = true; for (var col = 0; col < gridSize; col++) { if (!marked[col][row]) win = false; } if (win) return endGame(true, p); } // Check cols for (var col = 0; col < gridSize; col++) { var win = true; for (var row = 0; row < gridSize; row++) { if (!marked[col][row]) win = false; } if (win) return endGame(true, p); } // Check diag TL-BR var win = true; for (var i = 0; i < gridSize; i++) { if (!marked[i][i]) win = false; } if (win) return endGame(true, p); // Check diag TR-BL win = true; for (var i = 0; i < gridSize; i++) { if (!marked[gridSize - 1 - i][i]) win = false; } if (win) return endGame(true, p); }; // End game: win or lose for a specific player function endGame(won, playerIdx) { gameOver = true; game.state = 'ended'; if (callTimer) LK.clearTimeout(callTimer); if (timerInterval) LK.clearInterval(timerInterval); // Freeze Timer timeout logic removed if (won) { // Helper to highlight a line var highlightLine = function highlightLine(indices) { for (var i = 0; i < indices.length; i++) { var idx = indices[i]; var cell = bingoCells[playerIdx][idx]; tween(cell.markOverlay, { alpha: 1 }, { duration: 300, easing: tween.easeOut }); cell.markOverlay.color = 0xff6600; } }; winText[playerIdx].setText("BINGO!\nYou Win!"); winText[playerIdx].setStyle({ fill: 0xff6600 }); LK.effects.flashScreen(0xff6600, 1000); // Highlight the winning line(s) // Rebuild marked grid var marked = []; for (var col = 0; col < gridSize; col++) { marked[col] = []; for (var row = 0; row < gridSize; row++) { var idx = col * gridSize + row; marked[col][row] = bingoCells[playerIdx][idx].marked; } } for (var row = 0; row < gridSize; row++) { var win = true; var indices = []; for (var col = 0; col < gridSize; col++) { if (!marked[col][row]) win = false; indices.push(col * gridSize + row); } if (win) highlightLine(indices); } for (var col = 0; col < gridSize; col++) { var win = true; var indices = []; for (var row = 0; row < gridSize; row++) { if (!marked[col][row]) win = false; indices.push(col * gridSize + row); } if (win) highlightLine(indices); } var win = true; var indices = []; for (var i = 0; i < gridSize; i++) { if (!marked[i][i]) win = false; indices.push(i * gridSize + i); } if (win) highlightLine(indices); win = true; indices = []; for (var i = 0; i < gridSize; i++) { if (!marked[gridSize - 1 - i][i]) win = false; indices.push((gridSize - 1 - i) * gridSize + i); } if (win) highlightLine(indices); // Confetti effect on win for (var confetti = 0; confetti < 32; confetti++) { (function () { var c = new Container(); var colorList = [0xff6600, 0xffd700, 0x76ff03, 0x1565c0, 0xffffff]; var confettiColor = colorList[Math.floor(Math.random() * colorList.length)]; var confettiShape = c.attachAsset('bingoCellBg', { width: 24 + Math.random() * 16, height: 12 + Math.random() * 8, color: confettiColor, anchorX: 0.5, anchorY: 0.5 }); c.x = (playerIdx === 0 ? 2048 / 4 : 2048 * 3 / 4) + (Math.random() - 0.5) * 200; c.y = 0; c.rotation = Math.random() * Math.PI * 2; game.addChild(c); var targetY = 2732 / 2 + 400 + Math.random() * 200; var targetX = c.x + (Math.random() - 0.5) * 400; tween(c, { x: targetX, y: targetY, rotation: c.rotation + Math.PI * 2 * (Math.random() > 0.5 ? 1 : -1) }, { duration: 1200 + Math.random() * 600, easing: tween.easeIn, onComplete: function onComplete() { if (c.parent) c.parent.removeChild(c); } }); })(); } LK.showYouWin(); } else { winText[playerIdx].setText("Time's Up!\nGame Over"); winText[playerIdx].setStyle({ fill: 0x8b0000 }); LK.effects.flashScreen(0x8b0000, 1000); LK.showGameOver(); } winText[playerIdx].visible = true; // Freeze Timer button visibility removed } // --- Input: Restart on game over/win --- game.down = function (x, y, obj) { if (game.state === 'ended') { // Wait for LK to reset game } }; // --- Giriş Ekranı (Welcome Overlay) --- // Ava: Add a giriş overlay before starting the game, without breaking the current game logic var girisOverlay = new Container(); var girisBg = girisOverlay.attachAsset('Background', { width: 2048, height: 2732, color: 0x101218, anchorX: 0.5, anchorY: 0.5 }); girisBg.x = 2048 / 2; girisBg.y = 2732 / 2; girisBg.alpha = 0.96; // Welcome text var girisText = new Text2('ÇOK GİZLİ BİNGO', { size: 160, fill: 0xff6600 }); girisText.anchor.set(0.5, 0.5); girisText.x = 2048 / 2; girisText.y = 900; // Subtitle var altText = new Text2('Başlamak için dokunun', { size: 80, fill: 0xffffff }); altText.anchor.set(0.5, 0.5); altText.x = 2048 / 2; altText.y = 1200; // Optionally, a fun icon or animation var girisIcon = girisOverlay.attachAsset('aiIndicator', { anchorX: 0.5, anchorY: 0.5 }); girisIcon.x = 2048 / 2; girisIcon.y = 700; girisIcon.scale.x = 1.2; girisIcon.scale.y = 1.2; // Add to overlay girisOverlay.addChild(girisBg); girisOverlay.addChild(girisIcon); girisOverlay.addChild(girisText); girisOverlay.addChild(altText); // Block input to game until overlay is dismissed girisOverlay.interactive = true; girisOverlay.buttonMode = true; // Animate overlay in girisOverlay.alpha = 0; game.addChild(girisOverlay); tween(girisOverlay, { alpha: 1 }, { duration: 400, easing: tween.easeOut }); // When user taps anywhere, remove overlay and start game girisOverlay.down = function (x, y, obj) { // Animate out tween(girisOverlay, { alpha: 0 }, { duration: 300, easing: tween.easeIn, onComplete: function onComplete() { if (girisOverlay.parent) girisOverlay.parent.removeChild(girisOverlay); // Show AI robots only after overlay is dismissed showAIRobots(); // Start the game only after user taps overlay startGame(); } }); }; // Optionally, pulse the subtitle for attention var pulseT = { v: 0 }; function pulseAltText() { tween(pulseT, { v: 1 }, { duration: 1200, yoyo: true, repeat: 1, easing: tween.easeInOut, onUpdate: function onUpdate() { altText.alpha = 0.7 + 0.3 * Math.abs(Math.sin(pulseT.v * Math.PI)); }, onComplete: function onComplete() { pulseT.v = 0; pulseAltText(); } }); } pulseAltText(); // --- Start game immediately, difficulty selection deactivated --- // startGame();//{8P} // Ava: now called after overlay is dismissed // --- Ava: Add AI robots for all AI players, but only after giriş overlay is dismissed --- function showAIRobots() { // AI Robot 1 (top-right, above card 1) var aiRobotInstance1 = new AIRobot(); aiRobotInstance1.x = 2048 * 3 / 4; aiRobotInstance1.y = cardStartY - 100; game.addChild(aiRobotInstance1); // AI Robot 2 (bottom-left, above card 2) var aiRobotInstance2 = new AIRobot(); aiRobotInstance2.x = 2048 / 4; aiRobotInstance2.y = cardBottomY - 100; game.addChild(aiRobotInstance2); // AI Robot 3 (bottom-right, above card 3) var aiRobotInstance3 = new AIRobot(); aiRobotInstance3.x = 2048 * 3 / 4; aiRobotInstance3.y = cardBottomY - 100; game.addChild(aiRobotInstance3); // Animate a gentle up-down float for the AI robots var aiFloatT = { v: 0 }; var _aiFloat = function aiFloat() { tween(aiFloatT, { v: 1 }, { duration: 1800 + Math.random() * 600, easing: tween.easeInOut, onUpdate: function onUpdate() { // Float each AI robot above its card aiRobotInstance1.y = cardStartY - 100 + Math.sin(aiFloatT.v * Math.PI * 2) * 18; aiRobotInstance2.y = cardBottomY - 100 + Math.sin(aiFloatT.v * Math.PI * 2) * 18; aiRobotInstance3.y = cardBottomY - 100 + Math.sin(aiFloatT.v * Math.PI * 2) * 18; }, onComplete: function onComplete() { aiFloatT.v = 0; _aiFloat(); } }); }; _aiFloat(); } // --- Add Save Button (Kaydet) --- var kaydetBtn = new Container(); var btnBg = kaydetBtn.attachAsset('buttonHover', { anchorX: 0.5, anchorY: 0.5 }); var btnText = new Text2('Kaydet', { size: 70, fill: 0xffffff }); btnText.anchor.set(0.5, 0.5); btnText.x = 0; btnText.y = 0; kaydetBtn.addChild(btnText); // Place button at top right, but not in the menu area kaydetBtn.x = 2048 - 200; kaydetBtn.y = 120; kaydetBtn.interactive = true; kaydetBtn.buttonMode = true; kaydetBtn.down = function (x, y, obj) { kaydetOyunu(); tween(btnBg, { alpha: 0.5 }, { duration: 80, yoyo: true, repeat: 1 }); }; LK.gui.top.addChild(kaydetBtn); // --- Optionally, load game if available on start --- yukleOyunu(); // --- Animated background color pulse for visual appeal --- var bgPulseColors = [0x101218, // Very dark navy 0x181c24, // Deep navy 0x232b38, // Slightly lighter navy 0x181c24, // Deep navy 0x101218 // Very dark navy ]; // Dark-only palette for background pulse var bgPulseIndex = 0; var bgPulseDuration = 3000; function pulseBackground() { var fromColor = bgPulseColors[bgPulseIndex]; var toColor = bgPulseColors[(bgPulseIndex + 1) % bgPulseColors.length]; var t = { v: 0 }; tween(t, { v: 1 }, { duration: bgPulseDuration, easing: tween.easeInOut, onUpdate: function onUpdate() { // Interpolate color var r1 = fromColor >> 16 & 0xff, g1 = fromColor >> 8 & 0xff, b1 = fromColor & 0xff; var r2 = toColor >> 16 & 0xff, g2 = toColor >> 8 & 0xff, b2 = toColor & 0xff; var r = Math.round(r1 + (r2 - r1) * t.v); var g = Math.round(g1 + (g2 - g1) * t.v); var b = Math.round(b1 + (b2 - b1) * t.v); var color = r << 16 | g << 8 | b; game.setBackgroundColor(color); }, onComplete: function onComplete() { bgPulseIndex = (bgPulseIndex + 1) % bgPulseColors.length; pulseBackground(); } }); } pulseBackground();
===================================================================
--- original.js
+++ change.js
@@ -1253,8 +1253,9 @@
onComplete: function onComplete() {
if (girisOverlay.parent) girisOverlay.parent.removeChild(girisOverlay);
// Show AI robots only after overlay is dismissed
showAIRobots();
+ // Start the game only after user taps overlay
startGame();
}
});
};
Bingo thema. In-Game asset. 2d. High contrast. No shadows
Aİ player. In-Game asset. 2d. High contrast. No shadows
Bingo Mark. In-Game asset. 2d. High contrast. No shadows
Streakbackground bingo. In-Game asset. 2d. High contrast. No shadows
Card border. In-Game asset. 2d. High contrast. No shadows
Yellow ball. In-Game asset. 2d. High contrast. No shadows
Siyah X işaretli jeton. In-Game asset. 2d. High contrast. No shadows
YOU yazısını yaz. In-Game asset. 2d. High contrast. No shadows
Click
Sound effect
Numberthree
Sound effect
ses1
Sound effect
ses2
Sound effect
ses3
Sound effect
ses4
Sound effect
ses5
Sound effect
ses6
Sound effect
ses7
Sound effect
ses8
Sound effect
ses9
Sound effect
ses10
Sound effect
ses11
Sound effect
ses12
Sound effect
ses13
Sound effect
ses14
Sound effect
ses15
Sound effect
ses16
Sound effect
ses17
Sound effect
ses18
Sound effect
ses19
Sound effect
ses20
Sound effect
ses21
Sound effect
ses22
Sound effect
ses23
Sound effect
ses24
Sound effect
ses25
Sound effect
ses26
Sound effect
ses27
Sound effect
ses28
Sound effect
ses29
Sound effect
ses30
Sound effect
ses31
Sound effect
ses32
Sound effect
ses33
Sound effect
ses34
Sound effect
ses35
Sound effect
ses36
Sound effect
ses37
Sound effect
ses38
Sound effect
ses39
Sound effect
ses40
Sound effect
ses41
Sound effect
ses42
Sound effect
ses43
Sound effect
ses44
Sound effect
ses45
Sound effect
ses46
Sound effect
ses47
Sound effect
ses48
Sound effect
ses49
Sound effect
ses50
Sound effect
ses51
Sound effect
ses52
Sound effect
ses53
Sound effect
ses54
Sound effect
ses55
Sound effect
ses56
Sound effect
ses57
Sound effect
ses58
Sound effect
ses59
Sound effect
ses60
Sound effect
ses61
Sound effect
ses62
Sound effect
ses64
Sound effect
ses65
Sound effect
ses66
Sound effect
ses67
Sound effect
ses68
Sound effect
ses69
Sound effect
ses70
Sound effect
ses71
Sound effect
ses72
Sound effect
ses75
Sound effect
Ses73
Sound effect
Ses74
Sound effect
Sonikidakika
Sound effect
Sonbirdakika
Sound effect
Oyunahosgeldin
Sound effect
oyunahosgeldin
Sound effect