User prompt
Sayı tablosu size i büyüyor sanırım sayı çıktığında
User prompt
Türkçe yaz
User prompt
AI playerde kullandığın durduğu yerde dans eden animasyonu playerindicatorda kullan ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Playerindicator text biraz daha yukarıya yerleştir
User prompt
250x250
User prompt
Playerindicator size 200x200
User prompt
You yazisini Sil
User prompt
Remove ufoalien assets
User prompt
You yazı yerine Oraya imagine eklicem örnek bir görsel ekle oraya
User prompt
Robot eklemiştin sil demiştim ekle yine
User prompt
Geri yükle
User prompt
Avatarı sil
User prompt
Tamam oluşturduğumuz bu assetse avatar eklicez mi
User prompt
Tamam orası için yeni bir assets oluştur
User prompt
Zaten ekledigin you da animasyon yok ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Sayfanın en üstüne koy
User prompt
Biraz daha yukarıya ortala
User prompt
Tamam şuan gözüküyor biraz daha yukarıya al lütfen
User prompt
Timer left pozisyonunu çıkan sayıları gösteren topun üstüne doğru yerleştir
User prompt
Komple timer left kodlarını silelim yeniden yapalım kod.karisikligi olabilir
User prompt
Hayır düzelmedi
User prompt
Sen hallet bu sorunu kodunu kontrol et eski timer left eklemiştik ordan bir cakisma söz konusu olabilir mi animasyon eklemiştik ama calismamisti bende sil demistim sana
User prompt
Time left gözükmüyor eğer arka plan ile çakışıyorsa düzelt
User prompt
Time left yazıni sayfanın en üst ortasına yerlestir
User prompt
Add time left
/**** * 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 two-player mode to fit both cards on screen var cellSize = 180; // px, reduced to fit two cards side by side var cardPadding = 30; var cardWidth = gridSize * cellSize; var cardHeight = gridSize * cellSize; var cardStartX = 2048 / 4 - cardWidth / 2; // Player 1 card center at 1/4 width, Player 2 at 3/4 width var cardStartY = 500; // Lowered to fit both cards and UI 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: 320, 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 --- // Two player support var playerCount = 2; var currentPlayer = 0; // 0 or 1 var bingoCells = [[], []]; // bingoCells[0] for player 1, bingoCells[1] for player 2 var calledNumbers = []; var availableNumbers = []; var callTimer = null; var timerInterval = null; var cardNumbers = [[], []]; var gameOver = false; var playerNames = ["You", "AI"]; var winText = [null, null]; // Per player var streak = [0, 0]; var streakText = [null, null]; // Freeze Timer state arrays removed // --- Freeze Timer compatibility: define freezeTimerActive as always-false array for each player --- var freezeTimerActive = [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 = 130; 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 - 300; game.addChild(numberCallText); // Number left text UI removed var winText = new Text2('', { size: 120, 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 both players function createBingoCards() { for (var p = 0; p < playerCount; p++) { bingoCells[p] = []; cardNumbers[p] = generateCardNumbers(); // Center cards at 1/4 and 3/4 of the screen width var cardCenterX = p === 0 ? 2048 / 4 : 2048 * 3 / 4; var offsetX = cardCenterX - cardWidth / 2; 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 = cardStartY + 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 - 120; game.addChild(youIndicatorInstance); // 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() { 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: 120, fill: 0xff6600 }); winText[p].anchor.set(0.5, 0.5); winText[p].x = p === 0 ? 2048 / 4 : 2048 * 3 / 4; winText[p].y = 2732 / 2; 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); timerInterval = LK.setInterval(function () { gameDuration -= 100; if (gameDuration < 0) gameDuration = 0; updateTimerText(); 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 tween(bingoCells[0][i].scale, { x: 1.22, y: 1.22 }, { duration: 140, yoyo: true, repeat: 1, easing: tween.easeOut }); } } // --- Enhanced Opponent AI --- if (playerCount === 2 && !gameOver) { var opponentIdx = 1; // 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); } } } // 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 } }; // --- Start game immediately, difficulty selection deactivated --- startGame(); // --- Ava: Add a subtle AI robot idle animation to make the AI feel more alive --- // Place the robot animation slightly higher and toward the center of the screen var aiRobotInstance = new AIRobot(); // Position robot: horizontally between center and right, vertically higher up aiRobotInstance.x = 2048 * 0.74; // Move a bit more to the right aiRobotInstance.y = 370; // Move slightly higher game.addChild(aiRobotInstance); // Animate a gentle up-down float for the AI robot var aiFloatT = { v: 0 }; var _aiFloat = function aiFloat() { tween(aiFloatT, { v: 1 }, { duration: 1800 + Math.random() * 600, easing: tween.easeInOut, onUpdate: function onUpdate() { // Float around the base y position aiRobotInstance.y = 370 + 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
@@ -683,9 +683,9 @@
youGlow.y = 20;
// You text removed per request
// Place above the player's card, centered horizontally
youIndicatorInstance.x = 2048 / 4;
- youIndicatorInstance.y = cardStartY - 80;
+ youIndicatorInstance.y = cardStartY - 120;
game.addChild(youIndicatorInstance);
// Animate: gentle up-down float and scale pulse
var youFloatT = {
v: 0
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