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