User prompt
Bingocell için de tasarımı yap değişmemiş arka planı
User prompt
I want a black design but the details shouldn't get lost in black. A black and red design.
User prompt
Darh tema
User prompt
Bana bu tasarımı yap lütfen Her BingoCell için, köşeleri hafif yuvarlatılmış, açık mavi renkte bir kutu kullanıyorum. Hücre işaretlendiğinde kutunun rengi sarıya dönüyor ve etrafında hafif bir parlama efekti beliriyor. Arka planda çok hafif, opaklığı düşük yıldız desenleri var. Bu sayede hem modern hem de eğlenceli bir görünüm elde ediliyor."
User prompt
Çıkan numara senin kartında varsa, o hücreyi daha belirgin hale getirmek kesinlikle iyi bir uygulamadır
User prompt
Animasyon gözükmüyor you olan
User prompt
Tamam yapalım
User prompt
Streak yazısını silelim
User prompt
Position the AI robot animation çok az daha sağ tarafa
User prompt
Position the AI robot animation biraz daha yukarıya sonra birazcık sağa
User prompt
Position the AI robot animation biraz daha yukarıya
User prompt
Position the AI robot animation biraz daha aşağıya ve ortaya doğru
User prompt
Position the AI robot animation sağ üst tarafa
User prompt
AI player yazısını sil ve mavi renkli olanı
User prompt
Your time yazısını ve AıI player time yazısını birazcık daha aşağıya getir
User prompt
Position the AI robot animation above the AI player timer text
User prompt
Position this animation above the AI player time text
User prompt
Dediğimi yap
User prompt
For example, place this animation under the AI player timer
User prompt
Sen olsaydın ne eklerdin
User prompt
Tüm sayıları sesli söylesin
User prompt
Sesleri ekle
User prompt
Tekrar ekle
User prompt
Tamam sen ses 75e kadar ekle assesti ben yüklücem müzik
User prompt
Hepsine yap
/**** * 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; // --- Custom background: rounded, light blue box --- var cellBg = self.attachAsset('Background', { width: cellSize, height: cellSize, color: 0xb3e5fc, // Light blue anchorX: 0.5, anchorY: 0.5 }); cellBg.radius = cellSize * 0.22; // Simulate rounded corners (if supported by engine) // --- Subtle star pattern: add 3-4 faint white/yellow stars randomly in the cell --- self.stars = []; for (var i = 0; i < 4; i++) { var star = self.attachAsset(i % 2 === 0 ? 'starWhite' : 'starYellow', { width: cellSize * (0.13 + Math.random() * 0.07), height: cellSize * (0.13 + Math.random() * 0.07), anchorX: 0.5, anchorY: 0.5 }); star.alpha = 0.13 + Math.random() * 0.07; // Place stars at random positions, but not center var angle = Math.random() * Math.PI * 2; var dist = cellSize * (0.23 + Math.random() * 0.18); star.x = Math.cos(angle) * dist; star.y = Math.sin(angle) * dist; self.stars.push(star); } // Number text var numberText = new Text2('', { size: Math.floor(cellSize * 0.45), fill: 0x1565c0 // Deep blue for contrast }); numberText.anchor.set(0.5, 0.5); self.addChild(numberText); // --- Mark overlay: yellow 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; self.markOverlay = markOverlay; // --- Glow effect: subtle white glow when marked --- var glow = self.attachAsset('freeSpace', { width: cellSize * 1.18, height: cellSize * 1.18, color: 0xffffff, 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 tween(markOverlay, { alpha: 0.92 }, { duration: 200, easing: tween.easeOut }); // Animate glow in tween(glow, { alpha: 0.22 }, { duration: 200, easing: tween.easeOut }); numberText.setText(self.number); numberText.setStyle({ fill: 0xffc300 // Black text replaced with deep yellow for contrast }); } else { // Animate mark overlay out tween(markOverlay, { alpha: 0 }, { duration: 200, easing: tween.easeOut }); // Animate glow out tween(glow, { alpha: 0 }, { duration: 200, easing: tween.easeOut }); numberText.setStyle({ fill: 0x1565c0 }); } }; // 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); } }; // Example: Trigger action when cell crosses X = 1000 from left to right if (self.lastX !== undefined && self.lastX <= 1000 && self.x > 1000) { // Place your action here, e.g. console.log("Cell crossed X=1000!"); } // Always update lastX at the end self.lastX = self.x; // Example: Trigger action when cell crosses Y = 800 from above to below if (self.lastY !== undefined && self.lastY <= 800 && self.y > 800) { // Place your action here, e.g. console.log("Cell crossed Y=800!"); } // Always update lastY at the end self.lastY = self.y; // Example: Trigger action when cell crosses X=1000 and Y=800 at the same frame if (self.lastY !== undefined && self.lastY <= 800 && self.y > 800 && self.lastX !== undefined && self.lastX <= 1000 && self.x > 1000) { // Place your action here, e.g. console.log("Cell arrived at (1000,800)!"); } // 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: 0x181a1b }); /**** * Game Code ****/ // --- Added ses41 to ses75 sound assets (IDs to be filled by asset loader) --- // Save the current game state (called numbers, card numbers, marked cells, time left, streaks) // --- Kaydet (Save) Functionality --- // --- Functions --- // --- Hint Power-Up Button --- // Bingo game shapes // New shapes for improved UI // Images // New image assets for polish (IDs are placeholders, replace with real IDs if available) // Sounds // Neon blue planet // Deep space blue // Cyan for hover // Dark blue for pressed // Space black // Galaxy border // Neon green // Star yellow // Light blue // Space shadow // Neon cyan // Neon green // Space black // Space shadow // Neon green // Deep blue // Star yellow // Star yellow // Space/Galaxy themed assets for richer visuals // Space/galaxy decorative shapes // Space/galaxy themed overlays for cards // Space/galaxy themed power-up icons // Images (IDs are placeholders, replace with real asset IDs as needed) // Sounds // Neon pink // Deep retro blue // Neon cyan // Neon yellow // Purple // Neon cyan // Neon pink // Neon yellow // Neon cyan // Purple // Neon pink // Neon yellow // Deep retro blue // Neon cyan // Neon pink // Neon yellow // Purple // Deep retro blue // Neon cyan // Neon cyan // Neon pink // Neon yellow // Purple // Neon pink // Neon cyan // Neon yellow // Neon pink // Deep retro blue // Neon yellow // Purple // Neon cyan // Neon pink // Neon yellow // Neon pink // Candy pink // Pastel orange // Mint green // Candy orange // Light pink // Mint green // Candy pink // Candy orange // Mint green // Light pink // Candy pink // Candy orange // Light pink // Mint green // Candy pink // Candy orange // Light pink // Pastel orange // Mint green // Pastel blue // Pastel purple // Candy pink // Light pink // Candy pink // Mint green // Candy orange // Candy pink // Pastel orange // Pastel yellow // Light pink // Mint green // Candy pink // Candy orange // Candy pink // Forest green ball // Light moss cell // Fern green hover // Deep green pressed // Pale green // Deep green border // Sunlight confetti // Light brown confetti // Fern green // Pale green // Forest green // Sunlight free space // Pale green bg // Fern swirl // Forest green // Deep green // Pale green overlay // Light brown // Deep green // Blue pond // Forest flower // Mushroom cap // Pale green // Forest green // Fern green // Light brown // Sunlight // Light moss // Sunlight // Pale green // Fern green // Forest green // Sunlight // Deep green // Ses assets for ses1 to ses40 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; }) : []], timeLeft: timeLeft.slice(), 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() : []; timeLeft = saveData.timeLeft ? saveData.timeLeft.slice() : [gameDuration, gameDuration]; 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 for (var p = 0; p < playerCount; p++) { if (timerInterval[p]) LK.clearInterval(timerInterval[p]); timerInterval[p] = LK.setInterval(function (playerIdx) { return function () { if (!freezeTimerActive[playerIdx]) { timeLeft[playerIdx] -= 100; if (timeLeft[playerIdx] < 0) timeLeft[playerIdx] = 0; updateTimerTextForPlayer(playerIdx); if (timeLeft[playerIdx] <= 0 && !gameOver) { endGame(false, playerIdx); } } }; }(p), 100); updateTimerTextForPlayer(p); // streakText UI removed } 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 = 225000; // ms (3 min 45 sec) 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 timeLeft = [gameDuration, gameDuration]; // Separate timers for each player var timerInterval = [null, null]; var cardNumbers = [[], []]; var gameOver = false; var playerNames = ["You", "AI"]; var winText = [null, null]; // Per player var streak = [0, 0]; var streakText = [null, null]; var timerText = [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: 0xff073a // Neon red }); 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: 0xfff200 // Neon yellow }); 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('freeSpace', { width: 180, height: 90, color: 0xff6600, anchorX: 0.5, anchorY: 0.5 }); youBg.alpha = 0.22; // Add a white ellipse for extra glow var youGlow = youIndicatorInstance.attachAsset('freeSpace', { width: 220, height: 110, color: 0xffffff, anchorX: 0.5, anchorY: 0.5 }); youGlow.alpha = 0.09; // Add the "You" text var youText = new Text2('You', { size: 80, fill: 0xff6600, font: "Impact, Arial Black, Tahoma" }); youText.anchor.set(0.5, 0.5); youText.y = 0; youIndicatorInstance.addChild(youText); // Place above the player's card, centered horizontally youIndicatorInstance.x = 2048 / 4; youIndicatorInstance.y = cardStartY - 80; 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]); } // (AI robot animation and label will be handled globally after startGame) // streakText UI removed if (!timerText[p]) { timerText[p] = new Text2('', { size: 60, fill: 0xFFFFFF }); timerText[p].anchor.set(0.5, 0); if (p === 0) { // Human player timer below their board, aligned like AI timer timerText[p].x = 2048 / 4; timerText[p].y = cardStartY + cardHeight + 200 + 180; // Moved 60px further down game.addChild(timerText[p]); } else { // AI player timer below their board timerText[p].x = 2048 * 3 / 4; // Move timerText below the AI indicator image (aiIndicator.y + aiIndicator.height/2 + margin) timerText[p].y = cardStartY + cardHeight + 200 + 180; // Moved 60px further down game.addChild(timerText[p]); } } winText[p].visible = false; streak[p] = 0; // streakText UI removed // Freeze Timer state reset removed timeLeft[p] = gameDuration; updateTimerTextForPlayer(p); if (timerInterval[p]) LK.clearInterval(timerInterval[p]); timerInterval[p] = LK.setInterval(function (playerIdx) { return function () { if (!freezeTimerActive[playerIdx]) { timeLeft[playerIdx] -= 100; if (timeLeft[playerIdx] < 0) timeLeft[playerIdx] = 0; updateTimerTextForPlayer(playerIdx); if (timeLeft[playerIdx] <= 0 && !gameOver) { endGame(false, playerIdx); } } }; }(p), 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]++; // Add time bonus for streak if (streak[opponentIdx] > 1) { timeLeft[opponentIdx] += 1000; } // 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 a specific player function updateTimerTextForPlayer(p) { var sec = Math.ceil(timeLeft[p] / 1000); if (p === 0) { timerText[p].setText("Your Time: " + sec + "s"); } else { timerText[p].setText("AI Player Time: " + sec + "s"); } } // 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); for (var p = 0; p < playerCount; p++) { if (timerInterval[p]) LK.clearInterval(timerInterval[p]); // 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 if (typeof aiRobotInstance === "undefined") { 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 = [0x181a1b, // near-black 0x23272a, // dark gray 0x222326, // blackish blue 0x181a1b, // repeat for smooth loop 0x23272a]; // Blackish/dark palette 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
@@ -61,31 +61,61 @@
var self = Container.call(this);
// Properties
self.number = 0;
self.marked = false;
- // Create cell background
- var cellBg = self.attachAsset('bingoCellBg', {
+ // --- Custom background: rounded, light blue box ---
+ var cellBg = self.attachAsset('Background', {
width: cellSize,
height: cellSize,
+ color: 0xb3e5fc,
+ // Light blue
anchorX: 0.5,
anchorY: 0.5
});
+ cellBg.radius = cellSize * 0.22; // Simulate rounded corners (if supported by engine)
+ // --- Subtle star pattern: add 3-4 faint white/yellow stars randomly in the cell ---
+ self.stars = [];
+ for (var i = 0; i < 4; i++) {
+ var star = self.attachAsset(i % 2 === 0 ? 'starWhite' : 'starYellow', {
+ width: cellSize * (0.13 + Math.random() * 0.07),
+ height: cellSize * (0.13 + Math.random() * 0.07),
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ star.alpha = 0.13 + Math.random() * 0.07;
+ // Place stars at random positions, but not center
+ var angle = Math.random() * Math.PI * 2;
+ var dist = cellSize * (0.23 + Math.random() * 0.18);
+ star.x = Math.cos(angle) * dist;
+ star.y = Math.sin(angle) * dist;
+ self.stars.push(star);
+ }
// Number text
var numberText = new Text2('', {
size: Math.floor(cellSize * 0.45),
- fill: 0xffffff
+ fill: 0x1565c0 // Deep blue for contrast
});
numberText.anchor.set(0.5, 0.5);
self.addChild(numberText);
- // Mark overlay (hidden by default)
- var markOverlay = self.attachAsset('bingoMark', {
- width: cellSize * 0.7,
- height: cellSize * 0.7,
+ // --- Mark overlay: yellow 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;
self.markOverlay = markOverlay;
+ // --- Glow effect: subtle white glow when marked ---
+ var glow = self.attachAsset('freeSpace', {
+ width: cellSize * 1.18,
+ height: cellSize * 1.18,
+ color: 0xffffff,
+ 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 : '');
@@ -93,27 +123,43 @@
// Mark/unmark cell
self.setMarked = function (val) {
self.marked = val;
if (val) {
+ // Animate mark overlay in
tween(markOverlay, {
- alpha: 0.8
+ alpha: 0.92
}, {
duration: 200,
easing: tween.easeOut
});
+ // Animate glow in
+ tween(glow, {
+ alpha: 0.22
+ }, {
+ duration: 200,
+ easing: tween.easeOut
+ });
numberText.setText(self.number);
numberText.setStyle({
- fill: 0x000000
+ fill: 0xffc300 // Black text replaced with deep yellow for contrast
});
} else {
+ // Animate mark overlay out
tween(markOverlay, {
alpha: 0
}, {
duration: 200,
easing: tween.easeOut
});
+ // Animate glow out
+ tween(glow, {
+ alpha: 0
+ }, {
+ duration: 200,
+ easing: tween.easeOut
+ });
numberText.setStyle({
- fill: 0xffffff
+ fill: 0x1565c0
});
}
};
// Touch event
@@ -124,9 +170,19 @@
if (game.state !== 'playing') return;
var p = self.playerIndex !== undefined ? self.playerIndex : 0;
if (self.number === game.currentNumber && p === currentPlayer) {
self.setMarked(true);
- LK.effects.flashObject(self, 0xff6600, 200);
+ // 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) {
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