/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ // Card class: represents a single card (type, subtype, owner, value, etc) var Card = Container.expand(function () { var self = Container.call(this); // Card properties (set after creation) self.cardType = null; // 'human', 'elf', 'orc' self.subType = null; // 'warrior', 'archer', 'wizard' self.owner = null; // 'player', 'bot1', 'bot2' self.value = 0; // base value (for future expansion) self.isFaceUp = false; self.cardIndex = -1; // 0-8, for unique identification // Card visuals // Card art asset (will be set in setCard) var cardArt = null; // Set card data and visuals self.setCard = function (cardType, subType, owner, cardIndex) { self.cardType = cardType; self.subType = subType; self.owner = owner; self.cardIndex = cardIndex; // Remove previous cardArt if any if (cardArt) { cardArt.destroy(); cardArt = null; } // Determine which asset to use: for bots, use 'cardBg' until played, then real asset var assetId; if ((owner === 'bot1' || owner === 'bot2') && !self.isFaceUp) { assetId = 'cardBg'; } else { assetId = cardType + '-' + subType; } cardArt = self.attachAsset(assetId, { anchorX: 0.5, anchorY: 0.5, width: 400, height: 600 }); // Always on top for click/tap detection self.setChildIndex(cardArt, self.children.length - 1); }; // Show/hide card face self.setFaceUp = function (isUp) { self.isFaceUp = isUp; // If bot card and being turned face up, swap asset to real card art if ((self.owner === 'bot1' || self.owner === 'bot2') && isUp) { if (cardArt) { cardArt.destroy(); cardArt = null; } var assetId = self.cardType + '-' + self.subType; cardArt = self.attachAsset(assetId, { anchorX: 0.5, anchorY: 0.5, width: 400, height: 600 }); self.setChildIndex(cardArt, self.children.length - 1); } else if (cardArt) { cardArt.alpha = isUp ? 1 : 0.2; } }; // For click/tap detection self.down = function (x, y, obj) { // Allow player to play a card by tapping a card in their hand if (self.owner === 'player' && self.isFaceUp && canPlayCard && !roundCards.player) { playPlayerCard(self); } }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x22223a }); /**** * Game Code ****/ // --- Game Data --- var cardTypes = ['human', 'elf', 'orc']; var subTypes = ['warrior', 'archer', 'wizard']; // All 9 unique cards var allCards = []; for (var i = 0; i < cardTypes.length; i++) { for (var j = 0; j < subTypes.length; j++) { allCards.push({ cardType: cardTypes[i], subType: subTypes[j], cardIndex: i * 3 + j }); } } // Location data // Each location has a name, color, and a list of cardType+subType combos that get +1 point var locations = [{ name: 'Castle', color: 0x607d8b, bonuses: [{ cardType: 'human', subType: 'archer' }, { cardType: 'human', subType: 'mage' }, { cardType: 'human', subType: 'warrior' }, { cardType: 'elf', subType: 'warrior' }, { cardType: 'orc', subType: 'warrior' }] }, { name: 'Forest', color: 0x4caf50, bonuses: [{ cardType: 'elf', subType: 'archer' }, { cardType: 'elf', subType: 'mage' }, { cardType: 'elf', subType: 'archer' }, // duplicate, but harmless { cardType: 'human', subType: 'archer' }, { cardType: 'orc', subType: 'archer' }] }, { name: 'Cave', color: 0x795548, bonuses: [{ cardType: 'orc', subType: 'mage' }, { cardType: 'orc', subType: 'warrior' }, { cardType: 'orc', subType: 'archer' }, { cardType: 'human', subType: 'mage' }, { cardType: 'elf', subType: 'mage' }] }]; // --- Game State --- var playerHand = []; var bot1Hand = []; var bot2Hand = []; var playerScore = 0; var bot1Score = 0; var bot2Score = 0; var round = 1; var maxRounds = 3; var currentGame = 1; var totalGames = 1; var sessionPlayerWins = 0; var sessionBot1Wins = 0; var sessionBot2Wins = 0; var sessionPlayerTotalScore = 0; var sessionBot1TotalScore = 0; var sessionBot2TotalScore = 0; var canPlayCard = false; var roundCards = { player: null, bot1: null, bot2: null }; var roundLocation = null; var allCardObjs = []; // All Card instances for cleanup var locationNode = null; var infoText = null; var scoreText = null; var roundText = null; // --- GUI Setup --- // Score text (left side) - current round scores scoreText = new Text2('', { size: 50, fill: "#000", // Black text stroke: "#fff", // White stroke for shine//{1B.1} strokeThickness: 6, //{1B.2} shadowColor: "#fff", //{1B.3} shadowBlur: 18, //{1B.4} shadowDistance: 0, //{1B.5} shadowAngle: 0, //{1B.6} shadowAlpha: 0.7 //{1B.7} }); scoreText.anchor.set(0, 0); scoreText.x = 120; scoreText.y = 150; LK.gui.topLeft.addChild(scoreText); // Bot1 score text var bot1TotalText = new Text2('', { size: 50, fill: "#000", // Black text stroke: "#fff", // White stroke for shine//{1E.1} strokeThickness: 6, //{1E.2} shadowColor: "#fff", //{1E.3} shadowBlur: 18, //{1E.4} shadowDistance: 0, //{1E.5} shadowAngle: 0, //{1E.6} shadowAlpha: 0.7 //{1E.7} }); bot1TotalText.anchor.set(0, 0); bot1TotalText.x = 120; bot1TotalText.y = 210; LK.gui.topLeft.addChild(bot1TotalText); // Bot2 score text var bot2TotalText = new Text2('', { size: 50, fill: "#000", // Black text stroke: "#fff", // White stroke for shine//{1H.1} strokeThickness: 6, //{1H.2} shadowColor: "#fff", //{1H.3} shadowBlur: 18, //{1H.4} shadowDistance: 0, //{1H.5} shadowAngle: 0, //{1H.6} shadowAlpha: 0.7 //{1H.7} }); bot2TotalText.anchor.set(0, 0); bot2TotalText.x = 120; bot2TotalText.y = 270; LK.gui.topLeft.addChild(bot2TotalText); // Total score text var totalScoreText = new Text2('', { size: 50, fill: "#000", // Black text stroke: "#fff", // White stroke for shine//{1K.1} strokeThickness: 6, //{1K.2} shadowColor: "#fff", //{1K.3} shadowBlur: 18, //{1K.4} shadowDistance: 0, //{1K.5} shadowAngle: 0, //{1K.6} shadowAlpha: 0.7 //{1K.7} }); totalScoreText.anchor.set(0, 0); totalScoreText.x = 120; totalScoreText.y = 330; LK.gui.topLeft.addChild(totalScoreText); // Round text (center) roundText = new Text2('', { size: 80, fill: "#000", // Black text stroke: "#fff", // White stroke for shine//{1M.1} strokeThickness: 8, //{1M.2} shadowColor: "#fff", //{1M.3} shadowBlur: 24, //{1M.4} shadowDistance: 0, //{1M.5} shadowAngle: 0, //{1M.6} shadowAlpha: 0.7 //{1M.7} }); roundText.anchor.set(0.5, 0.5); LK.gui.center.addChild(roundText); // --- Helper Functions --- function shuffle(arr) { // Fisher-Yates shuffle for (var i = arr.length - 1; i > 0; i--) { var j = Math.floor(Math.random() * (i + 1)); var t = arr[i]; arr[i] = arr[j]; arr[j] = t; } return arr; } function dealHands() { var deck = allCards.slice(); shuffle(deck); var cardsPerPlayer = maxRounds; playerHand = deck.slice(0, cardsPerPlayer); bot1Hand = deck.slice(cardsPerPlayer, cardsPerPlayer * 2); bot2Hand = deck.slice(cardsPerPlayer * 2, cardsPerPlayer * 3); } function updateScoreText() { scoreText.setText("You: " + playerScore); bot1TotalText.setText("Legolas: " + bot1Score); bot2TotalText.setText("Urukai: " + bot2Score); totalScoreText.setText("Total: " + sessionPlayerTotalScore + " | " + sessionBot1TotalScore + " | " + sessionBot2TotalScore); } function updateRoundText(msg) { if (msg) { roundText.setText(msg); } else { roundText.setText("Round " + round + " / " + maxRounds); } } function clearBoard() { for (var i = 0; i < allCardObjs.length; i++) { allCardObjs[i].destroy(); } allCardObjs = []; if (locationNode) { locationNode.destroy(); locationNode = null; } } function showLocation(location) { // Remove previous background if any if (game._locationBgImage) { game._locationBgImage.destroy(); game._locationBgImage = null; } // Determine background asset id by location name (lowercase) var bgAssetId = ''; if (location.name.toLowerCase() === 'castle') { bgAssetId = 'castle'; } else if (location.name.toLowerCase() === 'forest') { bgAssetId = 'forest'; } else if (location.name.toLowerCase() === 'cave') { bgAssetId = 'cave'; } // Add background image covering the whole game area if (bgAssetId) { var bgImg = LK.getAsset(bgAssetId, { anchorX: 0, anchorY: 0, x: 0, y: 0, width: 2048, height: 2732 }); game.addChildAt(bgImg, 0); // Add at bottom game._locationBgImage = bgImg; } // Show location in center locationNode = LK.getAsset('locationBg', { width: 600, height: 200, color: location.color, shape: 'box', anchorX: 0.5, anchorY: 0.5, x: 2048 / 2, y: 400 // Move higher on the screen }); game.addChild(locationNode); var locText = new Text2(location.name, { size: 90, fill: "#fff" }); locText.anchor.set(0.5, 0.5); locText.x = 0; locText.y = 0; locationNode.addChild(locText); // Remove previous bonusText if any if (game._bonusText) { game._bonusText.destroy(); game._bonusText = null; } } function layoutHands() { // Player hand (bottom) var spacing = 400; var startX = 2048 / 2 - spacing; var y = 2732 - 400; for (var i = 0; i < playerHand.length; i++) { var c = new Card(); c.setCard(playerHand[i].cardType, playerHand[i].subType, 'player', playerHand[i].cardIndex); c.x = startX + i * spacing; c.y = y; // Show player's hand face up so the player can see their cards c.setFaceUp(true); game.addChild(c); allCardObjs.push(c); } // Bot1 hand (left) var x1 = 400; var spacingY1 = 400; var startY1 = 2732 / 2 - spacingY1; for (var i = 0; i < bot1Hand.length; i++) { var c = new Card(); c.setCard(bot1Hand[i].cardType, bot1Hand[i].subType, 'bot1', bot1Hand[i].cardIndex); c.x = x1; c.y = startY1 + i * spacingY1; c.setFaceUp(false); c.rotation = Math.PI / 2; // Rotate 90 degrees for left bot game.addChild(c); allCardObjs.push(c); } // Bot2 hand (right) var x2 = 2048 - 400; var spacingY2 = 400; var startY2 = 2732 / 2 - spacingY2; for (var i = 0; i < bot2Hand.length; i++) { var c = new Card(); c.setCard(bot2Hand[i].cardType, bot2Hand[i].subType, 'bot2', bot2Hand[i].cardIndex); c.x = x2; c.y = startY2 + i * spacingY2; c.setFaceUp(false); c.rotation = Math.PI / 2; // Rotate 90 degrees for right bot game.addChild(c); allCardObjs.push(c); } } function playPlayerCard(cardObj) { if (!canPlayCard || roundCards.player) return; canPlayCard = false; roundCards.player = cardObj; cardObj.setFaceUp(true); // Play card playing sound LK.getSound('card-playing-sound').play(); // Animate to center tween(cardObj, { x: 2048 / 2 - 300, y: 2732 / 2 + 250 }, { duration: 400, easing: tween.cubicOut }); // Remove from hand for (var i = 0; i < playerHand.length; i++) { if (playerHand[i].cardIndex === cardObj.cardIndex) { playerHand.splice(i, 1); break; } } // Bots play after short delay LK.setTimeout(function () { playBotCards(); }, 500); } function playBotCards() { // Helper: calculate points for a card for the current roundLocation function calcCardPoints(card) { if (!card) return 0; // Return 0 points if card is null var p = 0; var cardName = (card.cardType + '-' + card.subType).toLowerCase(); if (roundLocation && roundLocation.name) { var loc = roundLocation.name.toLowerCase(); if (loc === 'cave') { if (cardName.indexOf('wizard') !== -1) p += 1; if (cardName.indexOf('orc') !== -1) p += 1; } else if (loc === 'castle') { if (cardName.indexOf('warrior') !== -1) p += 1; if (cardName.indexOf('human') !== -1) p += 1; } else if (loc === 'forest') { if (cardName.indexOf('archer') !== -1) p += 1; if (cardName.indexOf('elf') !== -1) p += 1; } } // Extra +1 for human-warrior, elf-archer, orc-wizard in every location if (card.cardType === 'human' && card.subType === 'warrior' || card.cardType === 'elf' && card.subType === 'archer' || card.cardType === 'orc' && card.subType === 'wizard') { p += 1; } return p; } // Bot1: pick best card var bestIdx1 = 0; var bestScore1 = -1; for (var i = 0; i < bot1Hand.length; i++) { var pts = calcCardPoints(bot1Hand[i]); if (pts > bestScore1) { bestScore1 = pts; bestIdx1 = i; } } var idx1 = bestIdx1; var card1 = null; for (var i = 0; i < allCardObjs.length; i++) { if (allCardObjs[i].owner === 'bot1' && allCardObjs[i].cardIndex === bot1Hand[idx1].cardIndex) { card1 = allCardObjs[i]; break; } } roundCards.bot1 = card1; if (card1) { card1.setFaceUp(true); } // Rotate bot1 card 90 degrees when played to the ground if (card1) { card1.rotation = Math.PI / 2; tween(card1, { x: 2048 / 2, y: 2732 / 2 - 250 }, { duration: 400, easing: tween.cubicOut }); } bot1Hand.splice(idx1, 1); // Bot2: pick best card var bestIdx2 = 0; var bestScore2 = -1; for (var i = 0; i < bot2Hand.length; i++) { var pts = calcCardPoints(bot2Hand[i]); if (pts > bestScore2) { bestScore2 = pts; bestIdx2 = i; } } var idx2 = bestIdx2; var card2 = null; for (var i = 0; i < allCardObjs.length; i++) { if (allCardObjs[i].owner === 'bot2' && allCardObjs[i].cardIndex === bot2Hand[idx2].cardIndex) { card2 = allCardObjs[i]; break; } } roundCards.bot2 = card2; if (card2) { card2.setFaceUp(true); } // Rotate bot2 card 90 degrees when played to the ground if (card2) { card2.rotation = Math.PI / 2; tween(card2, { x: 2048 / 2 + 300, y: 2732 / 2 + 250 }, { duration: 400, easing: tween.cubicOut }); } bot2Hand.splice(idx2, 1); // Reveal location after short delay LK.setTimeout(function () { revealLocationAndScore(); }, 700); } function revealLocationAndScore() { // Location is already selected and shown at round start // Calculate points var pts = { player: 0, bot1: 0, bot2: 0 }; // New scoring: points by substring match per location rules function calcCardPoints(card) { if (!card) return 0; // Return 0 points if card is null var p = 0; // Build card name for substring matching var cardName = (card.cardType + '-' + card.subType).toLowerCase(); if (roundLocation && roundLocation.name) { var loc = roundLocation.name.toLowerCase(); if (loc === 'cave') { // +1 for 'wizard' in name, +1 for 'orc' in name if (cardName.indexOf('wizard') !== -1) p += 1; if (cardName.indexOf('orc') !== -1) p += 1; } else if (loc === 'castle') { // +1 for 'warrior' in name, +1 for 'human' in name if (cardName.indexOf('warrior') !== -1) p += 1; if (cardName.indexOf('human') !== -1) p += 1; } else if (loc === 'forest') { // +1 for 'archer' in name, +1 for 'elf' in name if (cardName.indexOf('archer') !== -1) p += 1; if (cardName.indexOf('elf') !== -1) p += 1; } } // Extra +1 for human-warrior, elf-archer, orc-wizard in every location if (card.cardType === 'human' && card.subType === 'warrior' || card.cardType === 'elf' && card.subType === 'archer' || card.cardType === 'orc' && card.subType === 'wizard') { p += 1; } return p; } pts.player = calcCardPoints(roundCards.player); pts.bot1 = calcCardPoints(roundCards.bot1); pts.bot2 = calcCardPoints(roundCards.bot2); // Animate cards (flash winner) var maxPts = Math.max(pts.player, pts.bot1, pts.bot2); if (pts.player === maxPts) { LK.effects.flashObject(roundCards.player, 0xffff00, 700); } if (pts.bot1 === maxPts) { LK.effects.flashObject(roundCards.bot1, 0xffff00, 700); } if (pts.bot2 === maxPts) { LK.effects.flashObject(roundCards.bot2, 0xffff00, 700); } // Update scores playerScore += pts.player; bot1Score += pts.bot1; bot2Score += pts.bot2; updateScoreText(); // Show round result var msg = "You: +" + pts.player + " Legolas: +" + pts.bot1 + " Urukai: +" + pts.bot2; updateRoundText(msg); // Next round or end after delay LK.setTimeout(function () { round++; if (round > maxRounds) { endGame(); } else { startRound(); } }, 1500); } function startRound() { clearBoard(); roundCards = { player: null, bot1: null, bot2: null }; // Pick random location from availableLocations, ensuring no repeats if (availableLocations.length === 0) { availableLocations = locations.slice(); } var idx = Math.floor(Math.random() * availableLocations.length); roundLocation = availableLocations[idx]; availableLocations.splice(idx, 1); // Remove used location showLocation(roundLocation); canPlayCard = true; updateScoreText(); updateRoundText(); layoutHands(); } function endGame() { clearBoard(); canPlayCard = false; // Add current game scores to session totals sessionPlayerTotalScore += playerScore; sessionBot1TotalScore += bot1Score; sessionBot2TotalScore += bot2Score; var winner = ''; // Track session wins for individual game results if (playerScore > bot1Score && playerScore > bot2Score) { sessionPlayerWins++; winner = "You win game " + currentGame + "!"; } else if (bot1Score > playerScore && bot1Score > bot2Score) { sessionBot1Wins++; winner = "Bot1 wins game " + currentGame + "!"; } else if (bot2Score > playerScore && bot2Score > bot1Score) { sessionBot2Wins++; winner = "Bot2 wins game " + currentGame + "!"; } else { winner = "Game " + currentGame + " tie!"; } // Check if session is complete if (currentGame >= totalGames) { // Session complete - show total score, then after 3 seconds, show win/lose var sessionWinner = ''; var winType = ''; // Prepare array of scores and names var scoreArr = [{ name: "YOU", score: sessionPlayerTotalScore }, { name: "LEGOLAS", score: sessionBot1TotalScore }, { name: "URUKAI", score: sessionBot2TotalScore }]; // Sort descending by score scoreArr.sort(function (a, b) { return b.score - a.score; }); // Build multiline string, top to bottom, highest first var scoreLines = ""; for (var i = 0; i < scoreArr.length; i++) { scoreLines += scoreArr[i].name + ": " + scoreArr[i].score + " P"; if (i < scoreArr.length - 1) scoreLines += "\n"; } // Determine winner for win/lose if (scoreArr[0].score > scoreArr[1].score) { if (scoreArr[0].name === "YOU") { sessionWinner = "You win the session!"; winType = "win"; } else if (scoreArr[0].name === "LEGOLAS") { sessionWinner = "Legolas wins the session!"; winType = "lose"; } else if (scoreArr[0].name === "URUKAI") { sessionWinner = "Urukai wins the session!"; winType = "lose"; } else { sessionWinner = scoreArr[0].name + " wins the session!"; winType = "lose"; } } else { sessionWinner = "Session ends in a tie!"; winType = "lose"; } // Show total score message in the center, sorted, with names updateRoundText(scoreLines); // After 3 seconds, show win/lose LK.setTimeout(function () { updateRoundText(sessionWinner); LK.setTimeout(function () { if (winType === "win") { LK.showYouWin(); } else { LK.showGameOver(); } }, 1500); }, 3000); } else { // More games to play in session currentGame++; // Show next game after delay LK.setTimeout(function () { newGame(); }, 2000); } updateRoundText(''); } // --- Game Start --- // Track which locations have been used this game var availableLocations = []; // Game start button var startButton = null; function showStartButton() { if (startButton) { startButton.destroy(); startButton = null; } if (game._startMenu) { game._startMenu.destroy(); game._startMenu = null; } // Create menu container var menuContainer = new Container(); menuContainer.x = 2048 / 2; menuContainer.y = 2732 / 2; game._startMenu = menuContainer; // Logo image at the top middle above the HUMAN GAME text var logoImg = LK.getAsset('logo', { anchorX: 0.5, anchorY: 0.5, x: 0, y: -500, width: 1050, height: 1050 }); menuContainer.addChild(logoImg); // Title - bigger and more prominent var titleText = new Text2('', { size: 180, fill: "#000", stroke: "#fff", strokeThickness: 8, shadowColor: "#fff", shadowBlur: 30, shadowDistance: 0, shadowAngle: 0, shadowAlpha: 0.7 }); titleText.anchor.set(0.5, 0.5); titleText.x = 0; titleText.y = -300; menuContainer.addChild(titleText); // Subtitle for magic theme var subtitleText = new Text2('', { size: 100, fill: "#000", stroke: "#fff", strokeThickness: 6, shadowColor: "#fff", shadowBlur: 20, shadowDistance: 0, shadowAngle: 0, shadowAlpha: 0.7 }); subtitleText.anchor.set(0.5, 0.5); subtitleText.x = 0; subtitleText.y = -200; menuContainer.addChild(subtitleText); // Single game button (3 rounds) - bigger and more magical var button1 = new Text2('HUMAN GAME', { size: 100, fill: "#000", stroke: "#fff", strokeThickness: 8, shadowColor: "#fff", shadowBlur: 40, shadowDistance: 0, shadowAngle: 0, shadowAlpha: 0.9 }); button1.anchor.set(0.5, 0.5); button1.x = 0; button1.y = 100; button1.interactive = true; button1.buttonMode = true; button1.down = function (x, y, obj) { maxRounds = 3; totalGames = 1; currentGame = 1; sessionPlayerWins = 0; sessionBot1Wins = 0; sessionBot2Wins = 0; sessionPlayerTotalScore = 0; sessionBot1TotalScore = 0; sessionBot2TotalScore = 0; menuContainer.visible = false; newGame(); }; menuContainer.addChild(button1); // 3 games button (3 hands each) - bigger and more magical var button3 = new Text2('ELF GAME', { size: 100, fill: "#000", stroke: "#fff", strokeThickness: 8, shadowColor: "#fff", shadowBlur: 40, shadowDistance: 0, shadowAngle: 0, shadowAlpha: 0.9 }); button3.anchor.set(0.5, 0.5); button3.x = 0; button3.y = 220; button3.interactive = true; button3.buttonMode = true; button3.down = function (x, y, obj) { maxRounds = 3; totalGames = 3; currentGame = 1; sessionPlayerWins = 0; sessionBot1Wins = 0; sessionBot2Wins = 0; sessionPlayerTotalScore = 0; sessionBot1TotalScore = 0; sessionBot2TotalScore = 0; menuContainer.visible = false; newGame(); }; menuContainer.addChild(button3); // 5 games button (3 hands each) - bigger and more magical var button5 = new Text2('KING GAME', { size: 100, fill: "#000", stroke: "#fff", strokeThickness: 8, shadowColor: "#fff", shadowBlur: 40, shadowDistance: 0, shadowAngle: 0, shadowAlpha: 0.9 }); button5.anchor.set(0.5, 0.5); button5.x = 0; button5.y = 340; button5.interactive = true; button5.buttonMode = true; button5.down = function (x, y, obj) { maxRounds = 3; totalGames = 5; currentGame = 1; sessionPlayerWins = 0; sessionBot1Wins = 0; sessionBot2Wins = 0; sessionPlayerTotalScore = 0; sessionBot1TotalScore = 0; sessionBot2TotalScore = 0; menuContainer.visible = false; newGame(); }; menuContainer.addChild(button5); game.addChild(menuContainer); } // Only call newGame from the start button now function newGame() { playerScore = 0; bot1Score = 0; bot2Score = 0; round = 1; canPlayCard = false; roundCards = { player: null, bot1: null, bot2: null }; roundLocation = null; clearBoard(); dealHands(); updateScoreText(); updateRoundText("Game " + currentGame + " / " + totalGames); // Reset available locations for the new game availableLocations = locations.slice(); // Start the first round which will handle location selection startRound(); } // Show the start button on load showStartButton(); // Play background music as soon as the game loads LK.playMusic('backgraund-song'); // --- Game move handler (for drag, not used here) --- game.move = function (x, y, obj) { // No drag in this game };
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
// Card class: represents a single card (type, subtype, owner, value, etc)
var Card = Container.expand(function () {
var self = Container.call(this);
// Card properties (set after creation)
self.cardType = null; // 'human', 'elf', 'orc'
self.subType = null; // 'warrior', 'archer', 'wizard'
self.owner = null; // 'player', 'bot1', 'bot2'
self.value = 0; // base value (for future expansion)
self.isFaceUp = false;
self.cardIndex = -1; // 0-8, for unique identification
// Card visuals
// Card art asset (will be set in setCard)
var cardArt = null;
// Set card data and visuals
self.setCard = function (cardType, subType, owner, cardIndex) {
self.cardType = cardType;
self.subType = subType;
self.owner = owner;
self.cardIndex = cardIndex;
// Remove previous cardArt if any
if (cardArt) {
cardArt.destroy();
cardArt = null;
}
// Determine which asset to use: for bots, use 'cardBg' until played, then real asset
var assetId;
if ((owner === 'bot1' || owner === 'bot2') && !self.isFaceUp) {
assetId = 'cardBg';
} else {
assetId = cardType + '-' + subType;
}
cardArt = self.attachAsset(assetId, {
anchorX: 0.5,
anchorY: 0.5,
width: 400,
height: 600
});
// Always on top for click/tap detection
self.setChildIndex(cardArt, self.children.length - 1);
};
// Show/hide card face
self.setFaceUp = function (isUp) {
self.isFaceUp = isUp;
// If bot card and being turned face up, swap asset to real card art
if ((self.owner === 'bot1' || self.owner === 'bot2') && isUp) {
if (cardArt) {
cardArt.destroy();
cardArt = null;
}
var assetId = self.cardType + '-' + self.subType;
cardArt = self.attachAsset(assetId, {
anchorX: 0.5,
anchorY: 0.5,
width: 400,
height: 600
});
self.setChildIndex(cardArt, self.children.length - 1);
} else if (cardArt) {
cardArt.alpha = isUp ? 1 : 0.2;
}
};
// For click/tap detection
self.down = function (x, y, obj) {
// Allow player to play a card by tapping a card in their hand
if (self.owner === 'player' && self.isFaceUp && canPlayCard && !roundCards.player) {
playPlayerCard(self);
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x22223a
});
/****
* Game Code
****/
// --- Game Data ---
var cardTypes = ['human', 'elf', 'orc'];
var subTypes = ['warrior', 'archer', 'wizard'];
// All 9 unique cards
var allCards = [];
for (var i = 0; i < cardTypes.length; i++) {
for (var j = 0; j < subTypes.length; j++) {
allCards.push({
cardType: cardTypes[i],
subType: subTypes[j],
cardIndex: i * 3 + j
});
}
}
// Location data
// Each location has a name, color, and a list of cardType+subType combos that get +1 point
var locations = [{
name: 'Castle',
color: 0x607d8b,
bonuses: [{
cardType: 'human',
subType: 'archer'
}, {
cardType: 'human',
subType: 'mage'
}, {
cardType: 'human',
subType: 'warrior'
}, {
cardType: 'elf',
subType: 'warrior'
}, {
cardType: 'orc',
subType: 'warrior'
}]
}, {
name: 'Forest',
color: 0x4caf50,
bonuses: [{
cardType: 'elf',
subType: 'archer'
}, {
cardType: 'elf',
subType: 'mage'
}, {
cardType: 'elf',
subType: 'archer'
},
// duplicate, but harmless
{
cardType: 'human',
subType: 'archer'
}, {
cardType: 'orc',
subType: 'archer'
}]
}, {
name: 'Cave',
color: 0x795548,
bonuses: [{
cardType: 'orc',
subType: 'mage'
}, {
cardType: 'orc',
subType: 'warrior'
}, {
cardType: 'orc',
subType: 'archer'
}, {
cardType: 'human',
subType: 'mage'
}, {
cardType: 'elf',
subType: 'mage'
}]
}];
// --- Game State ---
var playerHand = [];
var bot1Hand = [];
var bot2Hand = [];
var playerScore = 0;
var bot1Score = 0;
var bot2Score = 0;
var round = 1;
var maxRounds = 3;
var currentGame = 1;
var totalGames = 1;
var sessionPlayerWins = 0;
var sessionBot1Wins = 0;
var sessionBot2Wins = 0;
var sessionPlayerTotalScore = 0;
var sessionBot1TotalScore = 0;
var sessionBot2TotalScore = 0;
var canPlayCard = false;
var roundCards = {
player: null,
bot1: null,
bot2: null
};
var roundLocation = null;
var allCardObjs = []; // All Card instances for cleanup
var locationNode = null;
var infoText = null;
var scoreText = null;
var roundText = null;
// --- GUI Setup ---
// Score text (left side) - current round scores
scoreText = new Text2('', {
size: 50,
fill: "#000",
// Black text
stroke: "#fff",
// White stroke for shine//{1B.1}
strokeThickness: 6,
//{1B.2}
shadowColor: "#fff",
//{1B.3}
shadowBlur: 18,
//{1B.4}
shadowDistance: 0,
//{1B.5}
shadowAngle: 0,
//{1B.6}
shadowAlpha: 0.7 //{1B.7}
});
scoreText.anchor.set(0, 0);
scoreText.x = 120;
scoreText.y = 150;
LK.gui.topLeft.addChild(scoreText);
// Bot1 score text
var bot1TotalText = new Text2('', {
size: 50,
fill: "#000",
// Black text
stroke: "#fff",
// White stroke for shine//{1E.1}
strokeThickness: 6,
//{1E.2}
shadowColor: "#fff",
//{1E.3}
shadowBlur: 18,
//{1E.4}
shadowDistance: 0,
//{1E.5}
shadowAngle: 0,
//{1E.6}
shadowAlpha: 0.7 //{1E.7}
});
bot1TotalText.anchor.set(0, 0);
bot1TotalText.x = 120;
bot1TotalText.y = 210;
LK.gui.topLeft.addChild(bot1TotalText);
// Bot2 score text
var bot2TotalText = new Text2('', {
size: 50,
fill: "#000",
// Black text
stroke: "#fff",
// White stroke for shine//{1H.1}
strokeThickness: 6,
//{1H.2}
shadowColor: "#fff",
//{1H.3}
shadowBlur: 18,
//{1H.4}
shadowDistance: 0,
//{1H.5}
shadowAngle: 0,
//{1H.6}
shadowAlpha: 0.7 //{1H.7}
});
bot2TotalText.anchor.set(0, 0);
bot2TotalText.x = 120;
bot2TotalText.y = 270;
LK.gui.topLeft.addChild(bot2TotalText);
// Total score text
var totalScoreText = new Text2('', {
size: 50,
fill: "#000",
// Black text
stroke: "#fff",
// White stroke for shine//{1K.1}
strokeThickness: 6,
//{1K.2}
shadowColor: "#fff",
//{1K.3}
shadowBlur: 18,
//{1K.4}
shadowDistance: 0,
//{1K.5}
shadowAngle: 0,
//{1K.6}
shadowAlpha: 0.7 //{1K.7}
});
totalScoreText.anchor.set(0, 0);
totalScoreText.x = 120;
totalScoreText.y = 330;
LK.gui.topLeft.addChild(totalScoreText);
// Round text (center)
roundText = new Text2('', {
size: 80,
fill: "#000",
// Black text
stroke: "#fff",
// White stroke for shine//{1M.1}
strokeThickness: 8,
//{1M.2}
shadowColor: "#fff",
//{1M.3}
shadowBlur: 24,
//{1M.4}
shadowDistance: 0,
//{1M.5}
shadowAngle: 0,
//{1M.6}
shadowAlpha: 0.7 //{1M.7}
});
roundText.anchor.set(0.5, 0.5);
LK.gui.center.addChild(roundText);
// --- Helper Functions ---
function shuffle(arr) {
// Fisher-Yates shuffle
for (var i = arr.length - 1; i > 0; i--) {
var j = Math.floor(Math.random() * (i + 1));
var t = arr[i];
arr[i] = arr[j];
arr[j] = t;
}
return arr;
}
function dealHands() {
var deck = allCards.slice();
shuffle(deck);
var cardsPerPlayer = maxRounds;
playerHand = deck.slice(0, cardsPerPlayer);
bot1Hand = deck.slice(cardsPerPlayer, cardsPerPlayer * 2);
bot2Hand = deck.slice(cardsPerPlayer * 2, cardsPerPlayer * 3);
}
function updateScoreText() {
scoreText.setText("You: " + playerScore);
bot1TotalText.setText("Legolas: " + bot1Score);
bot2TotalText.setText("Urukai: " + bot2Score);
totalScoreText.setText("Total: " + sessionPlayerTotalScore + " | " + sessionBot1TotalScore + " | " + sessionBot2TotalScore);
}
function updateRoundText(msg) {
if (msg) {
roundText.setText(msg);
} else {
roundText.setText("Round " + round + " / " + maxRounds);
}
}
function clearBoard() {
for (var i = 0; i < allCardObjs.length; i++) {
allCardObjs[i].destroy();
}
allCardObjs = [];
if (locationNode) {
locationNode.destroy();
locationNode = null;
}
}
function showLocation(location) {
// Remove previous background if any
if (game._locationBgImage) {
game._locationBgImage.destroy();
game._locationBgImage = null;
}
// Determine background asset id by location name (lowercase)
var bgAssetId = '';
if (location.name.toLowerCase() === 'castle') {
bgAssetId = 'castle';
} else if (location.name.toLowerCase() === 'forest') {
bgAssetId = 'forest';
} else if (location.name.toLowerCase() === 'cave') {
bgAssetId = 'cave';
}
// Add background image covering the whole game area
if (bgAssetId) {
var bgImg = LK.getAsset(bgAssetId, {
anchorX: 0,
anchorY: 0,
x: 0,
y: 0,
width: 2048,
height: 2732
});
game.addChildAt(bgImg, 0); // Add at bottom
game._locationBgImage = bgImg;
}
// Show location in center
locationNode = LK.getAsset('locationBg', {
width: 600,
height: 200,
color: location.color,
shape: 'box',
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2,
y: 400 // Move higher on the screen
});
game.addChild(locationNode);
var locText = new Text2(location.name, {
size: 90,
fill: "#fff"
});
locText.anchor.set(0.5, 0.5);
locText.x = 0;
locText.y = 0;
locationNode.addChild(locText);
// Remove previous bonusText if any
if (game._bonusText) {
game._bonusText.destroy();
game._bonusText = null;
}
}
function layoutHands() {
// Player hand (bottom)
var spacing = 400;
var startX = 2048 / 2 - spacing;
var y = 2732 - 400;
for (var i = 0; i < playerHand.length; i++) {
var c = new Card();
c.setCard(playerHand[i].cardType, playerHand[i].subType, 'player', playerHand[i].cardIndex);
c.x = startX + i * spacing;
c.y = y;
// Show player's hand face up so the player can see their cards
c.setFaceUp(true);
game.addChild(c);
allCardObjs.push(c);
}
// Bot1 hand (left)
var x1 = 400;
var spacingY1 = 400;
var startY1 = 2732 / 2 - spacingY1;
for (var i = 0; i < bot1Hand.length; i++) {
var c = new Card();
c.setCard(bot1Hand[i].cardType, bot1Hand[i].subType, 'bot1', bot1Hand[i].cardIndex);
c.x = x1;
c.y = startY1 + i * spacingY1;
c.setFaceUp(false);
c.rotation = Math.PI / 2; // Rotate 90 degrees for left bot
game.addChild(c);
allCardObjs.push(c);
}
// Bot2 hand (right)
var x2 = 2048 - 400;
var spacingY2 = 400;
var startY2 = 2732 / 2 - spacingY2;
for (var i = 0; i < bot2Hand.length; i++) {
var c = new Card();
c.setCard(bot2Hand[i].cardType, bot2Hand[i].subType, 'bot2', bot2Hand[i].cardIndex);
c.x = x2;
c.y = startY2 + i * spacingY2;
c.setFaceUp(false);
c.rotation = Math.PI / 2; // Rotate 90 degrees for right bot
game.addChild(c);
allCardObjs.push(c);
}
}
function playPlayerCard(cardObj) {
if (!canPlayCard || roundCards.player) return;
canPlayCard = false;
roundCards.player = cardObj;
cardObj.setFaceUp(true);
// Play card playing sound
LK.getSound('card-playing-sound').play();
// Animate to center
tween(cardObj, {
x: 2048 / 2 - 300,
y: 2732 / 2 + 250
}, {
duration: 400,
easing: tween.cubicOut
});
// Remove from hand
for (var i = 0; i < playerHand.length; i++) {
if (playerHand[i].cardIndex === cardObj.cardIndex) {
playerHand.splice(i, 1);
break;
}
}
// Bots play after short delay
LK.setTimeout(function () {
playBotCards();
}, 500);
}
function playBotCards() {
// Helper: calculate points for a card for the current roundLocation
function calcCardPoints(card) {
if (!card) return 0; // Return 0 points if card is null
var p = 0;
var cardName = (card.cardType + '-' + card.subType).toLowerCase();
if (roundLocation && roundLocation.name) {
var loc = roundLocation.name.toLowerCase();
if (loc === 'cave') {
if (cardName.indexOf('wizard') !== -1) p += 1;
if (cardName.indexOf('orc') !== -1) p += 1;
} else if (loc === 'castle') {
if (cardName.indexOf('warrior') !== -1) p += 1;
if (cardName.indexOf('human') !== -1) p += 1;
} else if (loc === 'forest') {
if (cardName.indexOf('archer') !== -1) p += 1;
if (cardName.indexOf('elf') !== -1) p += 1;
}
}
// Extra +1 for human-warrior, elf-archer, orc-wizard in every location
if (card.cardType === 'human' && card.subType === 'warrior' || card.cardType === 'elf' && card.subType === 'archer' || card.cardType === 'orc' && card.subType === 'wizard') {
p += 1;
}
return p;
}
// Bot1: pick best card
var bestIdx1 = 0;
var bestScore1 = -1;
for (var i = 0; i < bot1Hand.length; i++) {
var pts = calcCardPoints(bot1Hand[i]);
if (pts > bestScore1) {
bestScore1 = pts;
bestIdx1 = i;
}
}
var idx1 = bestIdx1;
var card1 = null;
for (var i = 0; i < allCardObjs.length; i++) {
if (allCardObjs[i].owner === 'bot1' && allCardObjs[i].cardIndex === bot1Hand[idx1].cardIndex) {
card1 = allCardObjs[i];
break;
}
}
roundCards.bot1 = card1;
if (card1) {
card1.setFaceUp(true);
}
// Rotate bot1 card 90 degrees when played to the ground
if (card1) {
card1.rotation = Math.PI / 2;
tween(card1, {
x: 2048 / 2,
y: 2732 / 2 - 250
}, {
duration: 400,
easing: tween.cubicOut
});
}
bot1Hand.splice(idx1, 1);
// Bot2: pick best card
var bestIdx2 = 0;
var bestScore2 = -1;
for (var i = 0; i < bot2Hand.length; i++) {
var pts = calcCardPoints(bot2Hand[i]);
if (pts > bestScore2) {
bestScore2 = pts;
bestIdx2 = i;
}
}
var idx2 = bestIdx2;
var card2 = null;
for (var i = 0; i < allCardObjs.length; i++) {
if (allCardObjs[i].owner === 'bot2' && allCardObjs[i].cardIndex === bot2Hand[idx2].cardIndex) {
card2 = allCardObjs[i];
break;
}
}
roundCards.bot2 = card2;
if (card2) {
card2.setFaceUp(true);
}
// Rotate bot2 card 90 degrees when played to the ground
if (card2) {
card2.rotation = Math.PI / 2;
tween(card2, {
x: 2048 / 2 + 300,
y: 2732 / 2 + 250
}, {
duration: 400,
easing: tween.cubicOut
});
}
bot2Hand.splice(idx2, 1);
// Reveal location after short delay
LK.setTimeout(function () {
revealLocationAndScore();
}, 700);
}
function revealLocationAndScore() {
// Location is already selected and shown at round start
// Calculate points
var pts = {
player: 0,
bot1: 0,
bot2: 0
};
// New scoring: points by substring match per location rules
function calcCardPoints(card) {
if (!card) return 0; // Return 0 points if card is null
var p = 0;
// Build card name for substring matching
var cardName = (card.cardType + '-' + card.subType).toLowerCase();
if (roundLocation && roundLocation.name) {
var loc = roundLocation.name.toLowerCase();
if (loc === 'cave') {
// +1 for 'wizard' in name, +1 for 'orc' in name
if (cardName.indexOf('wizard') !== -1) p += 1;
if (cardName.indexOf('orc') !== -1) p += 1;
} else if (loc === 'castle') {
// +1 for 'warrior' in name, +1 for 'human' in name
if (cardName.indexOf('warrior') !== -1) p += 1;
if (cardName.indexOf('human') !== -1) p += 1;
} else if (loc === 'forest') {
// +1 for 'archer' in name, +1 for 'elf' in name
if (cardName.indexOf('archer') !== -1) p += 1;
if (cardName.indexOf('elf') !== -1) p += 1;
}
}
// Extra +1 for human-warrior, elf-archer, orc-wizard in every location
if (card.cardType === 'human' && card.subType === 'warrior' || card.cardType === 'elf' && card.subType === 'archer' || card.cardType === 'orc' && card.subType === 'wizard') {
p += 1;
}
return p;
}
pts.player = calcCardPoints(roundCards.player);
pts.bot1 = calcCardPoints(roundCards.bot1);
pts.bot2 = calcCardPoints(roundCards.bot2);
// Animate cards (flash winner)
var maxPts = Math.max(pts.player, pts.bot1, pts.bot2);
if (pts.player === maxPts) {
LK.effects.flashObject(roundCards.player, 0xffff00, 700);
}
if (pts.bot1 === maxPts) {
LK.effects.flashObject(roundCards.bot1, 0xffff00, 700);
}
if (pts.bot2 === maxPts) {
LK.effects.flashObject(roundCards.bot2, 0xffff00, 700);
}
// Update scores
playerScore += pts.player;
bot1Score += pts.bot1;
bot2Score += pts.bot2;
updateScoreText();
// Show round result
var msg = "You: +" + pts.player + " Legolas: +" + pts.bot1 + " Urukai: +" + pts.bot2;
updateRoundText(msg);
// Next round or end after delay
LK.setTimeout(function () {
round++;
if (round > maxRounds) {
endGame();
} else {
startRound();
}
}, 1500);
}
function startRound() {
clearBoard();
roundCards = {
player: null,
bot1: null,
bot2: null
};
// Pick random location from availableLocations, ensuring no repeats
if (availableLocations.length === 0) {
availableLocations = locations.slice();
}
var idx = Math.floor(Math.random() * availableLocations.length);
roundLocation = availableLocations[idx];
availableLocations.splice(idx, 1); // Remove used location
showLocation(roundLocation);
canPlayCard = true;
updateScoreText();
updateRoundText();
layoutHands();
}
function endGame() {
clearBoard();
canPlayCard = false;
// Add current game scores to session totals
sessionPlayerTotalScore += playerScore;
sessionBot1TotalScore += bot1Score;
sessionBot2TotalScore += bot2Score;
var winner = '';
// Track session wins for individual game results
if (playerScore > bot1Score && playerScore > bot2Score) {
sessionPlayerWins++;
winner = "You win game " + currentGame + "!";
} else if (bot1Score > playerScore && bot1Score > bot2Score) {
sessionBot1Wins++;
winner = "Bot1 wins game " + currentGame + "!";
} else if (bot2Score > playerScore && bot2Score > bot1Score) {
sessionBot2Wins++;
winner = "Bot2 wins game " + currentGame + "!";
} else {
winner = "Game " + currentGame + " tie!";
}
// Check if session is complete
if (currentGame >= totalGames) {
// Session complete - show total score, then after 3 seconds, show win/lose
var sessionWinner = '';
var winType = '';
// Prepare array of scores and names
var scoreArr = [{
name: "YOU",
score: sessionPlayerTotalScore
}, {
name: "LEGOLAS",
score: sessionBot1TotalScore
}, {
name: "URUKAI",
score: sessionBot2TotalScore
}];
// Sort descending by score
scoreArr.sort(function (a, b) {
return b.score - a.score;
});
// Build multiline string, top to bottom, highest first
var scoreLines = "";
for (var i = 0; i < scoreArr.length; i++) {
scoreLines += scoreArr[i].name + ": " + scoreArr[i].score + " P";
if (i < scoreArr.length - 1) scoreLines += "\n";
}
// Determine winner for win/lose
if (scoreArr[0].score > scoreArr[1].score) {
if (scoreArr[0].name === "YOU") {
sessionWinner = "You win the session!";
winType = "win";
} else if (scoreArr[0].name === "LEGOLAS") {
sessionWinner = "Legolas wins the session!";
winType = "lose";
} else if (scoreArr[0].name === "URUKAI") {
sessionWinner = "Urukai wins the session!";
winType = "lose";
} else {
sessionWinner = scoreArr[0].name + " wins the session!";
winType = "lose";
}
} else {
sessionWinner = "Session ends in a tie!";
winType = "lose";
}
// Show total score message in the center, sorted, with names
updateRoundText(scoreLines);
// After 3 seconds, show win/lose
LK.setTimeout(function () {
updateRoundText(sessionWinner);
LK.setTimeout(function () {
if (winType === "win") {
LK.showYouWin();
} else {
LK.showGameOver();
}
}, 1500);
}, 3000);
} else {
// More games to play in session
currentGame++;
// Show next game after delay
LK.setTimeout(function () {
newGame();
}, 2000);
}
updateRoundText('');
}
// --- Game Start ---
// Track which locations have been used this game
var availableLocations = [];
// Game start button
var startButton = null;
function showStartButton() {
if (startButton) {
startButton.destroy();
startButton = null;
}
if (game._startMenu) {
game._startMenu.destroy();
game._startMenu = null;
}
// Create menu container
var menuContainer = new Container();
menuContainer.x = 2048 / 2;
menuContainer.y = 2732 / 2;
game._startMenu = menuContainer;
// Logo image at the top middle above the HUMAN GAME text
var logoImg = LK.getAsset('logo', {
anchorX: 0.5,
anchorY: 0.5,
x: 0,
y: -500,
width: 1050,
height: 1050
});
menuContainer.addChild(logoImg);
// Title - bigger and more prominent
var titleText = new Text2('', {
size: 180,
fill: "#000",
stroke: "#fff",
strokeThickness: 8,
shadowColor: "#fff",
shadowBlur: 30,
shadowDistance: 0,
shadowAngle: 0,
shadowAlpha: 0.7
});
titleText.anchor.set(0.5, 0.5);
titleText.x = 0;
titleText.y = -300;
menuContainer.addChild(titleText);
// Subtitle for magic theme
var subtitleText = new Text2('', {
size: 100,
fill: "#000",
stroke: "#fff",
strokeThickness: 6,
shadowColor: "#fff",
shadowBlur: 20,
shadowDistance: 0,
shadowAngle: 0,
shadowAlpha: 0.7
});
subtitleText.anchor.set(0.5, 0.5);
subtitleText.x = 0;
subtitleText.y = -200;
menuContainer.addChild(subtitleText);
// Single game button (3 rounds) - bigger and more magical
var button1 = new Text2('HUMAN GAME', {
size: 100,
fill: "#000",
stroke: "#fff",
strokeThickness: 8,
shadowColor: "#fff",
shadowBlur: 40,
shadowDistance: 0,
shadowAngle: 0,
shadowAlpha: 0.9
});
button1.anchor.set(0.5, 0.5);
button1.x = 0;
button1.y = 100;
button1.interactive = true;
button1.buttonMode = true;
button1.down = function (x, y, obj) {
maxRounds = 3;
totalGames = 1;
currentGame = 1;
sessionPlayerWins = 0;
sessionBot1Wins = 0;
sessionBot2Wins = 0;
sessionPlayerTotalScore = 0;
sessionBot1TotalScore = 0;
sessionBot2TotalScore = 0;
menuContainer.visible = false;
newGame();
};
menuContainer.addChild(button1);
// 3 games button (3 hands each) - bigger and more magical
var button3 = new Text2('ELF GAME', {
size: 100,
fill: "#000",
stroke: "#fff",
strokeThickness: 8,
shadowColor: "#fff",
shadowBlur: 40,
shadowDistance: 0,
shadowAngle: 0,
shadowAlpha: 0.9
});
button3.anchor.set(0.5, 0.5);
button3.x = 0;
button3.y = 220;
button3.interactive = true;
button3.buttonMode = true;
button3.down = function (x, y, obj) {
maxRounds = 3;
totalGames = 3;
currentGame = 1;
sessionPlayerWins = 0;
sessionBot1Wins = 0;
sessionBot2Wins = 0;
sessionPlayerTotalScore = 0;
sessionBot1TotalScore = 0;
sessionBot2TotalScore = 0;
menuContainer.visible = false;
newGame();
};
menuContainer.addChild(button3);
// 5 games button (3 hands each) - bigger and more magical
var button5 = new Text2('KING GAME', {
size: 100,
fill: "#000",
stroke: "#fff",
strokeThickness: 8,
shadowColor: "#fff",
shadowBlur: 40,
shadowDistance: 0,
shadowAngle: 0,
shadowAlpha: 0.9
});
button5.anchor.set(0.5, 0.5);
button5.x = 0;
button5.y = 340;
button5.interactive = true;
button5.buttonMode = true;
button5.down = function (x, y, obj) {
maxRounds = 3;
totalGames = 5;
currentGame = 1;
sessionPlayerWins = 0;
sessionBot1Wins = 0;
sessionBot2Wins = 0;
sessionPlayerTotalScore = 0;
sessionBot1TotalScore = 0;
sessionBot2TotalScore = 0;
menuContainer.visible = false;
newGame();
};
menuContainer.addChild(button5);
game.addChild(menuContainer);
}
// Only call newGame from the start button now
function newGame() {
playerScore = 0;
bot1Score = 0;
bot2Score = 0;
round = 1;
canPlayCard = false;
roundCards = {
player: null,
bot1: null,
bot2: null
};
roundLocation = null;
clearBoard();
dealHands();
updateScoreText();
updateRoundText("Game " + currentGame + " / " + totalGames);
// Reset available locations for the new game
availableLocations = locations.slice();
// Start the first round which will handle location selection
startRound();
}
// Show the start button on load
showStartButton();
// Play background music as soon as the game loads
LK.playMusic('backgraund-song');
// --- Game move handler (for drag, not used here) ---
game.move = function (x, y, obj) {
// No drag in this game
};