/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ var Coin = Container.expand(function () { var self = Container.call(this); // Create container for the coin halves var coinContainer = new Container(); coinContainer.x = 0; coinContainer.y = 0; self.addChild(coinContainer); // Create blue half (top) var blueHalf = coinContainer.attachAsset('coinBlueHalf', { anchorX: 0.5, anchorY: 1 }); blueHalf.x = 0; blueHalf.y = 0; // Create black half (bottom) var blackHalf = coinContainer.attachAsset('coinBlackHalf', { anchorX: 0.5, anchorY: 0 }); blackHalf.x = 0; blackHalf.y = 0; // Reference for animations (use the container) var coinGraphics = coinContainer; self.isFlipping = false; self.result = null; self.flip = function (callback) { if (self.isFlipping) return; self.isFlipping = true; self.result = Math.random() < 0.5 ? 'heads' : 'tails'; // Play flip sound LK.getSound('coinFlip').play(); // Animate coin flip with multiple rotations and scale changes var rotations = 8 + Math.floor(Math.random() * 4); // 8-11 rotations var duration = 2000 + Math.random() * 1000; // 2-3 seconds // First phase: spin up with scale tween(coinGraphics, { rotation: Math.PI * rotations, scaleX: 1.5, scaleY: 0.3 }, { duration: duration * 0.7, easing: tween.easeOut, onFinish: function onFinish() { // Second phase: settle down var finalRotation = self.result === 'heads' ? 0 : Math.PI; tween(coinGraphics, { rotation: finalRotation, scaleX: 1, scaleY: 1 }, { duration: duration * 0.3, easing: tween.easeInOut, onFinish: function onFinish() { self.isFlipping = false; if (callback) callback(self.result); } }); } }); // Vertical bounce animation var originalY = self.y; tween(self, { y: originalY - 200 }, { duration: duration * 0.5, easing: tween.easeOut, onFinish: function onFinish() { tween(self, { y: originalY }, { duration: duration * 0.5, easing: tween.bounceOut }); } }); }; return self; }); var PredictionButton = Container.expand(function (type, color) { var self = Container.call(this); var buttonGraphics = self.attachAsset(type === 'heads' ? 'headsButton' : 'tailsButton', { anchorX: 0.5, anchorY: 0.5 }); var buttonText = new Text2(type === 'heads' ? 'YAZI' : 'TURA', { size: 60, fill: 0xFFFFFF }); buttonText.anchor.set(0.5, 0.5); self.addChild(buttonText); self.type = type; self.isEnabled = true; self.setEnabled = function (enabled) { self.isEnabled = enabled; buttonGraphics.alpha = enabled ? 1 : 0.5; }; self.down = function (x, y, obj) { if (!self.isEnabled) return; // Button press animation tween(buttonGraphics, { scaleX: 0.95, scaleY: 0.95 }, { duration: 100, onFinish: function onFinish() { tween(buttonGraphics, { scaleX: 1, scaleY: 1 }, { duration: 100 }); } }); if (onPredictionMade) { onPredictionMade(self.type); } }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x1a1a2e }); /**** * Game Code ****/ // Game state variables var gameState = 'waiting'; // 'waiting', 'flipping', 'result' var currentPrediction = null; var streak = 0; var maxStreak = 0; var totalFlips = 0; var correctFlips = 0; var currentBet = 10; // Default bet amount var minBet = 10; // Minimum bet amount var playerCoins = 100; // Starting coins // Create coin var coin = game.addChild(new Coin()); coin.x = 2048 / 2; coin.y = 2732 / 2 - 200; // Create prediction buttons var headsButton = game.addChild(new PredictionButton('heads')); headsButton.x = 2048 / 2 - 250; headsButton.y = 2732 - 300; var tailsButton = game.addChild(new PredictionButton('tails')); tailsButton.x = 2048 / 2 + 250; tailsButton.y = 2732 - 300; // Initialize player with starting coins LK.setScore(playerCoins); // Create UI elements var scoreText = new Text2('Coins: ' + playerCoins, { size: 80, fill: 0xFFFFFF }); scoreText.anchor.set(0.5, 0); LK.gui.top.addChild(scoreText); // Create betting UI var betText = new Text2('Bet: ' + currentBet, { size: 60, fill: 0xFFD700 }); betText.anchor.set(0.5, 0); betText.x = 2048 / 2; betText.y = 2732 - 500; game.addChild(betText); // Create bet adjustment buttons var increaseBetButton = game.addChild(LK.getAsset('headsButton', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.6, scaleY: 0.6 })); increaseBetButton.x = 2048 / 2 + 150; increaseBetButton.y = 2732 - 500; var decreaseBetButton = game.addChild(LK.getAsset('tailsButton', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.6, scaleY: 0.6 })); decreaseBetButton.x = 2048 / 2 - 150; decreaseBetButton.y = 2732 - 500; // Add text to bet buttons var increaseBetText = new Text2('+', { size: 50, fill: 0xFFFFFF }); increaseBetText.anchor.set(0.5, 0.5); increaseBetText.x = increaseBetButton.x; increaseBetText.y = increaseBetButton.y; game.addChild(increaseBetText); var decreaseBetText = new Text2('-', { size: 50, fill: 0xFFFFFF }); decreaseBetText.anchor.set(0.5, 0.5); decreaseBetText.x = decreaseBetButton.x; decreaseBetText.y = decreaseBetButton.y; game.addChild(decreaseBetText); var streakText = new Text2('Streak: 0', { size: 60, fill: 0xFFD700 }); streakText.anchor.set(0, 0); streakText.x = 50; streakText.y = 150; LK.gui.addChild(streakText); var maxStreakText = new Text2('Best: 0', { size: 60, fill: 0xFFD700 }); maxStreakText.anchor.set(1, 0); maxStreakText.x = LK.gui.width - 50; maxStreakText.y = 150; LK.gui.addChild(maxStreakText); var instructionText = new Text2('Predict the coin flip!', { size: 70, fill: 0xFFFFFF }); instructionText.anchor.set(0.5, 0.5); instructionText.x = 2048 / 2; instructionText.y = 2732 / 2 + 300; game.addChild(instructionText); var resultText = new Text2('', { size: 100, fill: 0x00FF00 }); resultText.anchor.set(0.5, 0.5); resultText.x = 2048 / 2; resultText.y = 2732 / 2 + 150; game.addChild(resultText); // Bet adjustment functions function increaseBet() { if (gameState !== 'waiting') return; var newBet = currentBet + 10; if (newBet <= LK.getScore()) { currentBet = newBet; betText.setText('Bet: ' + currentBet); } } function decreaseBet() { if (gameState !== 'waiting') return; if (currentBet > minBet) { currentBet -= 10; betText.setText('Bet: ' + currentBet); } } // Add touch handlers for bet buttons game.down = function (x, y, obj) { // Check if increase bet button was tapped if (Math.abs(x - increaseBetButton.x) < 120 && Math.abs(y - increaseBetButton.y) < 36) { increaseBet(); } // Check if decrease bet button was tapped else if (Math.abs(x - decreaseBetButton.x) < 120 && Math.abs(y - decreaseBetButton.y) < 36) { decreaseBet(); } }; // Prediction callback function onPredictionMade(prediction) { if (gameState !== 'waiting') return; // Check if player has enough coins to bet if (LK.getScore() < currentBet) { // Flash screen red to indicate insufficient funds LK.effects.flashScreen(0xff0000, 500); return; } currentPrediction = prediction; gameState = 'flipping'; // Deduct bet amount immediately LK.setScore(LK.getScore() - currentBet); // Disable buttons during flip headsButton.setEnabled(false); tailsButton.setEnabled(false); // Update instruction instructionText.setText('Flipping...'); resultText.setText(''); // Start coin flip coin.flip(function (result) { gameState = 'result'; totalFlips++; var isCorrect = currentPrediction === result; if (isCorrect) { correctFlips++; streak++; if (streak > maxStreak) { maxStreak = streak; } // Win bet - player gets back double their bet var winnings = currentBet * 2; LK.setScore(LK.getScore() + winnings); resultText.setText('CORRECT! +' + winnings); resultText.tint = 0x00ff00; // Play correct sound LK.getSound('correct').play(); // Flash effect for correct guess LK.effects.flashObject(coin, 0x00ff00, 500); } else { streak = 0; resultText.setText('WRONG! -' + currentBet); resultText.tint = 0xff0000; // Play wrong sound LK.getSound('wrong').play(); // Flash effect for wrong guess LK.effects.flashObject(coin, 0xff0000, 500); } // Update UI updateUI(); // Show result for 2 seconds then reset LK.setTimeout(function () { resetForNextFlip(); }, 2000); }); } function updateUI() { scoreText.setText('Coins: ' + LK.getScore()); streakText.setText('Streak: ' + streak); maxStreakText.setText('Best: ' + maxStreak); // Update bet if player doesn't have enough coins if (currentBet > LK.getScore() && LK.getScore() >= minBet) { currentBet = Math.floor(LK.getScore() / 10) * 10; if (currentBet < minBet) currentBet = minBet; betText.setText('Bet: ' + currentBet); } // Animate streak text when it increases if (streak > 0) { tween(streakText, { scaleX: 1.2, scaleY: 1.2 }, { duration: 200, onFinish: function onFinish() { tween(streakText, { scaleX: 1, scaleY: 1 }, { duration: 200 }); } }); } } function resetForNextFlip() { gameState = 'waiting'; currentPrediction = null; // Check if player has run out of coins if (LK.getScore() < minBet) { LK.showGameOver(); return; } // Re-enable buttons headsButton.setEnabled(true); tailsButton.setEnabled(true); // Reset instruction text instructionText.setText('Predict the coin flip!'); resultText.setText(''); // Check for win condition (high score or long streak) if (LK.getScore() >= 1000 || maxStreak >= 20) { LK.showYouWin(); } } // Initialize UI updateUI();
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var Coin = Container.expand(function () {
var self = Container.call(this);
// Create container for the coin halves
var coinContainer = new Container();
coinContainer.x = 0;
coinContainer.y = 0;
self.addChild(coinContainer);
// Create blue half (top)
var blueHalf = coinContainer.attachAsset('coinBlueHalf', {
anchorX: 0.5,
anchorY: 1
});
blueHalf.x = 0;
blueHalf.y = 0;
// Create black half (bottom)
var blackHalf = coinContainer.attachAsset('coinBlackHalf', {
anchorX: 0.5,
anchorY: 0
});
blackHalf.x = 0;
blackHalf.y = 0;
// Reference for animations (use the container)
var coinGraphics = coinContainer;
self.isFlipping = false;
self.result = null;
self.flip = function (callback) {
if (self.isFlipping) return;
self.isFlipping = true;
self.result = Math.random() < 0.5 ? 'heads' : 'tails';
// Play flip sound
LK.getSound('coinFlip').play();
// Animate coin flip with multiple rotations and scale changes
var rotations = 8 + Math.floor(Math.random() * 4); // 8-11 rotations
var duration = 2000 + Math.random() * 1000; // 2-3 seconds
// First phase: spin up with scale
tween(coinGraphics, {
rotation: Math.PI * rotations,
scaleX: 1.5,
scaleY: 0.3
}, {
duration: duration * 0.7,
easing: tween.easeOut,
onFinish: function onFinish() {
// Second phase: settle down
var finalRotation = self.result === 'heads' ? 0 : Math.PI;
tween(coinGraphics, {
rotation: finalRotation,
scaleX: 1,
scaleY: 1
}, {
duration: duration * 0.3,
easing: tween.easeInOut,
onFinish: function onFinish() {
self.isFlipping = false;
if (callback) callback(self.result);
}
});
}
});
// Vertical bounce animation
var originalY = self.y;
tween(self, {
y: originalY - 200
}, {
duration: duration * 0.5,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(self, {
y: originalY
}, {
duration: duration * 0.5,
easing: tween.bounceOut
});
}
});
};
return self;
});
var PredictionButton = Container.expand(function (type, color) {
var self = Container.call(this);
var buttonGraphics = self.attachAsset(type === 'heads' ? 'headsButton' : 'tailsButton', {
anchorX: 0.5,
anchorY: 0.5
});
var buttonText = new Text2(type === 'heads' ? 'YAZI' : 'TURA', {
size: 60,
fill: 0xFFFFFF
});
buttonText.anchor.set(0.5, 0.5);
self.addChild(buttonText);
self.type = type;
self.isEnabled = true;
self.setEnabled = function (enabled) {
self.isEnabled = enabled;
buttonGraphics.alpha = enabled ? 1 : 0.5;
};
self.down = function (x, y, obj) {
if (!self.isEnabled) return;
// Button press animation
tween(buttonGraphics, {
scaleX: 0.95,
scaleY: 0.95
}, {
duration: 100,
onFinish: function onFinish() {
tween(buttonGraphics, {
scaleX: 1,
scaleY: 1
}, {
duration: 100
});
}
});
if (onPredictionMade) {
onPredictionMade(self.type);
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x1a1a2e
});
/****
* Game Code
****/
// Game state variables
var gameState = 'waiting'; // 'waiting', 'flipping', 'result'
var currentPrediction = null;
var streak = 0;
var maxStreak = 0;
var totalFlips = 0;
var correctFlips = 0;
var currentBet = 10; // Default bet amount
var minBet = 10; // Minimum bet amount
var playerCoins = 100; // Starting coins
// Create coin
var coin = game.addChild(new Coin());
coin.x = 2048 / 2;
coin.y = 2732 / 2 - 200;
// Create prediction buttons
var headsButton = game.addChild(new PredictionButton('heads'));
headsButton.x = 2048 / 2 - 250;
headsButton.y = 2732 - 300;
var tailsButton = game.addChild(new PredictionButton('tails'));
tailsButton.x = 2048 / 2 + 250;
tailsButton.y = 2732 - 300;
// Initialize player with starting coins
LK.setScore(playerCoins);
// Create UI elements
var scoreText = new Text2('Coins: ' + playerCoins, {
size: 80,
fill: 0xFFFFFF
});
scoreText.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreText);
// Create betting UI
var betText = new Text2('Bet: ' + currentBet, {
size: 60,
fill: 0xFFD700
});
betText.anchor.set(0.5, 0);
betText.x = 2048 / 2;
betText.y = 2732 - 500;
game.addChild(betText);
// Create bet adjustment buttons
var increaseBetButton = game.addChild(LK.getAsset('headsButton', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.6,
scaleY: 0.6
}));
increaseBetButton.x = 2048 / 2 + 150;
increaseBetButton.y = 2732 - 500;
var decreaseBetButton = game.addChild(LK.getAsset('tailsButton', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.6,
scaleY: 0.6
}));
decreaseBetButton.x = 2048 / 2 - 150;
decreaseBetButton.y = 2732 - 500;
// Add text to bet buttons
var increaseBetText = new Text2('+', {
size: 50,
fill: 0xFFFFFF
});
increaseBetText.anchor.set(0.5, 0.5);
increaseBetText.x = increaseBetButton.x;
increaseBetText.y = increaseBetButton.y;
game.addChild(increaseBetText);
var decreaseBetText = new Text2('-', {
size: 50,
fill: 0xFFFFFF
});
decreaseBetText.anchor.set(0.5, 0.5);
decreaseBetText.x = decreaseBetButton.x;
decreaseBetText.y = decreaseBetButton.y;
game.addChild(decreaseBetText);
var streakText = new Text2('Streak: 0', {
size: 60,
fill: 0xFFD700
});
streakText.anchor.set(0, 0);
streakText.x = 50;
streakText.y = 150;
LK.gui.addChild(streakText);
var maxStreakText = new Text2('Best: 0', {
size: 60,
fill: 0xFFD700
});
maxStreakText.anchor.set(1, 0);
maxStreakText.x = LK.gui.width - 50;
maxStreakText.y = 150;
LK.gui.addChild(maxStreakText);
var instructionText = new Text2('Predict the coin flip!', {
size: 70,
fill: 0xFFFFFF
});
instructionText.anchor.set(0.5, 0.5);
instructionText.x = 2048 / 2;
instructionText.y = 2732 / 2 + 300;
game.addChild(instructionText);
var resultText = new Text2('', {
size: 100,
fill: 0x00FF00
});
resultText.anchor.set(0.5, 0.5);
resultText.x = 2048 / 2;
resultText.y = 2732 / 2 + 150;
game.addChild(resultText);
// Bet adjustment functions
function increaseBet() {
if (gameState !== 'waiting') return;
var newBet = currentBet + 10;
if (newBet <= LK.getScore()) {
currentBet = newBet;
betText.setText('Bet: ' + currentBet);
}
}
function decreaseBet() {
if (gameState !== 'waiting') return;
if (currentBet > minBet) {
currentBet -= 10;
betText.setText('Bet: ' + currentBet);
}
}
// Add touch handlers for bet buttons
game.down = function (x, y, obj) {
// Check if increase bet button was tapped
if (Math.abs(x - increaseBetButton.x) < 120 && Math.abs(y - increaseBetButton.y) < 36) {
increaseBet();
}
// Check if decrease bet button was tapped
else if (Math.abs(x - decreaseBetButton.x) < 120 && Math.abs(y - decreaseBetButton.y) < 36) {
decreaseBet();
}
};
// Prediction callback
function onPredictionMade(prediction) {
if (gameState !== 'waiting') return;
// Check if player has enough coins to bet
if (LK.getScore() < currentBet) {
// Flash screen red to indicate insufficient funds
LK.effects.flashScreen(0xff0000, 500);
return;
}
currentPrediction = prediction;
gameState = 'flipping';
// Deduct bet amount immediately
LK.setScore(LK.getScore() - currentBet);
// Disable buttons during flip
headsButton.setEnabled(false);
tailsButton.setEnabled(false);
// Update instruction
instructionText.setText('Flipping...');
resultText.setText('');
// Start coin flip
coin.flip(function (result) {
gameState = 'result';
totalFlips++;
var isCorrect = currentPrediction === result;
if (isCorrect) {
correctFlips++;
streak++;
if (streak > maxStreak) {
maxStreak = streak;
}
// Win bet - player gets back double their bet
var winnings = currentBet * 2;
LK.setScore(LK.getScore() + winnings);
resultText.setText('CORRECT! +' + winnings);
resultText.tint = 0x00ff00;
// Play correct sound
LK.getSound('correct').play();
// Flash effect for correct guess
LK.effects.flashObject(coin, 0x00ff00, 500);
} else {
streak = 0;
resultText.setText('WRONG! -' + currentBet);
resultText.tint = 0xff0000;
// Play wrong sound
LK.getSound('wrong').play();
// Flash effect for wrong guess
LK.effects.flashObject(coin, 0xff0000, 500);
}
// Update UI
updateUI();
// Show result for 2 seconds then reset
LK.setTimeout(function () {
resetForNextFlip();
}, 2000);
});
}
function updateUI() {
scoreText.setText('Coins: ' + LK.getScore());
streakText.setText('Streak: ' + streak);
maxStreakText.setText('Best: ' + maxStreak);
// Update bet if player doesn't have enough coins
if (currentBet > LK.getScore() && LK.getScore() >= minBet) {
currentBet = Math.floor(LK.getScore() / 10) * 10;
if (currentBet < minBet) currentBet = minBet;
betText.setText('Bet: ' + currentBet);
}
// Animate streak text when it increases
if (streak > 0) {
tween(streakText, {
scaleX: 1.2,
scaleY: 1.2
}, {
duration: 200,
onFinish: function onFinish() {
tween(streakText, {
scaleX: 1,
scaleY: 1
}, {
duration: 200
});
}
});
}
}
function resetForNextFlip() {
gameState = 'waiting';
currentPrediction = null;
// Check if player has run out of coins
if (LK.getScore() < minBet) {
LK.showGameOver();
return;
}
// Re-enable buttons
headsButton.setEnabled(true);
tailsButton.setEnabled(true);
// Reset instruction text
instructionText.setText('Predict the coin flip!');
resultText.setText('');
// Check for win condition (high score or long streak)
if (LK.getScore() >= 1000 || maxStreak >= 20) {
LK.showYouWin();
}
}
// Initialize UI
updateUI();