/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ // Bot token class var BotToken = Container.expand(function () { var self = Container.call(this); var token = self.attachAsset('botToken', { width: 80, height: 80, anchorX: 0.5, anchorY: 0.5 }); return self; }); // Chance card class (for display) var ChanceCard = Container.expand(function () { var self = Container.call(this); var card = self.attachAsset('chanceCard', { width: 400, height: 200, color: 0xfff176, anchorX: 0.5, anchorY: 0.5 }); self.text = new Text2('', { size: 48, fill: 0xFFFFFF, fontWeight: "bold" }); self.text.anchor.set(0.5, 0.5); self.text.x = 0; self.text.y = 0; self.addChild(self.text); self.setText = function (t) { self.text.setText(t); }; return self; }); // Player token class var PlayerToken = Container.expand(function () { var self = Container.call(this); var token = self.attachAsset('playerToken', { width: 80, height: 80, color: 0xffa500, anchorX: 0.5, anchorY: 0.5 }); return self; }); // Property class: represents a property on the board var Property = Container.expand(function () { var self = Container.call(this); // Attach a box asset for the property var propBox = self.attachAsset('propertyBox', { width: 180, height: 180, color: self.color || 0xcccccc, anchorX: 0.5, anchorY: 0.5 }); // Property name text self.nameText = new Text2(self.name || '', { size: 36, fill: 0xFFFFFF, fontWeight: "bold" }); self.nameText.anchor.set(0.5, 0.5); self.nameText.x = 0; self.nameText.y = -40; self.addChild(self.nameText); // Price text self.priceText = new Text2('', { size: 32, fill: 0xFFFFFF, fontWeight: "bold" }); self.priceText.anchor.set(0.5, 0.5); self.priceText.x = 0; self.priceText.y = 60; // moved a bit lower self.addChild(self.priceText); // Owner indicator self.ownerIndicator = self.attachAsset('ownerCircle', { width: 40, height: 40, color: 0x00bfff, anchorX: 0.5, anchorY: 0.5, x: 0, y: 0 }); self.ownerIndicator.visible = false; self.addChild(self.ownerIndicator); // Set property info self.setInfo = function (info) { self.name = info.name; self.price = info.price; self.rent = info.rent; self.color = info.color; self.index = info.index; self.owner = null; self.upgradeLevel = 0; self.maxUpgrade = info.maxUpgrade || 3; self.nameText.setText(self.name); self.priceText.setText('$' + self.price); propBox.tint = self.color; self.ownerIndicator.visible = false; }; // Show owner self.setOwner = function (owner) { self.owner = owner; self.ownerIndicator.visible = !!owner; self.ownerIndicator.tint = owner ? 0x00bfff : 0xffffff; }; // Show upgrade level self.setUpgrade = function (level) { self.upgradeLevel = level; // Optionally, visually indicate upgrade (not implemented in MVP) }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0xf5f5dc }); /**** * Game Code ****/ // --- Board Setup --- var BOARD_SIZE = 12; // 12 spaces (simplified) var BOARD_RADIUS = 800; // px, for circular layout var BOARD_CENTER_X = 2048 / 2; var BOARD_CENTER_Y = 2732 / 2 + 100; var PROPERTY_COLORS = [0x4fc3f7, 0x81c784, 0xffb74d, 0xe57373, 0xba68c8, 0xa1887f]; // Board data: name, price, rent, color, maxUpgrade var boardData = [{ name: "GO", price: 0, rent: 0, color: 0xffffff, type: "go" }, { name: "Blue Ave", price: 100, rent: 20, color: PROPERTY_COLORS[0] }, { name: "Chance", price: 0, rent: 0, color: 0xfff176, type: "chance" }, { name: "Green St", price: 120, rent: 24, color: PROPERTY_COLORS[1] }, { name: "Tax", price: 0, rent: 0, color: 0xeeeeee, type: "tax" }, { name: "Orange Rd", price: 140, rent: 28, color: PROPERTY_COLORS[2] }, { name: "Jail", price: 0, rent: 0, color: 0x888888, type: "jail" }, { name: "Red Blvd", price: 160, rent: 32, color: PROPERTY_COLORS[3] }, { name: "Chance", price: 0, rent: 0, color: 0xfff176, type: "chance" }, { name: "Purple Ln", price: 180, rent: 36, color: PROPERTY_COLORS[4] }, { name: "Tax", price: 0, rent: 0, color: 0xeeeeee, type: "tax" }, { name: "Brown Pl", price: 200, rent: 40, color: PROPERTY_COLORS[5] }]; // --- Game State --- var properties = []; var player = { money: 1500, position: 0, properties: [], inJail: false, jailTurns: 0 }; var bot = { money: 1500, position: 0, properties: [], inJail: false, jailTurns: 0 }; var currentPlayer = "player"; // "player" or "bot" var turn = 1; var maxTurns = 20; var diceRolling = false; var awaitingAction = false; var chanceDeck = [{ text: "Advance to GO (Collect $200)", action: function action() { movePlayerTo(0); player.money += 200; } }, { text: "Bank error in your favor. Collect $150.", action: function action() { player.money += 150; } }, { text: "Pay school fees of $100.", action: function action() { player.money -= 100; } }, { text: "Go to Jail. Do not pass GO.", action: function action() { sendPlayerToJail(); } }, { text: "Collect $50 from every property you own.", action: function action() { player.money += player.properties.length * 50; } }, { text: "Pay property repairs: $40 per property.", action: function action() { player.money -= player.properties.length * 40; } }]; var chanceIndex = 0; // --- UI Elements --- var boardGroup = new Container(); game.addChild(boardGroup); var playerToken = new PlayerToken(); game.addChild(playerToken); var botToken = new BotToken(); game.addChild(botToken); var rollButton = null; var buyButton = null; var endTurnButton = null; var upgradeButton = null; var chanceCard = null; // GUI: Money, Turn, Message var moneyText = new Text2('$' + player.money, { size: 80, fill: 0x222222 }); moneyText.anchor.set(0.5, 0); LK.gui.top.addChild(moneyText); var turnText = new Text2('Turn 1/' + maxTurns, { size: 48, fill: 0x444444 }); turnText.anchor.set(1, 1); // Place in bottom right, with a margin from the edge turnText.x = -40; turnText.y = -20; LK.gui.bottomRight.addChild(turnText); var messageText = new Text2('', { size: 48, fill: 0xD84315 }); messageText.anchor.set(0.5, 0); LK.gui.bottom.addChild(messageText); // --- Board Rendering --- for (var i = 0; i < BOARD_SIZE; i++) { var angle = i / BOARD_SIZE * Math.PI * 2 - Math.PI / 2; var x = BOARD_CENTER_X + Math.cos(angle) * BOARD_RADIUS; var y = BOARD_CENTER_Y + Math.sin(angle) * BOARD_RADIUS; var prop = new Property(); var info = boardData[i]; prop.setInfo({ name: info.name, price: info.price, rent: info.rent, color: info.color, index: i, maxUpgrade: 3 }); prop.x = x; prop.y = y; prop.rotation = angle + Math.PI / 2; prop.index = i; prop.type = info.type || "property"; boardGroup.addChild(prop); properties.push(prop); } // --- Player Token Initial Position --- function updatePlayerToken() { var pos = player.position; var prop = properties[pos]; playerToken.x = prop.x; playerToken.y = prop.y; playerToken.zIndex = 100; var botPos = bot.position; var botProp = properties[botPos]; botToken.x = botProp.x; botToken.y = botProp.y; botToken.zIndex = 99; } updatePlayerToken(); // --- UI Buttons --- function createButton(label, onClick) { var btn = new Container(); var btnBg = btn.attachAsset('buttonBg', { width: 400, height: 120, color: 0x1976d2, anchorX: 0.5, anchorY: 0.5 }); var btnText = new Text2(label, { size: 56, fill: "#fff" }); btnText.anchor.set(0.5, 0.5); btnText.x = 0; btnText.y = 0; btn.addChild(btnText); btn.down = function (x, y, obj) { if (onClick) onClick(); }; return btn; } function showRollButton() { if (rollButton) return; rollButton = createButton("Roll Dice", function () { if (!diceRolling && !awaitingAction) { rollDice(); } }); rollButton.x = 2048 / 2; rollButton.y = 2732 - 250; game.addChild(rollButton); } function hideRollButton() { if (rollButton) { rollButton.destroy(); rollButton = null; } } function showBuyButton(price, onBuy) { if (buyButton) return; buyButton = createButton("Buy ($" + price + ")", function () { if (onBuy) onBuy(); }); buyButton.x = 2048 / 2 - 250; buyButton.y = 2732 - 250; game.addChild(buyButton); } function hideBuyButton() { if (buyButton) { buyButton.destroy(); buyButton = null; } } function showEndTurnButton(onEnd) { if (endTurnButton) return; endTurnButton = createButton("End Turn", function () { if (onEnd) onEnd(); }); endTurnButton.x = 2048 / 2 + 250; endTurnButton.y = 2732 - 250; game.addChild(endTurnButton); } function hideEndTurnButton() { if (endTurnButton) { endTurnButton.destroy(); endTurnButton = null; } } function showUpgradeButton(price, onUpgrade) { if (upgradeButton) return; upgradeButton = createButton("Upgrade ($" + price + ")", function () { if (onUpgrade) onUpgrade(); }); upgradeButton.x = 2048 / 2; upgradeButton.y = 2732 - 400; game.addChild(upgradeButton); } function hideUpgradeButton() { if (upgradeButton) { upgradeButton.destroy(); upgradeButton = null; } } // --- Chance Card Display --- function showChanceCard(text, onClose) { if (chanceCard) return; chanceCard = new ChanceCard(); chanceCard.setText(text); chanceCard.x = 2048 / 2; chanceCard.y = 2732 / 2; chanceCard.down = function (x, y, obj) { hideChanceCard(); if (onClose) onClose(); }; game.addChild(chanceCard); } function hideChanceCard() { if (chanceCard) { chanceCard.destroy(); chanceCard = null; } } // --- Game Logic --- function updateUI() { if (currentPlayer === "player") { moneyText.setText('You: $' + player.money + " | Bot: $" + bot.money); } else { moneyText.setText('Bot: $' + bot.money + " | You: $" + player.money); } turnText.setText('Turn ' + turn + '/' + maxTurns + (currentPlayer === "player" ? " (You)" : " (Bot)")); } function showMessage(msg, ms) { messageText.setText(msg); if (ms) { LK.setTimeout(function () { if (messageText.text === msg) messageText.setText(''); }, ms); } } function rollDice() { diceRolling = true; hideRollButton(); hideBuyButton(); hideEndTurnButton(); hideUpgradeButton(); showMessage("Rolling...", 800); // Simulate dice roll (1-6) var dice = 1 + Math.floor(Math.random() * 6); LK.setTimeout(function () { movePlayerBy(dice, currentPlayer); }, 800); } function movePlayerBy(steps, which) { var p = which === "player" ? player : bot; var oldPos = p.position; var newPos = (p.position + steps) % BOARD_SIZE; var passedGo = p.position + steps >= BOARD_SIZE; p.position = newPos; // Animate token movement var moveSteps = []; for (var i = 1; i <= steps; i++) { moveSteps.push((oldPos + i) % BOARD_SIZE); } var idx = 0; function moveStep() { if (idx < moveSteps.length) { var prop = properties[moveSteps[idx]]; var token = which === "player" ? playerToken : botToken; tween(token, { x: prop.x, y: prop.y }, { duration: 200, easing: tween.easeInOut, onFinish: function onFinish() { idx++; moveStep(); } }); } else { if (passedGo) { p.money += 200; showMessage((which === "player" ? "You" : "Bot") + " Passed GO! +$200", 1200); } LK.setTimeout(function () { landOnSpace(which); }, 250); } } moveStep(); } function movePlayerTo(pos, which) { var p = which === "player" ? player : bot; p.position = pos; updatePlayerToken(); landOnSpace(which); } function landOnSpace(which) { diceRolling = false; var p = which === "player" ? player : bot; var prop = properties[p.position]; var info = boardData[p.position]; // Special spaces if (info.type === "go") { showMessage((which === "player" ? "You" : "Bot") + " landed on GO! +$200", 1200); p.money += 200; endTurn(); return; } if (info.type === "tax") { showMessage((which === "player" ? "You" : "Bot") + " Pay Tax: -$100", 1200); p.money -= 100; endTurn(); return; } if (info.type === "jail") { showMessage((which === "player" ? "You" : "Bot") + " Go to Jail!", 1200); sendPlayerToJail(which); return; } if (info.type === "chance") { drawChanceCard(which); return; } // Property if (!prop.owner) { if (p.money >= prop.price) { if (which === "player") { showBuyButton(prop.price, function () { buyProperty(prop, which); }); } else { // Bot logic: buy if has money and random chance if (Math.random() < 0.7) { buyProperty(prop, which); } } } if (which === "player") { showEndTurnButton(endTurn); awaitingAction = true; } else { LK.setTimeout(function () { endTurn(); }, 600); } } else if (prop.owner === which) { // Option to upgrade if (prop.upgradeLevel < prop.maxUpgrade && p.money >= 100) { if (which === "player") { showUpgradeButton(100, function () { upgradeProperty(prop, which); }); } else { // Bot logic: upgrade if has money and random chance if (Math.random() < 0.5) { upgradeProperty(prop, which); } } } if (which === "player") { showEndTurnButton(endTurn); awaitingAction = true; } else { LK.setTimeout(function () { endTurn(); }, 600); } } else { // Pay rent var ownerObj = prop.owner === "player" ? player : bot; var rent = prop.rent + prop.upgradeLevel * 20; p.money -= rent; ownerObj.money += rent; showMessage((which === "player" ? "You" : "Bot") + " paid rent $" + rent + " to " + (prop.owner === "player" ? "You" : "Bot"), 1200); LK.setTimeout(function () { endTurn(); }, 800); } updateUI(); } function buyProperty(prop, which) { var p = which === "player" ? player : bot; if (p.money >= prop.price && !prop.owner) { p.money -= prop.price; prop.setOwner(which); p.properties.push(prop.index); showMessage((which === "player" ? "You" : "Bot") + " bought " + prop.name + "!", 1000); if (which === "player") { hideBuyButton(); } updateUI(); } } function upgradeProperty(prop, which) { var p = which === "player" ? player : bot; if (p.money >= 100 && prop.upgradeLevel < prop.maxUpgrade) { p.money -= 100; prop.setUpgrade(prop.upgradeLevel + 1); showMessage((which === "player" ? "You" : "Bot") + " upgraded " + prop.name + "!", 1000); if (which === "player") { hideUpgradeButton(); } updateUI(); } } function endTurn() { hideBuyButton(); hideEndTurnButton(); hideUpgradeButton(); awaitingAction = false; // Jail check for both var p = currentPlayer === "player" ? player : bot; if (p.money <= 0) { finishGame(); return; } if (turn > maxTurns) { finishGame(); return; } // Switch player if (currentPlayer === "player") { currentPlayer = "bot"; updateUI(); LK.setTimeout(function () { if (bot.inJail) { bot.jailTurns--; if (bot.jailTurns <= 0) { bot.inJail = false; showMessage("Bot released from Jail!", 1000); LK.setTimeout(function () { rollDice(); }, 800); } else { showMessage("Bot in Jail! " + bot.jailTurns + " turn(s) left.", 1000); LK.setTimeout(function () { endTurn(); }, 1000); } } else { rollDice(); } }, 800); } else { currentPlayer = "player"; turn++; updateUI(); if (player.inJail) { player.jailTurns--; if (player.jailTurns <= 0) { player.inJail = false; showMessage("Released from Jail!", 1000); showRollButton(); } else { showMessage("In Jail! " + player.jailTurns + " turn(s) left.", 1000); LK.setTimeout(function () { endTurn(); }, 1000); } } else { showRollButton(); } } } function sendPlayerToJail(which) { var p = which === "player" ? player : bot; p.inJail = true; p.jailTurns = 2; var jailPos = 6; // Jail index p.position = jailPos; updatePlayerToken(); showMessage((which === "player" ? "You" : "Bot") + " in Jail! Miss 2 turns.", 1500); LK.setTimeout(function () { endTurn(); }, 1200); } function drawChanceCard(which) { var p = which === "player" ? player : bot; var card = chanceDeck[chanceIndex % chanceDeck.length]; chanceIndex++; if (which === "player") { showChanceCard(card.text, function () { card.action(); updatePlayerToken(); updateUI(); LK.setTimeout(function () { endTurn(); }, 600); }); } else { showMessage("Bot draws a chance card!", 800); LK.setTimeout(function () { card.action(); updatePlayerToken(); updateUI(); LK.setTimeout(function () { endTurn(); }, 800); }, 800); } } function finishGame() { hideBuyButton(); hideEndTurnButton(); hideUpgradeButton(); hideRollButton(); var playerValue = player.money; for (var i = 0; i < player.properties.length; i++) { var idx = player.properties[i]; var prop = properties[idx]; playerValue += prop.price + prop.upgradeLevel * 100; } var botValue = bot.money; for (var i = 0; i < bot.properties.length; i++) { var idx = bot.properties[i]; var prop = properties[idx]; botValue += prop.price + prop.upgradeLevel * 100; } if (playerValue > botValue) { showMessage("Kazandın! Varlık: $" + playerValue, 4000); LK.setScore(playerValue); } else if (playerValue < botValue) { showMessage("Kaybettin! Bot daha zengin. Bot: $" + botValue, 4000); LK.setScore(playerValue); } else { showMessage("Berabere! Varlık: $" + playerValue, 4000); LK.setScore(playerValue); } LK.showGameOver(); } // --- Game Update Loop --- game.update = function () { // No-op: jail logic now handled in endTurn for both player and bot }; // --- Start Game --- updateUI(); showRollButton(); showMessage("Welcome to Monopoly Express!", 1800);
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
// Bot token class
var BotToken = Container.expand(function () {
var self = Container.call(this);
var token = self.attachAsset('botToken', {
width: 80,
height: 80,
anchorX: 0.5,
anchorY: 0.5
});
return self;
});
// Chance card class (for display)
var ChanceCard = Container.expand(function () {
var self = Container.call(this);
var card = self.attachAsset('chanceCard', {
width: 400,
height: 200,
color: 0xfff176,
anchorX: 0.5,
anchorY: 0.5
});
self.text = new Text2('', {
size: 48,
fill: 0xFFFFFF,
fontWeight: "bold"
});
self.text.anchor.set(0.5, 0.5);
self.text.x = 0;
self.text.y = 0;
self.addChild(self.text);
self.setText = function (t) {
self.text.setText(t);
};
return self;
});
// Player token class
var PlayerToken = Container.expand(function () {
var self = Container.call(this);
var token = self.attachAsset('playerToken', {
width: 80,
height: 80,
color: 0xffa500,
anchorX: 0.5,
anchorY: 0.5
});
return self;
});
// Property class: represents a property on the board
var Property = Container.expand(function () {
var self = Container.call(this);
// Attach a box asset for the property
var propBox = self.attachAsset('propertyBox', {
width: 180,
height: 180,
color: self.color || 0xcccccc,
anchorX: 0.5,
anchorY: 0.5
});
// Property name text
self.nameText = new Text2(self.name || '', {
size: 36,
fill: 0xFFFFFF,
fontWeight: "bold"
});
self.nameText.anchor.set(0.5, 0.5);
self.nameText.x = 0;
self.nameText.y = -40;
self.addChild(self.nameText);
// Price text
self.priceText = new Text2('', {
size: 32,
fill: 0xFFFFFF,
fontWeight: "bold"
});
self.priceText.anchor.set(0.5, 0.5);
self.priceText.x = 0;
self.priceText.y = 60; // moved a bit lower
self.addChild(self.priceText);
// Owner indicator
self.ownerIndicator = self.attachAsset('ownerCircle', {
width: 40,
height: 40,
color: 0x00bfff,
anchorX: 0.5,
anchorY: 0.5,
x: 0,
y: 0
});
self.ownerIndicator.visible = false;
self.addChild(self.ownerIndicator);
// Set property info
self.setInfo = function (info) {
self.name = info.name;
self.price = info.price;
self.rent = info.rent;
self.color = info.color;
self.index = info.index;
self.owner = null;
self.upgradeLevel = 0;
self.maxUpgrade = info.maxUpgrade || 3;
self.nameText.setText(self.name);
self.priceText.setText('$' + self.price);
propBox.tint = self.color;
self.ownerIndicator.visible = false;
};
// Show owner
self.setOwner = function (owner) {
self.owner = owner;
self.ownerIndicator.visible = !!owner;
self.ownerIndicator.tint = owner ? 0x00bfff : 0xffffff;
};
// Show upgrade level
self.setUpgrade = function (level) {
self.upgradeLevel = level;
// Optionally, visually indicate upgrade (not implemented in MVP)
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0xf5f5dc
});
/****
* Game Code
****/
// --- Board Setup ---
var BOARD_SIZE = 12; // 12 spaces (simplified)
var BOARD_RADIUS = 800; // px, for circular layout
var BOARD_CENTER_X = 2048 / 2;
var BOARD_CENTER_Y = 2732 / 2 + 100;
var PROPERTY_COLORS = [0x4fc3f7, 0x81c784, 0xffb74d, 0xe57373, 0xba68c8, 0xa1887f];
// Board data: name, price, rent, color, maxUpgrade
var boardData = [{
name: "GO",
price: 0,
rent: 0,
color: 0xffffff,
type: "go"
}, {
name: "Blue Ave",
price: 100,
rent: 20,
color: PROPERTY_COLORS[0]
}, {
name: "Chance",
price: 0,
rent: 0,
color: 0xfff176,
type: "chance"
}, {
name: "Green St",
price: 120,
rent: 24,
color: PROPERTY_COLORS[1]
}, {
name: "Tax",
price: 0,
rent: 0,
color: 0xeeeeee,
type: "tax"
}, {
name: "Orange Rd",
price: 140,
rent: 28,
color: PROPERTY_COLORS[2]
}, {
name: "Jail",
price: 0,
rent: 0,
color: 0x888888,
type: "jail"
}, {
name: "Red Blvd",
price: 160,
rent: 32,
color: PROPERTY_COLORS[3]
}, {
name: "Chance",
price: 0,
rent: 0,
color: 0xfff176,
type: "chance"
}, {
name: "Purple Ln",
price: 180,
rent: 36,
color: PROPERTY_COLORS[4]
}, {
name: "Tax",
price: 0,
rent: 0,
color: 0xeeeeee,
type: "tax"
}, {
name: "Brown Pl",
price: 200,
rent: 40,
color: PROPERTY_COLORS[5]
}];
// --- Game State ---
var properties = [];
var player = {
money: 1500,
position: 0,
properties: [],
inJail: false,
jailTurns: 0
};
var bot = {
money: 1500,
position: 0,
properties: [],
inJail: false,
jailTurns: 0
};
var currentPlayer = "player"; // "player" or "bot"
var turn = 1;
var maxTurns = 20;
var diceRolling = false;
var awaitingAction = false;
var chanceDeck = [{
text: "Advance to GO (Collect $200)",
action: function action() {
movePlayerTo(0);
player.money += 200;
}
}, {
text: "Bank error in your favor. Collect $150.",
action: function action() {
player.money += 150;
}
}, {
text: "Pay school fees of $100.",
action: function action() {
player.money -= 100;
}
}, {
text: "Go to Jail. Do not pass GO.",
action: function action() {
sendPlayerToJail();
}
}, {
text: "Collect $50 from every property you own.",
action: function action() {
player.money += player.properties.length * 50;
}
}, {
text: "Pay property repairs: $40 per property.",
action: function action() {
player.money -= player.properties.length * 40;
}
}];
var chanceIndex = 0;
// --- UI Elements ---
var boardGroup = new Container();
game.addChild(boardGroup);
var playerToken = new PlayerToken();
game.addChild(playerToken);
var botToken = new BotToken();
game.addChild(botToken);
var rollButton = null;
var buyButton = null;
var endTurnButton = null;
var upgradeButton = null;
var chanceCard = null;
// GUI: Money, Turn, Message
var moneyText = new Text2('$' + player.money, {
size: 80,
fill: 0x222222
});
moneyText.anchor.set(0.5, 0);
LK.gui.top.addChild(moneyText);
var turnText = new Text2('Turn 1/' + maxTurns, {
size: 48,
fill: 0x444444
});
turnText.anchor.set(1, 1);
// Place in bottom right, with a margin from the edge
turnText.x = -40;
turnText.y = -20;
LK.gui.bottomRight.addChild(turnText);
var messageText = new Text2('', {
size: 48,
fill: 0xD84315
});
messageText.anchor.set(0.5, 0);
LK.gui.bottom.addChild(messageText);
// --- Board Rendering ---
for (var i = 0; i < BOARD_SIZE; i++) {
var angle = i / BOARD_SIZE * Math.PI * 2 - Math.PI / 2;
var x = BOARD_CENTER_X + Math.cos(angle) * BOARD_RADIUS;
var y = BOARD_CENTER_Y + Math.sin(angle) * BOARD_RADIUS;
var prop = new Property();
var info = boardData[i];
prop.setInfo({
name: info.name,
price: info.price,
rent: info.rent,
color: info.color,
index: i,
maxUpgrade: 3
});
prop.x = x;
prop.y = y;
prop.rotation = angle + Math.PI / 2;
prop.index = i;
prop.type = info.type || "property";
boardGroup.addChild(prop);
properties.push(prop);
}
// --- Player Token Initial Position ---
function updatePlayerToken() {
var pos = player.position;
var prop = properties[pos];
playerToken.x = prop.x;
playerToken.y = prop.y;
playerToken.zIndex = 100;
var botPos = bot.position;
var botProp = properties[botPos];
botToken.x = botProp.x;
botToken.y = botProp.y;
botToken.zIndex = 99;
}
updatePlayerToken();
// --- UI Buttons ---
function createButton(label, onClick) {
var btn = new Container();
var btnBg = btn.attachAsset('buttonBg', {
width: 400,
height: 120,
color: 0x1976d2,
anchorX: 0.5,
anchorY: 0.5
});
var btnText = new Text2(label, {
size: 56,
fill: "#fff"
});
btnText.anchor.set(0.5, 0.5);
btnText.x = 0;
btnText.y = 0;
btn.addChild(btnText);
btn.down = function (x, y, obj) {
if (onClick) onClick();
};
return btn;
}
function showRollButton() {
if (rollButton) return;
rollButton = createButton("Roll Dice", function () {
if (!diceRolling && !awaitingAction) {
rollDice();
}
});
rollButton.x = 2048 / 2;
rollButton.y = 2732 - 250;
game.addChild(rollButton);
}
function hideRollButton() {
if (rollButton) {
rollButton.destroy();
rollButton = null;
}
}
function showBuyButton(price, onBuy) {
if (buyButton) return;
buyButton = createButton("Buy ($" + price + ")", function () {
if (onBuy) onBuy();
});
buyButton.x = 2048 / 2 - 250;
buyButton.y = 2732 - 250;
game.addChild(buyButton);
}
function hideBuyButton() {
if (buyButton) {
buyButton.destroy();
buyButton = null;
}
}
function showEndTurnButton(onEnd) {
if (endTurnButton) return;
endTurnButton = createButton("End Turn", function () {
if (onEnd) onEnd();
});
endTurnButton.x = 2048 / 2 + 250;
endTurnButton.y = 2732 - 250;
game.addChild(endTurnButton);
}
function hideEndTurnButton() {
if (endTurnButton) {
endTurnButton.destroy();
endTurnButton = null;
}
}
function showUpgradeButton(price, onUpgrade) {
if (upgradeButton) return;
upgradeButton = createButton("Upgrade ($" + price + ")", function () {
if (onUpgrade) onUpgrade();
});
upgradeButton.x = 2048 / 2;
upgradeButton.y = 2732 - 400;
game.addChild(upgradeButton);
}
function hideUpgradeButton() {
if (upgradeButton) {
upgradeButton.destroy();
upgradeButton = null;
}
}
// --- Chance Card Display ---
function showChanceCard(text, onClose) {
if (chanceCard) return;
chanceCard = new ChanceCard();
chanceCard.setText(text);
chanceCard.x = 2048 / 2;
chanceCard.y = 2732 / 2;
chanceCard.down = function (x, y, obj) {
hideChanceCard();
if (onClose) onClose();
};
game.addChild(chanceCard);
}
function hideChanceCard() {
if (chanceCard) {
chanceCard.destroy();
chanceCard = null;
}
}
// --- Game Logic ---
function updateUI() {
if (currentPlayer === "player") {
moneyText.setText('You: $' + player.money + " | Bot: $" + bot.money);
} else {
moneyText.setText('Bot: $' + bot.money + " | You: $" + player.money);
}
turnText.setText('Turn ' + turn + '/' + maxTurns + (currentPlayer === "player" ? " (You)" : " (Bot)"));
}
function showMessage(msg, ms) {
messageText.setText(msg);
if (ms) {
LK.setTimeout(function () {
if (messageText.text === msg) messageText.setText('');
}, ms);
}
}
function rollDice() {
diceRolling = true;
hideRollButton();
hideBuyButton();
hideEndTurnButton();
hideUpgradeButton();
showMessage("Rolling...", 800);
// Simulate dice roll (1-6)
var dice = 1 + Math.floor(Math.random() * 6);
LK.setTimeout(function () {
movePlayerBy(dice, currentPlayer);
}, 800);
}
function movePlayerBy(steps, which) {
var p = which === "player" ? player : bot;
var oldPos = p.position;
var newPos = (p.position + steps) % BOARD_SIZE;
var passedGo = p.position + steps >= BOARD_SIZE;
p.position = newPos;
// Animate token movement
var moveSteps = [];
for (var i = 1; i <= steps; i++) {
moveSteps.push((oldPos + i) % BOARD_SIZE);
}
var idx = 0;
function moveStep() {
if (idx < moveSteps.length) {
var prop = properties[moveSteps[idx]];
var token = which === "player" ? playerToken : botToken;
tween(token, {
x: prop.x,
y: prop.y
}, {
duration: 200,
easing: tween.easeInOut,
onFinish: function onFinish() {
idx++;
moveStep();
}
});
} else {
if (passedGo) {
p.money += 200;
showMessage((which === "player" ? "You" : "Bot") + " Passed GO! +$200", 1200);
}
LK.setTimeout(function () {
landOnSpace(which);
}, 250);
}
}
moveStep();
}
function movePlayerTo(pos, which) {
var p = which === "player" ? player : bot;
p.position = pos;
updatePlayerToken();
landOnSpace(which);
}
function landOnSpace(which) {
diceRolling = false;
var p = which === "player" ? player : bot;
var prop = properties[p.position];
var info = boardData[p.position];
// Special spaces
if (info.type === "go") {
showMessage((which === "player" ? "You" : "Bot") + " landed on GO! +$200", 1200);
p.money += 200;
endTurn();
return;
}
if (info.type === "tax") {
showMessage((which === "player" ? "You" : "Bot") + " Pay Tax: -$100", 1200);
p.money -= 100;
endTurn();
return;
}
if (info.type === "jail") {
showMessage((which === "player" ? "You" : "Bot") + " Go to Jail!", 1200);
sendPlayerToJail(which);
return;
}
if (info.type === "chance") {
drawChanceCard(which);
return;
}
// Property
if (!prop.owner) {
if (p.money >= prop.price) {
if (which === "player") {
showBuyButton(prop.price, function () {
buyProperty(prop, which);
});
} else {
// Bot logic: buy if has money and random chance
if (Math.random() < 0.7) {
buyProperty(prop, which);
}
}
}
if (which === "player") {
showEndTurnButton(endTurn);
awaitingAction = true;
} else {
LK.setTimeout(function () {
endTurn();
}, 600);
}
} else if (prop.owner === which) {
// Option to upgrade
if (prop.upgradeLevel < prop.maxUpgrade && p.money >= 100) {
if (which === "player") {
showUpgradeButton(100, function () {
upgradeProperty(prop, which);
});
} else {
// Bot logic: upgrade if has money and random chance
if (Math.random() < 0.5) {
upgradeProperty(prop, which);
}
}
}
if (which === "player") {
showEndTurnButton(endTurn);
awaitingAction = true;
} else {
LK.setTimeout(function () {
endTurn();
}, 600);
}
} else {
// Pay rent
var ownerObj = prop.owner === "player" ? player : bot;
var rent = prop.rent + prop.upgradeLevel * 20;
p.money -= rent;
ownerObj.money += rent;
showMessage((which === "player" ? "You" : "Bot") + " paid rent $" + rent + " to " + (prop.owner === "player" ? "You" : "Bot"), 1200);
LK.setTimeout(function () {
endTurn();
}, 800);
}
updateUI();
}
function buyProperty(prop, which) {
var p = which === "player" ? player : bot;
if (p.money >= prop.price && !prop.owner) {
p.money -= prop.price;
prop.setOwner(which);
p.properties.push(prop.index);
showMessage((which === "player" ? "You" : "Bot") + " bought " + prop.name + "!", 1000);
if (which === "player") {
hideBuyButton();
}
updateUI();
}
}
function upgradeProperty(prop, which) {
var p = which === "player" ? player : bot;
if (p.money >= 100 && prop.upgradeLevel < prop.maxUpgrade) {
p.money -= 100;
prop.setUpgrade(prop.upgradeLevel + 1);
showMessage((which === "player" ? "You" : "Bot") + " upgraded " + prop.name + "!", 1000);
if (which === "player") {
hideUpgradeButton();
}
updateUI();
}
}
function endTurn() {
hideBuyButton();
hideEndTurnButton();
hideUpgradeButton();
awaitingAction = false;
// Jail check for both
var p = currentPlayer === "player" ? player : bot;
if (p.money <= 0) {
finishGame();
return;
}
if (turn > maxTurns) {
finishGame();
return;
}
// Switch player
if (currentPlayer === "player") {
currentPlayer = "bot";
updateUI();
LK.setTimeout(function () {
if (bot.inJail) {
bot.jailTurns--;
if (bot.jailTurns <= 0) {
bot.inJail = false;
showMessage("Bot released from Jail!", 1000);
LK.setTimeout(function () {
rollDice();
}, 800);
} else {
showMessage("Bot in Jail! " + bot.jailTurns + " turn(s) left.", 1000);
LK.setTimeout(function () {
endTurn();
}, 1000);
}
} else {
rollDice();
}
}, 800);
} else {
currentPlayer = "player";
turn++;
updateUI();
if (player.inJail) {
player.jailTurns--;
if (player.jailTurns <= 0) {
player.inJail = false;
showMessage("Released from Jail!", 1000);
showRollButton();
} else {
showMessage("In Jail! " + player.jailTurns + " turn(s) left.", 1000);
LK.setTimeout(function () {
endTurn();
}, 1000);
}
} else {
showRollButton();
}
}
}
function sendPlayerToJail(which) {
var p = which === "player" ? player : bot;
p.inJail = true;
p.jailTurns = 2;
var jailPos = 6; // Jail index
p.position = jailPos;
updatePlayerToken();
showMessage((which === "player" ? "You" : "Bot") + " in Jail! Miss 2 turns.", 1500);
LK.setTimeout(function () {
endTurn();
}, 1200);
}
function drawChanceCard(which) {
var p = which === "player" ? player : bot;
var card = chanceDeck[chanceIndex % chanceDeck.length];
chanceIndex++;
if (which === "player") {
showChanceCard(card.text, function () {
card.action();
updatePlayerToken();
updateUI();
LK.setTimeout(function () {
endTurn();
}, 600);
});
} else {
showMessage("Bot draws a chance card!", 800);
LK.setTimeout(function () {
card.action();
updatePlayerToken();
updateUI();
LK.setTimeout(function () {
endTurn();
}, 800);
}, 800);
}
}
function finishGame() {
hideBuyButton();
hideEndTurnButton();
hideUpgradeButton();
hideRollButton();
var playerValue = player.money;
for (var i = 0; i < player.properties.length; i++) {
var idx = player.properties[i];
var prop = properties[idx];
playerValue += prop.price + prop.upgradeLevel * 100;
}
var botValue = bot.money;
for (var i = 0; i < bot.properties.length; i++) {
var idx = bot.properties[i];
var prop = properties[idx];
botValue += prop.price + prop.upgradeLevel * 100;
}
if (playerValue > botValue) {
showMessage("Kazandın! Varlık: $" + playerValue, 4000);
LK.setScore(playerValue);
} else if (playerValue < botValue) {
showMessage("Kaybettin! Bot daha zengin. Bot: $" + botValue, 4000);
LK.setScore(playerValue);
} else {
showMessage("Berabere! Varlık: $" + playerValue, 4000);
LK.setScore(playerValue);
}
LK.showGameOver();
}
// --- Game Update Loop ---
game.update = function () {
// No-op: jail logic now handled in endTurn for both player and bot
};
// --- Start Game ---
updateUI();
showRollButton();
showMessage("Welcome to Monopoly Express!", 1800);