User prompt
Elimina todas las ventanas de comprar tokens.
User prompt
Que las letras de la ventana de comprar token sean de color negro.
User prompt
Crea una ventana que se llame Comprar Tokens
User prompt
Que los números de las burbujas sean un tanto más grandes.
User prompt
Que la ventana de comprar token sea de color amarillo.
User prompt
Y la ventana con la función de comprar tokens que se vaya a la parte superior junto a la ventana de total de tokens.
User prompt
Crea una ventana que me dé la opción de comprar tokens.
User prompt
Que la ventana de comprar tokens sea de color amarillo.
User prompt
que las letras de la ventana de comprobar token sean un tanto mas grandes
User prompt
Crea una ventana con un botón que me de la opción de comprar tokens.
User prompt
Que los números de las burbujas sean un tanto más grandes.
User prompt
Que los números de las burbujas sean de color negro.
User prompt
que los cartones cambien la combinación de números cada vez que los toque
User prompt
que el numero del score sea un poco mas grande
User prompt
...el color de las letras de la escoria sea de color blanco.
User prompt
Asegúrate de que no se pueda cambiar el valor de los tokens mientras se esté jugando.
User prompt
Que las burbujas salgan cinco tantos más rápido. ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
que las burbujas salgan cinco tantos más rápido
User prompt
Dame un poco más de tiempo para ver los cartones antes de que termine el juego.
User prompt
Que el texto del botón de inicio sea tres tantos más grande y de color negro.
User prompt
que el texto del botón de pausa sea de color negro
User prompt
que el texto del botón de pausa sea tres tantos más grande
User prompt
que el botón de pausa se mueva un poco hacia arriba
User prompt
que el botón de pausa se mueva dos tantos a la izquierda
User prompt
Que el botón de pausa se mueva un poco a la izquierda.
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var storage = LK.import("@upit/storage.v1"); /**** * Classes ****/ var BingoCard = Container.expand(function (cardIndex) { var self = Container.call(this); self.cardIndex = cardIndex; self.numbers = []; self.bingoNumbers = []; self.cardBg = self.attachAsset('bingoCard', { anchorX: 0.5, anchorY: 0.5 }); // Generate 15 random unique numbers between 1-75 self.generateNumbers = function () { var availableNumbers = []; for (var i = 1; i <= 75; i++) { availableNumbers.push(i); } for (var j = 0; j < 15; j++) { var randomIndex = Math.floor(Math.random() * availableNumbers.length); self.numbers.push(availableNumbers[randomIndex]); availableNumbers.splice(randomIndex, 1); } }; self.createNumberGrid = function () { var startX = -270; var startY = -90; var spacingX = 135; var spacingY = 90; for (var row = 0; row < 3; row++) { self.bingoNumbers[row] = []; for (var col = 0; col < 5; col++) { var numberIndex = row * 5 + col; var bingoNumber = new BingoNumber(self.numbers[numberIndex], self.cardIndex, row, col); bingoNumber.x = startX + col * spacingX; bingoNumber.y = startY + row * spacingY; self.addChild(bingoNumber); self.bingoNumbers[row][col] = bingoNumber; } } }; self.generateNumbers(); self.createNumberGrid(); return self; }); var BingoNumber = Container.expand(function (number, cardIndex, row, col) { var self = Container.call(this); self.number = number; self.cardIndex = cardIndex; self.row = row; self.col = col; self.isMarked = false; self.bg = self.attachAsset('bingoNumber', { anchorX: 0.5, anchorY: 0.5 }); self.numberText = new Text2(number.toString(), { size: 43, fill: 0x000000 }); self.numberText.anchor.set(0.5, 0.5); self.addChild(self.numberText); self.markNumber = function () { if (!self.isMarked) { self.isMarked = true; self.removeChild(self.bg); self.bg = self.attachAsset('markedNumber', { anchorX: 0.5, anchorY: 0.5 }); // Replace the text with white color self.removeChild(self.numberText); self.numberText = new Text2(self.number.toString(), { size: 43, fill: 0xFFFFFF }); self.numberText.anchor.set(0.5, 0.5); self.addChild(self.numberText); LK.getSound('numberMarked').play(); // Check for completed lines checkForCompletedLines(self.cardIndex); } }; self.down = function (x, y, obj) { // Numbers are now automatically marked, no manual interaction needed }; return self; }); var BingoWindow = Container.expand(function () { var self = Container.call(this); // Create celebration window background self.windowBg = self.attachAsset('bingoWindow', { anchorX: 0.5, anchorY: 0.5 }); // Create BINGO text self.bingoText = new Text2('BINGO!', { size: 120, fill: 0x000000 }); self.bingoText.anchor.set(0.5, 0.5); self.addChild(self.bingoText); // Position at center of screen self.x = 1024; self.y = 1366; // Start invisible self.alpha = 0; self.scaleX = 0.1; self.scaleY = 0.1; self.show = function () { // Animate window appearance tween(self, { alpha: 1, scaleX: 1, scaleY: 1 }, { duration: 500, easing: tween.easeOut }); // Add pulsing animation to text tween(self.bingoText, { scaleX: 1.2, scaleY: 1.2 }, { duration: 300, easing: tween.easeInOut, onFinish: function onFinish() { tween(self.bingoText, { scaleX: 1, scaleY: 1 }, { duration: 300, easing: tween.easeInOut }); } }); // Auto-hide after 0.75 seconds LK.setTimeout(function () { self.hide(); }, 750); }; self.hide = function () { tween(self, { alpha: 0, scaleX: 0.1, scaleY: 0.1 }, { duration: 300, easing: tween.easeIn, onFinish: function onFinish() { if (self.parent) { self.parent.removeChild(self); } } }); }; return self; }); var NumberBubble = Container.expand(function (number) { var self = Container.call(this); self.number = number; self.speed = -3; self.floatSpeed = 0; // Create bubble background self.bubbleBg = self.attachAsset('numberBubble', { anchorX: 0.5, anchorY: 0.5 }); // Create number text self.numberText = new Text2(number.toString(), { size: 32, fill: 0xFFFFFF }); self.numberText.anchor.set(0.5, 0.5); self.addChild(self.numberText); // Calculate position in three horizontal rows var bubblesPerRow = 25; // 25 bubbles per row (75 total / 3 rows) var bubbleSpacing = 80; // Spacing between bubbles var rowSpacing = 90; // Spacing between rows var startX = 50; // Start position for each row var startY = 120; // Y position for first row var currentBubbleCount = numberBubbles.length; // Calculate which row and position within row var row = Math.floor(currentBubbleCount / bubblesPerRow); var positionInRow = currentBubbleCount % bubblesPerRow; // Set target position in three rows var targetX = startX + positionInRow * bubbleSpacing; var targetY = startY + row * rowSpacing; // Initialize position at bottom of screen for animation self.x = targetX; self.y = 2732 + 50; // Start below screen self.lastY = self.y; // Animate bubble entrance to target position tween(self, { y: targetY, scaleX: 1.0, scaleY: 1.0 }, { duration: 1500, easing: tween.easeOut }); // Add floating animation tween(self.bubbleBg, { rotation: Math.PI * 2 }, { duration: 4000, easing: tween.linear }); self.update = function () { // Bubbles stay fixed in position - no floating animation }; return self; }); var PauseWindow = Container.expand(function () { var self = Container.call(this); // Create window background self.windowBg = self.attachAsset('pauseWindow', { anchorX: 0.5, anchorY: 0.5 }); // Create pause title self.pauseTitle = new Text2('JUEGO PAUSADO', { size: 60, fill: 0xFFFFFF }); self.pauseTitle.anchor.set(0.5, 0.5); self.pauseTitle.y = -120; self.addChild(self.pauseTitle); // Create resume button self.resumeButton = new Container(); var resumeBg = LK.getAsset('resumeButton', { anchorX: 0.5, anchorY: 0.5 }); self.resumeButton.addChild(resumeBg); var resumeText = new Text2('CONTINUAR', { size: 40, fill: 0xFFFFFF }); resumeText.anchor.set(0.5, 0.5); self.resumeButton.addChild(resumeText); self.resumeButton.y = -20; self.addChild(self.resumeButton); // Create quit button self.quitButton = new Container(); var quitBg = LK.getAsset('quitButton', { anchorX: 0.5, anchorY: 0.5 }); self.quitButton.addChild(quitBg); var quitText = new Text2('SALIR', { size: 40, fill: 0xFFFFFF }); quitText.anchor.set(0.5, 0.5); self.quitButton.addChild(quitText); self.quitButton.y = 100; self.addChild(self.quitButton); // Position at center of screen self.x = 1024; self.y = 1366; // Start invisible self.alpha = 0; self.scaleX = 0.1; self.scaleY = 0.1; self.show = function () { // Animate window appearance tween(self, { alpha: 1, scaleX: 1, scaleY: 1 }, { duration: 300, easing: tween.easeOut }); }; self.hide = function () { tween(self, { alpha: 0, scaleX: 0.1, scaleY: 0.1 }, { duration: 200, easing: tween.easeIn, onFinish: function onFinish() { if (self.parent) { self.parent.removeChild(self); } } }); }; // Resume button event self.resumeButton.down = function (x, y, obj) { resumeGame(); }; // Quit button event self.quitButton.down = function (x, y, obj) { quitGame(); }; return self; }); var PaymentWindow = Container.expand(function () { var self = Container.call(this); // Load accumulated payments from storage, default to 0 self.totalPayments = storage.tokyoPayments || 0; // Create window background self.windowBg = self.attachAsset('paymentWindow', { anchorX: 0.5, anchorY: 0.5 }); // Create payment text self.paymentText = new Text2('Total de Tokens: $' + self.totalPayments, { size: 80, fill: 0xff0000 }); self.paymentText.anchor.set(0.5, 0.5); self.addChild(self.paymentText); // Method to add payment self.addPayment = function (amount) { self.totalPayments += amount; self.paymentText.setText('Total de Tokens: $' + self.totalPayments); // Save to storage storage.tokyoPayments = self.totalPayments; // Flash animation for payment addition tween(self.windowBg, { tint: 0xffd700 }, { duration: 200 }); tween(self.windowBg, { tint: 0xffffff }, { duration: 200 }); }; // Method to reset payments self.resetPayments = function () { self.totalPayments = 0; self.paymentText.setText('Total de Tokens: $' + self.totalPayments); storage.tokyoPayments = self.totalPayments; }; return self; }); var TokenWindow = Container.expand(function (cardIndex) { var self = Container.call(this); self.cardIndex = cardIndex; // Define predefined price options self.priceOptions = [10, 20, 30, 50, 100]; // Load saved price index from storage, default to 0 if not found var storageKey = 'tokenPrice_' + cardIndex; self.currentPriceIndex = storage[storageKey] || 0; // Create window background self.windowBg = self.attachAsset('tokenWindow', { anchorX: 0.5, anchorY: 0.5 }); // Create price text with saved price self.priceText = new Text2('Token Price: ' + self.priceOptions[self.currentPriceIndex], { size: 100, fill: 0xff0000 }); self.priceText.anchor.set(0.5, 0.5); self.addChild(self.priceText); // Add tap event to cycle through prices and save to storage self.down = function (x, y, obj) { self.currentPriceIndex = (self.currentPriceIndex + 1) % self.priceOptions.length; self.priceText.setText('Token Price: ' + self.priceOptions[self.currentPriceIndex]); // Save the selected price index to storage storage[storageKey] = self.currentPriceIndex; }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x1a1a2e }); /**** * Game Code ****/ var bingoCards = []; var currentCalledNumber = null; var calledNumbers = []; var availableNumbers = []; var callTimer = null; var completedLines = 0; var gameStarted = false; var startButton = null; var numberBubbles = []; var bingoWindow = null; var paymentWindow = null; var cardHorizontalLines = [0, 0, 0, 0]; // Track horizontal lines per card var gamePaused = false; var pauseWindow = null; var pauseButton = null; // Initialize available numbers for (var i = 1; i <= 75; i++) { availableNumbers.push(i); } // Create score display var scoreLabel = new Text2('Puntuación:', { size: 50, fill: 0xff0000 }); scoreLabel.anchor.set(0.5, 0); scoreLabel.x = -300; LK.gui.top.addChild(scoreLabel); scoreLabel.y = 250; var scoreText = new Text2('0', { size: 60, fill: 0xff0000 }); scoreText.anchor.set(0.5, 0); scoreText.x = -300; LK.gui.top.addChild(scoreText); scoreText.y = 300; // Create current called number display var calledNumberContainer = new Container(); var calledNumberBg = LK.getAsset('calledNumberBg', { anchorX: 0.5, anchorY: 0.5 }); calledNumberContainer.addChild(calledNumberBg); var calledNumberText = new Text2('--', { size: 36, fill: 0xFFFFFF }); calledNumberText.anchor.set(0.5, 0.5); calledNumberContainer.addChild(calledNumberText); game.addChild(calledNumberContainer); calledNumberContainer.x = 1024; calledNumberContainer.y = 150; // Create info text var infoText = new Text2('Tap START to begin the game!', { size: 30, fill: 0xFFFFFF }); infoText.anchor.set(0.5, 0.5); game.addChild(infoText); infoText.x = 1024; infoText.y = 250; // Create start button startButton = new Container(); var startButtonBg = LK.getAsset('startButton', { anchorX: 0.5, anchorY: 0.5 }); startButton.addChild(startButtonBg); var startButtonText = new Text2('START', { size: 32, fill: 0xFFFFFF }); startButtonText.anchor.set(0.5, 0.5); startButton.addChild(startButtonText); startButton.x = 1024; startButton.y = 2500; game.addChild(startButton); startButton.down = function (x, y, obj) { if (!gameStarted) { gameStarted = true; game.removeChild(startButton); startButton = null; infoText.setText('Cards fill automatically as numbers are called!'); // Deduct token price from each card before starting the game for (var cardIdx = 0; cardIdx < bingoCards.length; cardIdx++) { var tokenStorageKey = 'tokenPrice_' + cardIdx; var tokenPriceIndex = storage[tokenStorageKey] || 0; var priceOptions = [10, 20, 30, 50, 100]; var tokenPrice = priceOptions[tokenPriceIndex]; // Deduct the token price (negative payment) paymentWindow.addPayment(-tokenPrice); } // Start the game LK.setTimeout(callNextNumber, 8); } }; // Create bingo cards - centered on screen for (var c = 0; c < 4; c++) { var card = new BingoCard(c); var row = Math.floor(c / 2); var col = c % 2; // Center cards on 2048x2732 screen - 2 cards per row var cardSpacingX = 900; // Space between cards horizontally var cardSpacingY = 780; // Space between cards vertically - increased separation var totalWidth = cardSpacingX; // Width for 2 cards var totalHeight = cardSpacingY; // Height for 2 rows var startX = (2048 - totalWidth) / 2; // Center horizontally var startY = 950; // Position below the UI elements - moved down card.x = startX + col * cardSpacingX; card.y = startY + row * cardSpacingY; game.addChild(card); bingoCards.push(card); // Create token price window below each card var tokenWindow = new TokenWindow(c); tokenWindow.x = card.x; tokenWindow.y = card.y + 350; // Position below the card game.addChild(tokenWindow); } // Create payment window at the top right of the screen paymentWindow = new PaymentWindow(); paymentWindow.x = 1500; // Position at top right - moved left paymentWindow.y = 400; game.addChild(paymentWindow); // Create pause button pauseButton = new Container(); var pauseButtonBg = LK.getAsset('pauseButton', { anchorX: 0.5, anchorY: 0.5 }); pauseButton.addChild(pauseButtonBg); var pauseButtonText = new Text2('||', { size: 40, fill: 0xFFFFFF }); pauseButtonText.anchor.set(0.5, 0.5); pauseButton.addChild(pauseButtonText); pauseButton.x = 600; pauseButton.y = 2600; game.addChild(pauseButton); pauseButton.down = function (x, y, obj) { if (gameStarted && !gamePaused) { pauseGame(); } }; function pauseGame() { if (!gamePaused && gameStarted) { gamePaused = true; // Clear the current timer if (callTimer) { LK.clearTimeout(callTimer); callTimer = null; } // Show pause window pauseWindow = new PauseWindow(); game.addChild(pauseWindow); pauseWindow.show(); } } function resumeGame() { if (gamePaused) { gamePaused = false; // Hide pause window if (pauseWindow) { pauseWindow.hide(); pauseWindow = null; } // Resume number calling if game was active if (gameStarted && availableNumbers.length > 0) { var delay = Math.max(16 - completedLines * 6, 8); callTimer = LK.setTimeout(callNextNumber, delay); } } } function quitGame() { // Reset all game variables gamePaused = false; gameStarted = false; if (callTimer) { LK.clearTimeout(callTimer); callTimer = null; } // Hide pause window if (pauseWindow) { pauseWindow.hide(); pauseWindow = null; } // Show game over LK.setTimeout(function () { LK.showGameOver(); }, 300); } function callNextNumber() { if (availableNumbers.length > 0) { var randomIndex = Math.floor(Math.random() * availableNumbers.length); currentCalledNumber = availableNumbers[randomIndex]; availableNumbers.splice(randomIndex, 1); calledNumbers.push(currentCalledNumber); calledNumberText.setText(currentCalledNumber.toString()); LK.getSound('numberCalled').play(); // Create red bubble for the called number var bubble = new NumberBubble(currentCalledNumber); game.addChild(bubble); numberBubbles.push(bubble); // Automatically mark the called number on all cards with reduced probability for (var cardIndex = 0; cardIndex < bingoCards.length; cardIndex++) { var card = bingoCards[cardIndex]; for (var row = 0; row < 3; row++) { for (var col = 0; col < 5; col++) { var bingoNumber = card.bingoNumbers[row][col]; if (bingoNumber.number === currentCalledNumber && !bingoNumber.isMarked) { // Base probability is 70%, but reduce by 30% more for cards with existing horizontal lines var markProbability = 0.7; if (cardHorizontalLines[cardIndex] > 0) { markProbability = 0.7 * 0.5; // Reduce by 50% to achieve 30% overall reduction in second line probability } if (Math.random() < markProbability) { bingoNumber.markNumber(); } } } } } // Flash the called number tween(calledNumberBg, { tint: 0xffff00 }, { duration: 200 }); tween(calledNumberBg, { tint: 0xffffff }, { duration: 200 }); // Schedule next number call only if not paused if (!gamePaused) { var delay = Math.max(16 - completedLines * 6, 8); callTimer = LK.setTimeout(callNextNumber, delay); } } } function checkForCompletedLines(cardIndex) { var card = bingoCards[cardIndex]; var newLinesCompleted = 0; var horizontalLinesCompleted = 0; // Check horizontal lines for (var row = 0; row < 3; row++) { var lineComplete = true; for (var col = 0; col < 5; col++) { if (!card.bingoNumbers[row][col].isMarked) { lineComplete = false; break; } } if (lineComplete) { newLinesCompleted++; horizontalLinesCompleted++; } } // Update horizontal line count for this card cardHorizontalLines[cardIndex] = horizontalLinesCompleted; // Vertical and diagonal line checking removed - only horizontal lines count for scoring if (newLinesCompleted > 0) { completedLines += newLinesCompleted; LK.getSound('lineComplete').play(); // Calculate score based on token price instead of fixed 100 points var tokenStorageKey = 'tokenPrice_' + cardIndex; var tokenPriceIndex = storage[tokenStorageKey] || 0; var priceOptions = [10, 20, 30, 50, 100]; var tokenPrice = priceOptions[tokenPriceIndex]; var scoreAmount = tokenPrice * newLinesCompleted; LK.setScore(LK.getScore() + scoreAmount); scoreText.setText(LK.getScore()); // Add payment based on token price for this card var paymentAmount = tokenPrice * newLinesCompleted; paymentWindow.addPayment(paymentAmount); // Show BINGO celebration window for horizontal line completion if (horizontalLinesCompleted > 0) { bingoWindow = new BingoWindow(); game.addChild(bingoWindow); bingoWindow.show(); } // Flash the card tween(card.cardBg, { tint: 0x00ff00 }, { duration: 300 }); tween(card.cardBg, { tint: 0xffffff }, { duration: 300 }); // Check for full card completion var allMarked = true; for (var r = 0; r < 3; r++) { for (var c = 0; c < 5; c++) { if (!card.bingoNumbers[r][c].isMarked) { allMarked = false; break; } } if (!allMarked) break; } if (allMarked) { // Full card bonus is 5 times the token price var fullCardBonus = tokenPrice * 5; LK.setScore(LK.getScore() + fullCardBonus); scoreText.setText(LK.getScore()); // Check win condition - 3 completed lines or 1 full card if (completedLines >= 3) { LK.clearTimeout(callTimer); LK.setTimeout(function () { LK.showYouWin(); }, 1500); } } } } // Game will start when start button is pressed game.update = function () { // Update score display scoreText.setText(LK.getScore()); // Bubbles now stay at the top, no cleanup needed // Check if all numbers have been called if (availableNumbers.length === 0 && calledNumbers.length === 75) { LK.clearTimeout(callTimer); if (completedLines >= 1) { LK.setTimeout(function () { LK.showYouWin(); }, 1500); } else { LK.setTimeout(function () { LK.showGameOver(); }, 1500); } } };
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/****
* Classes
****/
var BingoCard = Container.expand(function (cardIndex) {
var self = Container.call(this);
self.cardIndex = cardIndex;
self.numbers = [];
self.bingoNumbers = [];
self.cardBg = self.attachAsset('bingoCard', {
anchorX: 0.5,
anchorY: 0.5
});
// Generate 15 random unique numbers between 1-75
self.generateNumbers = function () {
var availableNumbers = [];
for (var i = 1; i <= 75; i++) {
availableNumbers.push(i);
}
for (var j = 0; j < 15; j++) {
var randomIndex = Math.floor(Math.random() * availableNumbers.length);
self.numbers.push(availableNumbers[randomIndex]);
availableNumbers.splice(randomIndex, 1);
}
};
self.createNumberGrid = function () {
var startX = -270;
var startY = -90;
var spacingX = 135;
var spacingY = 90;
for (var row = 0; row < 3; row++) {
self.bingoNumbers[row] = [];
for (var col = 0; col < 5; col++) {
var numberIndex = row * 5 + col;
var bingoNumber = new BingoNumber(self.numbers[numberIndex], self.cardIndex, row, col);
bingoNumber.x = startX + col * spacingX;
bingoNumber.y = startY + row * spacingY;
self.addChild(bingoNumber);
self.bingoNumbers[row][col] = bingoNumber;
}
}
};
self.generateNumbers();
self.createNumberGrid();
return self;
});
var BingoNumber = Container.expand(function (number, cardIndex, row, col) {
var self = Container.call(this);
self.number = number;
self.cardIndex = cardIndex;
self.row = row;
self.col = col;
self.isMarked = false;
self.bg = self.attachAsset('bingoNumber', {
anchorX: 0.5,
anchorY: 0.5
});
self.numberText = new Text2(number.toString(), {
size: 43,
fill: 0x000000
});
self.numberText.anchor.set(0.5, 0.5);
self.addChild(self.numberText);
self.markNumber = function () {
if (!self.isMarked) {
self.isMarked = true;
self.removeChild(self.bg);
self.bg = self.attachAsset('markedNumber', {
anchorX: 0.5,
anchorY: 0.5
});
// Replace the text with white color
self.removeChild(self.numberText);
self.numberText = new Text2(self.number.toString(), {
size: 43,
fill: 0xFFFFFF
});
self.numberText.anchor.set(0.5, 0.5);
self.addChild(self.numberText);
LK.getSound('numberMarked').play();
// Check for completed lines
checkForCompletedLines(self.cardIndex);
}
};
self.down = function (x, y, obj) {
// Numbers are now automatically marked, no manual interaction needed
};
return self;
});
var BingoWindow = Container.expand(function () {
var self = Container.call(this);
// Create celebration window background
self.windowBg = self.attachAsset('bingoWindow', {
anchorX: 0.5,
anchorY: 0.5
});
// Create BINGO text
self.bingoText = new Text2('BINGO!', {
size: 120,
fill: 0x000000
});
self.bingoText.anchor.set(0.5, 0.5);
self.addChild(self.bingoText);
// Position at center of screen
self.x = 1024;
self.y = 1366;
// Start invisible
self.alpha = 0;
self.scaleX = 0.1;
self.scaleY = 0.1;
self.show = function () {
// Animate window appearance
tween(self, {
alpha: 1,
scaleX: 1,
scaleY: 1
}, {
duration: 500,
easing: tween.easeOut
});
// Add pulsing animation to text
tween(self.bingoText, {
scaleX: 1.2,
scaleY: 1.2
}, {
duration: 300,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(self.bingoText, {
scaleX: 1,
scaleY: 1
}, {
duration: 300,
easing: tween.easeInOut
});
}
});
// Auto-hide after 0.75 seconds
LK.setTimeout(function () {
self.hide();
}, 750);
};
self.hide = function () {
tween(self, {
alpha: 0,
scaleX: 0.1,
scaleY: 0.1
}, {
duration: 300,
easing: tween.easeIn,
onFinish: function onFinish() {
if (self.parent) {
self.parent.removeChild(self);
}
}
});
};
return self;
});
var NumberBubble = Container.expand(function (number) {
var self = Container.call(this);
self.number = number;
self.speed = -3;
self.floatSpeed = 0;
// Create bubble background
self.bubbleBg = self.attachAsset('numberBubble', {
anchorX: 0.5,
anchorY: 0.5
});
// Create number text
self.numberText = new Text2(number.toString(), {
size: 32,
fill: 0xFFFFFF
});
self.numberText.anchor.set(0.5, 0.5);
self.addChild(self.numberText);
// Calculate position in three horizontal rows
var bubblesPerRow = 25; // 25 bubbles per row (75 total / 3 rows)
var bubbleSpacing = 80; // Spacing between bubbles
var rowSpacing = 90; // Spacing between rows
var startX = 50; // Start position for each row
var startY = 120; // Y position for first row
var currentBubbleCount = numberBubbles.length;
// Calculate which row and position within row
var row = Math.floor(currentBubbleCount / bubblesPerRow);
var positionInRow = currentBubbleCount % bubblesPerRow;
// Set target position in three rows
var targetX = startX + positionInRow * bubbleSpacing;
var targetY = startY + row * rowSpacing;
// Initialize position at bottom of screen for animation
self.x = targetX;
self.y = 2732 + 50; // Start below screen
self.lastY = self.y;
// Animate bubble entrance to target position
tween(self, {
y: targetY,
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 1500,
easing: tween.easeOut
});
// Add floating animation
tween(self.bubbleBg, {
rotation: Math.PI * 2
}, {
duration: 4000,
easing: tween.linear
});
self.update = function () {
// Bubbles stay fixed in position - no floating animation
};
return self;
});
var PauseWindow = Container.expand(function () {
var self = Container.call(this);
// Create window background
self.windowBg = self.attachAsset('pauseWindow', {
anchorX: 0.5,
anchorY: 0.5
});
// Create pause title
self.pauseTitle = new Text2('JUEGO PAUSADO', {
size: 60,
fill: 0xFFFFFF
});
self.pauseTitle.anchor.set(0.5, 0.5);
self.pauseTitle.y = -120;
self.addChild(self.pauseTitle);
// Create resume button
self.resumeButton = new Container();
var resumeBg = LK.getAsset('resumeButton', {
anchorX: 0.5,
anchorY: 0.5
});
self.resumeButton.addChild(resumeBg);
var resumeText = new Text2('CONTINUAR', {
size: 40,
fill: 0xFFFFFF
});
resumeText.anchor.set(0.5, 0.5);
self.resumeButton.addChild(resumeText);
self.resumeButton.y = -20;
self.addChild(self.resumeButton);
// Create quit button
self.quitButton = new Container();
var quitBg = LK.getAsset('quitButton', {
anchorX: 0.5,
anchorY: 0.5
});
self.quitButton.addChild(quitBg);
var quitText = new Text2('SALIR', {
size: 40,
fill: 0xFFFFFF
});
quitText.anchor.set(0.5, 0.5);
self.quitButton.addChild(quitText);
self.quitButton.y = 100;
self.addChild(self.quitButton);
// Position at center of screen
self.x = 1024;
self.y = 1366;
// Start invisible
self.alpha = 0;
self.scaleX = 0.1;
self.scaleY = 0.1;
self.show = function () {
// Animate window appearance
tween(self, {
alpha: 1,
scaleX: 1,
scaleY: 1
}, {
duration: 300,
easing: tween.easeOut
});
};
self.hide = function () {
tween(self, {
alpha: 0,
scaleX: 0.1,
scaleY: 0.1
}, {
duration: 200,
easing: tween.easeIn,
onFinish: function onFinish() {
if (self.parent) {
self.parent.removeChild(self);
}
}
});
};
// Resume button event
self.resumeButton.down = function (x, y, obj) {
resumeGame();
};
// Quit button event
self.quitButton.down = function (x, y, obj) {
quitGame();
};
return self;
});
var PaymentWindow = Container.expand(function () {
var self = Container.call(this);
// Load accumulated payments from storage, default to 0
self.totalPayments = storage.tokyoPayments || 0;
// Create window background
self.windowBg = self.attachAsset('paymentWindow', {
anchorX: 0.5,
anchorY: 0.5
});
// Create payment text
self.paymentText = new Text2('Total de Tokens: $' + self.totalPayments, {
size: 80,
fill: 0xff0000
});
self.paymentText.anchor.set(0.5, 0.5);
self.addChild(self.paymentText);
// Method to add payment
self.addPayment = function (amount) {
self.totalPayments += amount;
self.paymentText.setText('Total de Tokens: $' + self.totalPayments);
// Save to storage
storage.tokyoPayments = self.totalPayments;
// Flash animation for payment addition
tween(self.windowBg, {
tint: 0xffd700
}, {
duration: 200
});
tween(self.windowBg, {
tint: 0xffffff
}, {
duration: 200
});
};
// Method to reset payments
self.resetPayments = function () {
self.totalPayments = 0;
self.paymentText.setText('Total de Tokens: $' + self.totalPayments);
storage.tokyoPayments = self.totalPayments;
};
return self;
});
var TokenWindow = Container.expand(function (cardIndex) {
var self = Container.call(this);
self.cardIndex = cardIndex;
// Define predefined price options
self.priceOptions = [10, 20, 30, 50, 100];
// Load saved price index from storage, default to 0 if not found
var storageKey = 'tokenPrice_' + cardIndex;
self.currentPriceIndex = storage[storageKey] || 0;
// Create window background
self.windowBg = self.attachAsset('tokenWindow', {
anchorX: 0.5,
anchorY: 0.5
});
// Create price text with saved price
self.priceText = new Text2('Token Price: ' + self.priceOptions[self.currentPriceIndex], {
size: 100,
fill: 0xff0000
});
self.priceText.anchor.set(0.5, 0.5);
self.addChild(self.priceText);
// Add tap event to cycle through prices and save to storage
self.down = function (x, y, obj) {
self.currentPriceIndex = (self.currentPriceIndex + 1) % self.priceOptions.length;
self.priceText.setText('Token Price: ' + self.priceOptions[self.currentPriceIndex]);
// Save the selected price index to storage
storage[storageKey] = self.currentPriceIndex;
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x1a1a2e
});
/****
* Game Code
****/
var bingoCards = [];
var currentCalledNumber = null;
var calledNumbers = [];
var availableNumbers = [];
var callTimer = null;
var completedLines = 0;
var gameStarted = false;
var startButton = null;
var numberBubbles = [];
var bingoWindow = null;
var paymentWindow = null;
var cardHorizontalLines = [0, 0, 0, 0]; // Track horizontal lines per card
var gamePaused = false;
var pauseWindow = null;
var pauseButton = null;
// Initialize available numbers
for (var i = 1; i <= 75; i++) {
availableNumbers.push(i);
}
// Create score display
var scoreLabel = new Text2('Puntuación:', {
size: 50,
fill: 0xff0000
});
scoreLabel.anchor.set(0.5, 0);
scoreLabel.x = -300;
LK.gui.top.addChild(scoreLabel);
scoreLabel.y = 250;
var scoreText = new Text2('0', {
size: 60,
fill: 0xff0000
});
scoreText.anchor.set(0.5, 0);
scoreText.x = -300;
LK.gui.top.addChild(scoreText);
scoreText.y = 300;
// Create current called number display
var calledNumberContainer = new Container();
var calledNumberBg = LK.getAsset('calledNumberBg', {
anchorX: 0.5,
anchorY: 0.5
});
calledNumberContainer.addChild(calledNumberBg);
var calledNumberText = new Text2('--', {
size: 36,
fill: 0xFFFFFF
});
calledNumberText.anchor.set(0.5, 0.5);
calledNumberContainer.addChild(calledNumberText);
game.addChild(calledNumberContainer);
calledNumberContainer.x = 1024;
calledNumberContainer.y = 150;
// Create info text
var infoText = new Text2('Tap START to begin the game!', {
size: 30,
fill: 0xFFFFFF
});
infoText.anchor.set(0.5, 0.5);
game.addChild(infoText);
infoText.x = 1024;
infoText.y = 250;
// Create start button
startButton = new Container();
var startButtonBg = LK.getAsset('startButton', {
anchorX: 0.5,
anchorY: 0.5
});
startButton.addChild(startButtonBg);
var startButtonText = new Text2('START', {
size: 32,
fill: 0xFFFFFF
});
startButtonText.anchor.set(0.5, 0.5);
startButton.addChild(startButtonText);
startButton.x = 1024;
startButton.y = 2500;
game.addChild(startButton);
startButton.down = function (x, y, obj) {
if (!gameStarted) {
gameStarted = true;
game.removeChild(startButton);
startButton = null;
infoText.setText('Cards fill automatically as numbers are called!');
// Deduct token price from each card before starting the game
for (var cardIdx = 0; cardIdx < bingoCards.length; cardIdx++) {
var tokenStorageKey = 'tokenPrice_' + cardIdx;
var tokenPriceIndex = storage[tokenStorageKey] || 0;
var priceOptions = [10, 20, 30, 50, 100];
var tokenPrice = priceOptions[tokenPriceIndex];
// Deduct the token price (negative payment)
paymentWindow.addPayment(-tokenPrice);
}
// Start the game
LK.setTimeout(callNextNumber, 8);
}
};
// Create bingo cards - centered on screen
for (var c = 0; c < 4; c++) {
var card = new BingoCard(c);
var row = Math.floor(c / 2);
var col = c % 2;
// Center cards on 2048x2732 screen - 2 cards per row
var cardSpacingX = 900; // Space between cards horizontally
var cardSpacingY = 780; // Space between cards vertically - increased separation
var totalWidth = cardSpacingX; // Width for 2 cards
var totalHeight = cardSpacingY; // Height for 2 rows
var startX = (2048 - totalWidth) / 2; // Center horizontally
var startY = 950; // Position below the UI elements - moved down
card.x = startX + col * cardSpacingX;
card.y = startY + row * cardSpacingY;
game.addChild(card);
bingoCards.push(card);
// Create token price window below each card
var tokenWindow = new TokenWindow(c);
tokenWindow.x = card.x;
tokenWindow.y = card.y + 350; // Position below the card
game.addChild(tokenWindow);
}
// Create payment window at the top right of the screen
paymentWindow = new PaymentWindow();
paymentWindow.x = 1500; // Position at top right - moved left
paymentWindow.y = 400;
game.addChild(paymentWindow);
// Create pause button
pauseButton = new Container();
var pauseButtonBg = LK.getAsset('pauseButton', {
anchorX: 0.5,
anchorY: 0.5
});
pauseButton.addChild(pauseButtonBg);
var pauseButtonText = new Text2('||', {
size: 40,
fill: 0xFFFFFF
});
pauseButtonText.anchor.set(0.5, 0.5);
pauseButton.addChild(pauseButtonText);
pauseButton.x = 600;
pauseButton.y = 2600;
game.addChild(pauseButton);
pauseButton.down = function (x, y, obj) {
if (gameStarted && !gamePaused) {
pauseGame();
}
};
function pauseGame() {
if (!gamePaused && gameStarted) {
gamePaused = true;
// Clear the current timer
if (callTimer) {
LK.clearTimeout(callTimer);
callTimer = null;
}
// Show pause window
pauseWindow = new PauseWindow();
game.addChild(pauseWindow);
pauseWindow.show();
}
}
function resumeGame() {
if (gamePaused) {
gamePaused = false;
// Hide pause window
if (pauseWindow) {
pauseWindow.hide();
pauseWindow = null;
}
// Resume number calling if game was active
if (gameStarted && availableNumbers.length > 0) {
var delay = Math.max(16 - completedLines * 6, 8);
callTimer = LK.setTimeout(callNextNumber, delay);
}
}
}
function quitGame() {
// Reset all game variables
gamePaused = false;
gameStarted = false;
if (callTimer) {
LK.clearTimeout(callTimer);
callTimer = null;
}
// Hide pause window
if (pauseWindow) {
pauseWindow.hide();
pauseWindow = null;
}
// Show game over
LK.setTimeout(function () {
LK.showGameOver();
}, 300);
}
function callNextNumber() {
if (availableNumbers.length > 0) {
var randomIndex = Math.floor(Math.random() * availableNumbers.length);
currentCalledNumber = availableNumbers[randomIndex];
availableNumbers.splice(randomIndex, 1);
calledNumbers.push(currentCalledNumber);
calledNumberText.setText(currentCalledNumber.toString());
LK.getSound('numberCalled').play();
// Create red bubble for the called number
var bubble = new NumberBubble(currentCalledNumber);
game.addChild(bubble);
numberBubbles.push(bubble);
// Automatically mark the called number on all cards with reduced probability
for (var cardIndex = 0; cardIndex < bingoCards.length; cardIndex++) {
var card = bingoCards[cardIndex];
for (var row = 0; row < 3; row++) {
for (var col = 0; col < 5; col++) {
var bingoNumber = card.bingoNumbers[row][col];
if (bingoNumber.number === currentCalledNumber && !bingoNumber.isMarked) {
// Base probability is 70%, but reduce by 30% more for cards with existing horizontal lines
var markProbability = 0.7;
if (cardHorizontalLines[cardIndex] > 0) {
markProbability = 0.7 * 0.5; // Reduce by 50% to achieve 30% overall reduction in second line probability
}
if (Math.random() < markProbability) {
bingoNumber.markNumber();
}
}
}
}
}
// Flash the called number
tween(calledNumberBg, {
tint: 0xffff00
}, {
duration: 200
});
tween(calledNumberBg, {
tint: 0xffffff
}, {
duration: 200
});
// Schedule next number call only if not paused
if (!gamePaused) {
var delay = Math.max(16 - completedLines * 6, 8);
callTimer = LK.setTimeout(callNextNumber, delay);
}
}
}
function checkForCompletedLines(cardIndex) {
var card = bingoCards[cardIndex];
var newLinesCompleted = 0;
var horizontalLinesCompleted = 0;
// Check horizontal lines
for (var row = 0; row < 3; row++) {
var lineComplete = true;
for (var col = 0; col < 5; col++) {
if (!card.bingoNumbers[row][col].isMarked) {
lineComplete = false;
break;
}
}
if (lineComplete) {
newLinesCompleted++;
horizontalLinesCompleted++;
}
}
// Update horizontal line count for this card
cardHorizontalLines[cardIndex] = horizontalLinesCompleted;
// Vertical and diagonal line checking removed - only horizontal lines count for scoring
if (newLinesCompleted > 0) {
completedLines += newLinesCompleted;
LK.getSound('lineComplete').play();
// Calculate score based on token price instead of fixed 100 points
var tokenStorageKey = 'tokenPrice_' + cardIndex;
var tokenPriceIndex = storage[tokenStorageKey] || 0;
var priceOptions = [10, 20, 30, 50, 100];
var tokenPrice = priceOptions[tokenPriceIndex];
var scoreAmount = tokenPrice * newLinesCompleted;
LK.setScore(LK.getScore() + scoreAmount);
scoreText.setText(LK.getScore());
// Add payment based on token price for this card
var paymentAmount = tokenPrice * newLinesCompleted;
paymentWindow.addPayment(paymentAmount);
// Show BINGO celebration window for horizontal line completion
if (horizontalLinesCompleted > 0) {
bingoWindow = new BingoWindow();
game.addChild(bingoWindow);
bingoWindow.show();
}
// Flash the card
tween(card.cardBg, {
tint: 0x00ff00
}, {
duration: 300
});
tween(card.cardBg, {
tint: 0xffffff
}, {
duration: 300
});
// Check for full card completion
var allMarked = true;
for (var r = 0; r < 3; r++) {
for (var c = 0; c < 5; c++) {
if (!card.bingoNumbers[r][c].isMarked) {
allMarked = false;
break;
}
}
if (!allMarked) break;
}
if (allMarked) {
// Full card bonus is 5 times the token price
var fullCardBonus = tokenPrice * 5;
LK.setScore(LK.getScore() + fullCardBonus);
scoreText.setText(LK.getScore());
// Check win condition - 3 completed lines or 1 full card
if (completedLines >= 3) {
LK.clearTimeout(callTimer);
LK.setTimeout(function () {
LK.showYouWin();
}, 1500);
}
}
}
}
// Game will start when start button is pressed
game.update = function () {
// Update score display
scoreText.setText(LK.getScore());
// Bubbles now stay at the top, no cleanup needed
// Check if all numbers have been called
if (availableNumbers.length === 0 && calledNumbers.length === 75) {
LK.clearTimeout(callTimer);
if (completedLines >= 1) {
LK.setTimeout(function () {
LK.showYouWin();
}, 1500);
} else {
LK.setTimeout(function () {
LK.showGameOver();
}, 1500);
}
}
};