/****
* 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
};