User prompt
Please arrange everything on the screen so that no elements touch or overlap each other under any circumstances. If necessary, resize some elements to make sure there is enough space between all of them."
User prompt
please update the game so that players bought from the transfer market stay on the team for at least 3 full seasons before they are removed or retire automatically. You can track this using a seasonsRemaining property for each player. Also, expand the transfer market to offer more than 3 players at a time, ideally increasing variety and options for the user.
User prompt
Ensure that the transfer market features the latest and highest-valued real-world football players based on current market values
User prompt
At the end of each season, the player should receive prize money based on their final league position. For example: 1st place gets $50 2nd place gets $30 3rd place gets $20 4th place gets $10 and all lower positions receive $5 This money can then be used in the transfer market.
User prompt
Please update the teams in the league to have their current, real-life players in their squads
User prompt
Ensure that the match events or summary menu that pops up after each match is positioned directly underneath the 'Play Match' button on the screen
User prompt
move the play button to the right
User prompt
move the play button to the right but not much
User prompt
move the play button to the right a bit
User prompt
move the play button to the right
User prompt
Make sure every menu has its own space and does not overlap or interfere with others on the screen.
User prompt
Arrange all on-screen menus neatly with enough padding and margins so that they do not overlap or collide visually. Each menu should have its own distinct area, ensuring a clean and user-friendly interface
User prompt
Stop being clever with formatting. Do not divide the number. Do not format it. Just show the full number like 100000000. Literally just print it as text. Nothing else.
User prompt
Do not divide or format the budget values. I want the full numeric amounts to be shown exactly as they are, without converting them to millions or shortening them. For example, if the budget is 100000000, it should display exactly as '100000000', not '100' or '100 million'.
User prompt
In the budget section of the game, please display all money values as full numbers without using words like 'million' or 'billion'. For example, show 50000000 instead of '50 million'.
User prompt
At the end of each season, the player should receive prize money based on their final league position. For example: 1st place gets $50 2nd place gets $30 3rd place gets $20 4th place gets $10 and all lower positions receive $5 This money can then be used in the transfer market.
User prompt
At the end of each season, the player should receive prize money based on their final league position. For example: 1st place gets $50,000,000, 2nd place gets $30,000,000, 3rd place gets $20,000,000, 4th place gets $10,000,000, and all lower positions receive $5,000,000. This money can then be used in the transfer market.
User prompt
Please simulate the league matches following a typical football league schedule. Each matchday, all teams should play one match simultaneously against their scheduled opponent. The season consists of every team playing each other twice—once at home and once away. After all these matches are completed, the league season ends, the points are tallied, and then a new season can begin.
User prompt
Please include a points system in the league table, updating team standings based on match outcomes (e.g., 3 points for a win, 1 for a draw, 0 for a loss). The season should end after each team has played every other team exactly twice. After the season ends, the league table should reset and a new season should begin from scratch. Make sure that no team plays against another more than twice per season.
User prompt
Please position the transfer market interface directly above the opponent team display section. Additionally, move the full league table — including all teams in the game — to the right side of the screen for better visibility and organization
User prompt
Please fix the bug: 'Uncaught TypeError: Cannot read properties of undefined (reading 'name')' in or related to this line: 'showInfo("Tap a bench player to swap with " + squad[selectedPlayerIdx].name);' Line Number: 164
User prompt
Please replace the generic opponent team names like 'Opponent FC' with more realistic names such as Denizlispor, Sivasspor, Galatasaray, and Fenerbahce
User prompt
move the play match button to the bottom middle
User prompt
move all of the buttons to bottom
User prompt
move the button to bottom
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var storage = LK.import("@upit/storage.v1"); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x1a3d2f }); /**** * Game Code ****/ // Player class: represents a footballer // --- CONSTANTS --- var Player = function Player(name, attack, defense, stamina, value) { var self = {}; self.name = name; self.attack = attack; self.defense = defense; self.stamina = stamina; self.value = value; self.maxStamina = stamina; self.inSquad = false; // true if in starting 5 return self; }; // Team class: holds a list of players var Team = function Team(name, players) { var self = {}; self.name = name; self.players = players; // array of Player return self; }; var SQUAD_SIZE = 5; var BENCH_SIZE = 3; var INITIAL_BUDGET = 100; var PLAYER_MIN_VALUE = 10; var PLAYER_MAX_VALUE = 40; // --- GLOBALS --- var allPlayers = []; // All players owned by user var squad = []; // Starting 5 var bench = []; // Bench 3 var transferList = []; // Players available to buy var budget = INITIAL_BUDGET; var opponentTeam = null; var matchInProgress = false; var matchLog = []; var matchResult = null; var selectedPlayerIdx = null; // For swapping var selectedBenchIdx = null; // For swapping var infoText = null; var budgetText = null; var matchText = null; var transferText = null; var transferBtns = []; var swapBtns = []; var playBtn = null; var nextBtn = null; var sellBtns = []; var buyBtns = []; var squadLabels = []; var benchLabels = []; var opponentLabels = []; var guiY = 0; // --- UTILS --- function randomInt(min, max) { return Math.floor(Math.random() * (max - min + 1)) + min; } function randomName() { var first = ["Alex", "Ben", "Chris", "Dan", "Eli", "Finn", "Gus", "Hugo", "Ivan", "Jack", "Kai", "Leo", "Max", "Nico", "Oli", "Paul", "Quinn", "Ray", "Sam", "Tom"]; var last = ["Smith", "Jones", "Brown", "Miller", "Davis", "Wilson", "Moore", "Taylor", "Clark", "Hall", "Young", "King", "Wright", "Scott", "Green", "Baker", "Adams", "Hill", "Ward", "Cruz"]; return first[randomInt(0, first.length - 1)] + " " + last[randomInt(0, last.length - 1)]; } function makeRandomPlayer() { var atk = randomInt(5, 15); var def = randomInt(5, 15); var sta = randomInt(10, 20); var val = Math.floor((atk + def + sta) / 3) + randomInt(PLAYER_MIN_VALUE, PLAYER_MAX_VALUE); return new Player(randomName(), atk, def, sta, val); } function makeOpponentTeam() { var oppPlayers = []; for (var i = 0; i < SQUAD_SIZE; i++) { var p = makeRandomPlayer(); oppPlayers.push(p); } return new Team("Opponent FC", oppPlayers); } function clonePlayer(p) { return new Player(p.name, p.attack, p.defense, p.stamina, p.value); } // --- INIT DATA --- function initPlayers() { allPlayers = []; for (var i = 0; i < SQUAD_SIZE + BENCH_SIZE; i++) { allPlayers.push(makeRandomPlayer()); } updateSquadAndBench(); } function updateSquadAndBench() { squad = []; bench = []; for (var i = 0; i < allPlayers.length; i++) { if (i < SQUAD_SIZE) { allPlayers[i].inSquad = true; squad.push(allPlayers[i]); } else { allPlayers[i].inSquad = false; bench.push(allPlayers[i]); } } } function initTransferList() { transferList = []; for (var i = 0; i < 3; i++) { transferList.push(makeRandomPlayer()); } } // --- UI HELPERS --- function clearArray(arr) { while (arr.length > 0) { var el = arr.pop(); if (el && el.destroy) el.destroy(); } } function makeLabel(txt, x, y, size, color) { var t = new Text2(txt, { size: size || 60, fill: color || "#fff" }); t.x = x; t.y = y; return t; } function updateBudgetText() { budgetText.setText("Budget: $" + budget + "M"); } function showInfo(msg) { infoText.setText(msg); } function updateSquadLabels() { clearArray(squadLabels); var startY = guiY + 180; for (var i = 0; i < SQUAD_SIZE; i++) { var p = squad[i]; var t = makeLabel(i + 1 + ". " + p.name + " [A:" + p.attack + " D:" + p.defense + " S:" + p.stamina + "]", 80, startY + i * 90, 54, "#ffe066"); game.addChild(t); squadLabels.push(t); // Add swap button var btn = makeLabel("↔", 900, t.y, 54, "#fff"); btn.idx = i; btn.interactive = true; btn.down = function (x, y, obj) { selectedPlayerIdx = obj.idx; showInfo("Tap a bench player to swap with " + squad[selectedPlayerIdx].name); }; game.addChild(btn); swapBtns.push(btn); // Add sell button var sellBtn = makeLabel("Sell", 1000, t.y, 44, "#ff7675"); sellBtn.idx = i; sellBtn.interactive = true; sellBtn.down = function (idxCopy) { return function (x, y, obj) { var idx = idxCopy; var p = squad[idx]; if (!p) { showInfo("Player not available."); return; } // Find the player in allPlayers by reference, not by index var allIdx = allPlayers.indexOf(p); if (allIdx !== -1) { budget += p.value; allPlayers.splice(allIdx, 1); updateSquadAndBench(); updateBudgetText(); showInfo("Sold " + p.name + " for $" + p.value + "M"); refreshUI(); } else { showInfo("Player not found in squad."); } }; }(i); game.addChild(sellBtn); sellBtns.push(sellBtn); } } function updateBenchLabels() { clearArray(benchLabels); var startY = guiY + 180; for (var i = 0; i < BENCH_SIZE; i++) { var p = bench[i]; if (!p) continue; var t = makeLabel("B" + (i + 1) + ". " + p.name + " [A:" + p.attack + " D:" + p.defense + " S:" + p.stamina + "]", 1200, startY + i * 90, 54, "#b2bec3"); game.addChild(t); benchLabels.push(t); // Add swap handler t.idx = i; t.interactive = true; t.down = function (x, y, obj) { if (selectedPlayerIdx !== null) { // Swap squad[selectedPlayerIdx] with bench[obj.idx] var sIdx = selectedPlayerIdx; var bIdx = obj.idx; var temp = squad[sIdx]; squad[sIdx] = bench[bIdx]; bench[bIdx] = temp; // Update allPlayers order for (var j = 0; j < SQUAD_SIZE; j++) allPlayers[j] = squad[j]; for (var j = 0; j < BENCH_SIZE; j++) allPlayers[SQUAD_SIZE + j] = bench[j]; selectedPlayerIdx = null; showInfo("Swapped players."); // Do not call refreshUI here; handled by menu system } }; } } function updateTransferLabels() { clearArray(transferBtns); clearArray(buyBtns); // Position transfer section at bottom-right var sectionWidth = 900; var sectionX = 2048 - sectionWidth - 80; // 80px margin from right var startY = 2048 - (transferList.length + 2) * 80 - 60; // 80px per line, 2 lines for header/spacing if (startY < guiY + 1400) startY = guiY + 1400; // avoid overlap with other UI if (transferText) transferText.destroy(); transferText = makeLabel("Transfer Market", sectionX, startY - 60, 60, "#00b894"); game.addChild(transferText); for (var i = 0; i < transferList.length; i++) { var p = transferList[i]; var t = makeLabel(p.name + " [A:" + p.attack + " D:" + p.defense + " S:" + p.stamina + "] $" + p.value + "M", sectionX, startY + i * 80, 50, "#fff"); game.addChild(t); transferBtns.push(t); // Buy button var buyBtn = makeLabel("Buy", sectionX + 700, t.y, 44, "#00b894"); buyBtn.idx = i; buyBtn.interactive = true; buyBtn.down = function (idxCopy) { return function (x, y, obj) { var idx = idxCopy; var p = transferList[idx]; if (!p) { showInfo("Player not available."); return; } if (budget < p.value) { showInfo("Not enough budget!"); return; } if (allPlayers.length >= SQUAD_SIZE + BENCH_SIZE) { showInfo("Squad full! Sell a player first."); return; } budget -= p.value; allPlayers.push(clonePlayer(p)); updateSquadAndBench(); updateBudgetText(); showInfo("Bought " + p.name + " for $" + p.value + "M"); // Remove from transfer list, add new transferList.splice(idx, 1, makeRandomPlayer()); refreshUI(); }; }(i); game.addChild(buyBtn); buyBtns.push(buyBtn); } } function updateOpponentLabels() { clearArray(opponentLabels); // Position league table at bottom-left var startY = 2048 - (SQUAD_SIZE + 2) * 60 - 60; // 60px per line, 2 lines for header/spacing if (startY < guiY + 1400) startY = guiY + 1400; // avoid overlap with other UI var t = makeLabel("Next Opponent: " + opponentTeam.name, 80, startY, 60, "#fab1a0"); game.addChild(t); opponentLabels.push(t); for (var i = 0; i < SQUAD_SIZE; i++) { var p = opponentTeam.players[i]; var pt = makeLabel(i + 1 + ". " + p.name + " [A:" + p.attack + " D:" + p.defense + " S:" + p.stamina + "]", 80, startY + 60 + i * 60, 44, "#fff"); game.addChild(pt); opponentLabels.push(pt); } } function clearMatchText() { if (matchText) { matchText.destroy(); matchText = null; } } function showMatchLog() { clearMatchText(); var log = matchLog.join("\n"); matchText = new Text2(log, { size: 48, fill: "#fff", wordWrap: true, wordWrapWidth: 1800 }); matchText.x = 80; matchText.y = guiY + 1800; game.addChild(matchText); } function clearAllUI() { clearArray(squadLabels); clearArray(benchLabels); clearArray(transferBtns); clearArray(buyBtns); clearArray(swapBtns); clearArray(sellBtns); clearArray(opponentLabels); if (transferText) transferText.destroy(); transferText = null; clearMatchText(); if (playBtn) playBtn.destroy(); playBtn = null; if (nextBtn) nextBtn.destroy(); nextBtn = null; } // --- GAME LOGIC --- function simulateMatch() { matchLog = []; matchResult = null; matchInProgress = true; // Calculate team stats var userAtk = 0, userDef = 0, userSta = 0; for (var i = 0; i < SQUAD_SIZE; i++) { userAtk += squad[i].attack; userDef += squad[i].defense; userSta += squad[i].stamina; } var oppAtk = 0, oppDef = 0, oppSta = 0; for (var i = 0; i < SQUAD_SIZE; i++) { oppAtk += opponentTeam.players[i].attack; oppDef += opponentTeam.players[i].defense; oppSta += opponentTeam.players[i].stamina; } // Simulate 5 "turns" (one per player) var userGoals = 0, oppGoals = 0; for (var turn = 0; turn < 5; turn++) { // User attack var atkP = squad[turn]; var defP = opponentTeam.players[turn]; var atkChance = atkP.attack + randomInt(0, atkP.stamina); var defChance = defP.defense + randomInt(0, defP.stamina); if (atkChance > defChance + 3) { userGoals++; matchLog.push("Minute " + (turn * 18 + 5) + ": " + atkP.name + " scores!"); } else if (defChance > atkChance + 5) { matchLog.push("Minute " + (turn * 18 + 8) + ": " + defP.name + " makes a key tackle."); } // Opponent attack var oAtkP = opponentTeam.players[turn]; var oDefP = squad[turn]; var oAtkChance = oAtkP.attack + randomInt(0, oAtkP.stamina); var oDefChance = oDefP.defense + randomInt(0, oDefP.stamina); if (oAtkChance > oDefChance + 3) { oppGoals++; matchLog.push("Minute " + (turn * 18 + 12) + ": " + oAtkP.name + " scores!"); } else if (oDefChance > oAtkChance + 5) { matchLog.push("Minute " + (turn * 18 + 15) + ": " + oDefP.name + " blocks a shot."); } } matchLog.push("Full Time: You " + userGoals + " - " + oppGoals + " " + opponentTeam.name); if (userGoals > oppGoals) { matchResult = "win"; matchLog.push("You win! +$20M"); budget += 20; } else if (userGoals < oppGoals) { matchResult = "lose"; matchLog.push("You lose."); } else { matchResult = "draw"; matchLog.push("Draw. +$5M"); budget += 5; } updateBudgetText(); showMatchLog(); matchInProgress = false; } function refreshUI() { clearAllUI(); updateSquadLabels(); updateBenchLabels(); updateBudgetText(); showInfo("Pick lineup, buy/sell, then Play Match!"); // Play match button at bottom center playBtn = makeLabel("Play Match", 1024 - 200, 2732 - 200, 70, "#00cec9"); playBtn.interactive = true; playBtn.down = function (x, y, obj) { if (matchInProgress) return; simulateMatch(); playBtn.destroy(); playBtn = null; // Next match button at bottom center, right of Play Match nextBtn = makeLabel("Next Match", 1024 + 100, 2732 - 200, 60, "#fdcb6e"); nextBtn.interactive = true; nextBtn.down = function (x, y, obj) { // New opponent, restore stamina a bit for (var i = 0; i < allPlayers.length; i++) { allPlayers[i].stamina = Math.min(allPlayers[i].maxStamina, allPlayers[i].stamina + randomInt(1, 3)); } opponentTeam = makeOpponentTeam(); clearMatchText(); nextBtn.destroy(); nextBtn = null; refreshUI(); }; game.addChild(nextBtn); }; game.addChild(playBtn); } // --- INIT UI --- function showSquadPanel() { clearAllUI(); updateSquadLabels(); updateBenchLabels(); updateBudgetText(); showInfo("Pick lineup, buy/sell, then Play Match!"); // Play match button at bottom center playBtn = makeLabel("Play Match", 1024 - 200, 2732 - 200, 70, "#00cec9"); playBtn.interactive = true; playBtn.down = function (x, y, obj) { if (matchInProgress) return; simulateMatch(); playBtn.destroy(); playBtn = null; // Next match button at bottom center, right of Play Match nextBtn = makeLabel("Next Match", 1024 + 100, 2732 - 200, 60, "#fdcb6e"); nextBtn.interactive = true; nextBtn.down = function (x, y, obj) { // New opponent, restore stamina a bit for (var i = 0; i < allPlayers.length; i++) { allPlayers[i].stamina = Math.min(allPlayers[i].maxStamina, allPlayers[i].stamina + randomInt(1, 3)); } opponentTeam = makeOpponentTeam(); clearMatchText(); nextBtn.destroy(); nextBtn = null; showSquadPanel(); }; game.addChild(nextBtn); }; game.addChild(playBtn); } function showTransfersPanel() { clearAllUI(); updateBudgetText(); showInfo("Buy new players for your squad!"); } function showOpponentPanel() { clearAllUI(); updateBudgetText(); showInfo("View your next opponent."); } function showMatchLogPanel() { clearAllUI(); showMatchLog(); updateBudgetText(); showInfo("Match log and results."); } function initUI() { guiY = 0; // Title var title = new Text2("Mini Football Manager", { size: 90, fill: 0x00CEC9 }); title.x = 80; title.y = guiY + 40; game.addChild(title); // Budget budgetText = new Text2("Budget: $" + budget + "M", { size: 60, fill: "#fff" }); budgetText.x = 80; budgetText.y = guiY + 120; game.addChild(budgetText); // Info infoText = new Text2("", { size: 54, fill: 0xFDCB6E }); infoText.x = 600; infoText.y = guiY + 120; game.addChild(infoText); // Top menu bar buttons var menuNames = ["Squad", "Transfers", "Opponent", "Match Log"]; var menuActions = [showSquadPanel, showTransfersPanel, showOpponentPanel, showMatchLogPanel]; var menuBtnWidth = 320; var menuBtnStartX = 80; var menuBtnY = guiY + 10; for (var i = 0; i < menuNames.length; i++) { var btn = new Text2(menuNames[i], { size: 54, fill: "#fff" }); btn.x = menuBtnStartX + i * (menuBtnWidth + 10); btn.y = menuBtnY; btn.interactive = true; btn.idx = i; btn.down = function (idxCopy) { return function (x, y, obj) { menuActions[idxCopy](); }; }(i); game.addChild(btn); } // Show squad panel by default showSquadPanel(); } // --- GAME START --- function newGame() { budget = INITIAL_BUDGET; initPlayers(); initTransferList(); opponentTeam = makeOpponentTeam(); matchInProgress = false; matchLog = []; matchResult = null; selectedPlayerIdx = null; selectedBenchIdx = null; initUI(); } newGame(); // --- END ---
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x1a3d2f
});
/****
* Game Code
****/
// Player class: represents a footballer
// --- CONSTANTS ---
var Player = function Player(name, attack, defense, stamina, value) {
var self = {};
self.name = name;
self.attack = attack;
self.defense = defense;
self.stamina = stamina;
self.value = value;
self.maxStamina = stamina;
self.inSquad = false; // true if in starting 5
return self;
};
// Team class: holds a list of players
var Team = function Team(name, players) {
var self = {};
self.name = name;
self.players = players; // array of Player
return self;
};
var SQUAD_SIZE = 5;
var BENCH_SIZE = 3;
var INITIAL_BUDGET = 100;
var PLAYER_MIN_VALUE = 10;
var PLAYER_MAX_VALUE = 40;
// --- GLOBALS ---
var allPlayers = []; // All players owned by user
var squad = []; // Starting 5
var bench = []; // Bench 3
var transferList = []; // Players available to buy
var budget = INITIAL_BUDGET;
var opponentTeam = null;
var matchInProgress = false;
var matchLog = [];
var matchResult = null;
var selectedPlayerIdx = null; // For swapping
var selectedBenchIdx = null; // For swapping
var infoText = null;
var budgetText = null;
var matchText = null;
var transferText = null;
var transferBtns = [];
var swapBtns = [];
var playBtn = null;
var nextBtn = null;
var sellBtns = [];
var buyBtns = [];
var squadLabels = [];
var benchLabels = [];
var opponentLabels = [];
var guiY = 0;
// --- UTILS ---
function randomInt(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}
function randomName() {
var first = ["Alex", "Ben", "Chris", "Dan", "Eli", "Finn", "Gus", "Hugo", "Ivan", "Jack", "Kai", "Leo", "Max", "Nico", "Oli", "Paul", "Quinn", "Ray", "Sam", "Tom"];
var last = ["Smith", "Jones", "Brown", "Miller", "Davis", "Wilson", "Moore", "Taylor", "Clark", "Hall", "Young", "King", "Wright", "Scott", "Green", "Baker", "Adams", "Hill", "Ward", "Cruz"];
return first[randomInt(0, first.length - 1)] + " " + last[randomInt(0, last.length - 1)];
}
function makeRandomPlayer() {
var atk = randomInt(5, 15);
var def = randomInt(5, 15);
var sta = randomInt(10, 20);
var val = Math.floor((atk + def + sta) / 3) + randomInt(PLAYER_MIN_VALUE, PLAYER_MAX_VALUE);
return new Player(randomName(), atk, def, sta, val);
}
function makeOpponentTeam() {
var oppPlayers = [];
for (var i = 0; i < SQUAD_SIZE; i++) {
var p = makeRandomPlayer();
oppPlayers.push(p);
}
return new Team("Opponent FC", oppPlayers);
}
function clonePlayer(p) {
return new Player(p.name, p.attack, p.defense, p.stamina, p.value);
}
// --- INIT DATA ---
function initPlayers() {
allPlayers = [];
for (var i = 0; i < SQUAD_SIZE + BENCH_SIZE; i++) {
allPlayers.push(makeRandomPlayer());
}
updateSquadAndBench();
}
function updateSquadAndBench() {
squad = [];
bench = [];
for (var i = 0; i < allPlayers.length; i++) {
if (i < SQUAD_SIZE) {
allPlayers[i].inSquad = true;
squad.push(allPlayers[i]);
} else {
allPlayers[i].inSquad = false;
bench.push(allPlayers[i]);
}
}
}
function initTransferList() {
transferList = [];
for (var i = 0; i < 3; i++) {
transferList.push(makeRandomPlayer());
}
}
// --- UI HELPERS ---
function clearArray(arr) {
while (arr.length > 0) {
var el = arr.pop();
if (el && el.destroy) el.destroy();
}
}
function makeLabel(txt, x, y, size, color) {
var t = new Text2(txt, {
size: size || 60,
fill: color || "#fff"
});
t.x = x;
t.y = y;
return t;
}
function updateBudgetText() {
budgetText.setText("Budget: $" + budget + "M");
}
function showInfo(msg) {
infoText.setText(msg);
}
function updateSquadLabels() {
clearArray(squadLabels);
var startY = guiY + 180;
for (var i = 0; i < SQUAD_SIZE; i++) {
var p = squad[i];
var t = makeLabel(i + 1 + ". " + p.name + " [A:" + p.attack + " D:" + p.defense + " S:" + p.stamina + "]", 80, startY + i * 90, 54, "#ffe066");
game.addChild(t);
squadLabels.push(t);
// Add swap button
var btn = makeLabel("↔", 900, t.y, 54, "#fff");
btn.idx = i;
btn.interactive = true;
btn.down = function (x, y, obj) {
selectedPlayerIdx = obj.idx;
showInfo("Tap a bench player to swap with " + squad[selectedPlayerIdx].name);
};
game.addChild(btn);
swapBtns.push(btn);
// Add sell button
var sellBtn = makeLabel("Sell", 1000, t.y, 44, "#ff7675");
sellBtn.idx = i;
sellBtn.interactive = true;
sellBtn.down = function (idxCopy) {
return function (x, y, obj) {
var idx = idxCopy;
var p = squad[idx];
if (!p) {
showInfo("Player not available.");
return;
}
// Find the player in allPlayers by reference, not by index
var allIdx = allPlayers.indexOf(p);
if (allIdx !== -1) {
budget += p.value;
allPlayers.splice(allIdx, 1);
updateSquadAndBench();
updateBudgetText();
showInfo("Sold " + p.name + " for $" + p.value + "M");
refreshUI();
} else {
showInfo("Player not found in squad.");
}
};
}(i);
game.addChild(sellBtn);
sellBtns.push(sellBtn);
}
}
function updateBenchLabels() {
clearArray(benchLabels);
var startY = guiY + 180;
for (var i = 0; i < BENCH_SIZE; i++) {
var p = bench[i];
if (!p) continue;
var t = makeLabel("B" + (i + 1) + ". " + p.name + " [A:" + p.attack + " D:" + p.defense + " S:" + p.stamina + "]", 1200, startY + i * 90, 54, "#b2bec3");
game.addChild(t);
benchLabels.push(t);
// Add swap handler
t.idx = i;
t.interactive = true;
t.down = function (x, y, obj) {
if (selectedPlayerIdx !== null) {
// Swap squad[selectedPlayerIdx] with bench[obj.idx]
var sIdx = selectedPlayerIdx;
var bIdx = obj.idx;
var temp = squad[sIdx];
squad[sIdx] = bench[bIdx];
bench[bIdx] = temp;
// Update allPlayers order
for (var j = 0; j < SQUAD_SIZE; j++) allPlayers[j] = squad[j];
for (var j = 0; j < BENCH_SIZE; j++) allPlayers[SQUAD_SIZE + j] = bench[j];
selectedPlayerIdx = null;
showInfo("Swapped players.");
// Do not call refreshUI here; handled by menu system
}
};
}
}
function updateTransferLabels() {
clearArray(transferBtns);
clearArray(buyBtns);
// Position transfer section at bottom-right
var sectionWidth = 900;
var sectionX = 2048 - sectionWidth - 80; // 80px margin from right
var startY = 2048 - (transferList.length + 2) * 80 - 60; // 80px per line, 2 lines for header/spacing
if (startY < guiY + 1400) startY = guiY + 1400; // avoid overlap with other UI
if (transferText) transferText.destroy();
transferText = makeLabel("Transfer Market", sectionX, startY - 60, 60, "#00b894");
game.addChild(transferText);
for (var i = 0; i < transferList.length; i++) {
var p = transferList[i];
var t = makeLabel(p.name + " [A:" + p.attack + " D:" + p.defense + " S:" + p.stamina + "] $" + p.value + "M", sectionX, startY + i * 80, 50, "#fff");
game.addChild(t);
transferBtns.push(t);
// Buy button
var buyBtn = makeLabel("Buy", sectionX + 700, t.y, 44, "#00b894");
buyBtn.idx = i;
buyBtn.interactive = true;
buyBtn.down = function (idxCopy) {
return function (x, y, obj) {
var idx = idxCopy;
var p = transferList[idx];
if (!p) {
showInfo("Player not available.");
return;
}
if (budget < p.value) {
showInfo("Not enough budget!");
return;
}
if (allPlayers.length >= SQUAD_SIZE + BENCH_SIZE) {
showInfo("Squad full! Sell a player first.");
return;
}
budget -= p.value;
allPlayers.push(clonePlayer(p));
updateSquadAndBench();
updateBudgetText();
showInfo("Bought " + p.name + " for $" + p.value + "M");
// Remove from transfer list, add new
transferList.splice(idx, 1, makeRandomPlayer());
refreshUI();
};
}(i);
game.addChild(buyBtn);
buyBtns.push(buyBtn);
}
}
function updateOpponentLabels() {
clearArray(opponentLabels);
// Position league table at bottom-left
var startY = 2048 - (SQUAD_SIZE + 2) * 60 - 60; // 60px per line, 2 lines for header/spacing
if (startY < guiY + 1400) startY = guiY + 1400; // avoid overlap with other UI
var t = makeLabel("Next Opponent: " + opponentTeam.name, 80, startY, 60, "#fab1a0");
game.addChild(t);
opponentLabels.push(t);
for (var i = 0; i < SQUAD_SIZE; i++) {
var p = opponentTeam.players[i];
var pt = makeLabel(i + 1 + ". " + p.name + " [A:" + p.attack + " D:" + p.defense + " S:" + p.stamina + "]", 80, startY + 60 + i * 60, 44, "#fff");
game.addChild(pt);
opponentLabels.push(pt);
}
}
function clearMatchText() {
if (matchText) {
matchText.destroy();
matchText = null;
}
}
function showMatchLog() {
clearMatchText();
var log = matchLog.join("\n");
matchText = new Text2(log, {
size: 48,
fill: "#fff",
wordWrap: true,
wordWrapWidth: 1800
});
matchText.x = 80;
matchText.y = guiY + 1800;
game.addChild(matchText);
}
function clearAllUI() {
clearArray(squadLabels);
clearArray(benchLabels);
clearArray(transferBtns);
clearArray(buyBtns);
clearArray(swapBtns);
clearArray(sellBtns);
clearArray(opponentLabels);
if (transferText) transferText.destroy();
transferText = null;
clearMatchText();
if (playBtn) playBtn.destroy();
playBtn = null;
if (nextBtn) nextBtn.destroy();
nextBtn = null;
}
// --- GAME LOGIC ---
function simulateMatch() {
matchLog = [];
matchResult = null;
matchInProgress = true;
// Calculate team stats
var userAtk = 0,
userDef = 0,
userSta = 0;
for (var i = 0; i < SQUAD_SIZE; i++) {
userAtk += squad[i].attack;
userDef += squad[i].defense;
userSta += squad[i].stamina;
}
var oppAtk = 0,
oppDef = 0,
oppSta = 0;
for (var i = 0; i < SQUAD_SIZE; i++) {
oppAtk += opponentTeam.players[i].attack;
oppDef += opponentTeam.players[i].defense;
oppSta += opponentTeam.players[i].stamina;
}
// Simulate 5 "turns" (one per player)
var userGoals = 0,
oppGoals = 0;
for (var turn = 0; turn < 5; turn++) {
// User attack
var atkP = squad[turn];
var defP = opponentTeam.players[turn];
var atkChance = atkP.attack + randomInt(0, atkP.stamina);
var defChance = defP.defense + randomInt(0, defP.stamina);
if (atkChance > defChance + 3) {
userGoals++;
matchLog.push("Minute " + (turn * 18 + 5) + ": " + atkP.name + " scores!");
} else if (defChance > atkChance + 5) {
matchLog.push("Minute " + (turn * 18 + 8) + ": " + defP.name + " makes a key tackle.");
}
// Opponent attack
var oAtkP = opponentTeam.players[turn];
var oDefP = squad[turn];
var oAtkChance = oAtkP.attack + randomInt(0, oAtkP.stamina);
var oDefChance = oDefP.defense + randomInt(0, oDefP.stamina);
if (oAtkChance > oDefChance + 3) {
oppGoals++;
matchLog.push("Minute " + (turn * 18 + 12) + ": " + oAtkP.name + " scores!");
} else if (oDefChance > oAtkChance + 5) {
matchLog.push("Minute " + (turn * 18 + 15) + ": " + oDefP.name + " blocks a shot.");
}
}
matchLog.push("Full Time: You " + userGoals + " - " + oppGoals + " " + opponentTeam.name);
if (userGoals > oppGoals) {
matchResult = "win";
matchLog.push("You win! +$20M");
budget += 20;
} else if (userGoals < oppGoals) {
matchResult = "lose";
matchLog.push("You lose.");
} else {
matchResult = "draw";
matchLog.push("Draw. +$5M");
budget += 5;
}
updateBudgetText();
showMatchLog();
matchInProgress = false;
}
function refreshUI() {
clearAllUI();
updateSquadLabels();
updateBenchLabels();
updateBudgetText();
showInfo("Pick lineup, buy/sell, then Play Match!");
// Play match button at bottom center
playBtn = makeLabel("Play Match", 1024 - 200, 2732 - 200, 70, "#00cec9");
playBtn.interactive = true;
playBtn.down = function (x, y, obj) {
if (matchInProgress) return;
simulateMatch();
playBtn.destroy();
playBtn = null;
// Next match button at bottom center, right of Play Match
nextBtn = makeLabel("Next Match", 1024 + 100, 2732 - 200, 60, "#fdcb6e");
nextBtn.interactive = true;
nextBtn.down = function (x, y, obj) {
// New opponent, restore stamina a bit
for (var i = 0; i < allPlayers.length; i++) {
allPlayers[i].stamina = Math.min(allPlayers[i].maxStamina, allPlayers[i].stamina + randomInt(1, 3));
}
opponentTeam = makeOpponentTeam();
clearMatchText();
nextBtn.destroy();
nextBtn = null;
refreshUI();
};
game.addChild(nextBtn);
};
game.addChild(playBtn);
}
// --- INIT UI ---
function showSquadPanel() {
clearAllUI();
updateSquadLabels();
updateBenchLabels();
updateBudgetText();
showInfo("Pick lineup, buy/sell, then Play Match!");
// Play match button at bottom center
playBtn = makeLabel("Play Match", 1024 - 200, 2732 - 200, 70, "#00cec9");
playBtn.interactive = true;
playBtn.down = function (x, y, obj) {
if (matchInProgress) return;
simulateMatch();
playBtn.destroy();
playBtn = null;
// Next match button at bottom center, right of Play Match
nextBtn = makeLabel("Next Match", 1024 + 100, 2732 - 200, 60, "#fdcb6e");
nextBtn.interactive = true;
nextBtn.down = function (x, y, obj) {
// New opponent, restore stamina a bit
for (var i = 0; i < allPlayers.length; i++) {
allPlayers[i].stamina = Math.min(allPlayers[i].maxStamina, allPlayers[i].stamina + randomInt(1, 3));
}
opponentTeam = makeOpponentTeam();
clearMatchText();
nextBtn.destroy();
nextBtn = null;
showSquadPanel();
};
game.addChild(nextBtn);
};
game.addChild(playBtn);
}
function showTransfersPanel() {
clearAllUI();
updateBudgetText();
showInfo("Buy new players for your squad!");
}
function showOpponentPanel() {
clearAllUI();
updateBudgetText();
showInfo("View your next opponent.");
}
function showMatchLogPanel() {
clearAllUI();
showMatchLog();
updateBudgetText();
showInfo("Match log and results.");
}
function initUI() {
guiY = 0;
// Title
var title = new Text2("Mini Football Manager", {
size: 90,
fill: 0x00CEC9
});
title.x = 80;
title.y = guiY + 40;
game.addChild(title);
// Budget
budgetText = new Text2("Budget: $" + budget + "M", {
size: 60,
fill: "#fff"
});
budgetText.x = 80;
budgetText.y = guiY + 120;
game.addChild(budgetText);
// Info
infoText = new Text2("", {
size: 54,
fill: 0xFDCB6E
});
infoText.x = 600;
infoText.y = guiY + 120;
game.addChild(infoText);
// Top menu bar buttons
var menuNames = ["Squad", "Transfers", "Opponent", "Match Log"];
var menuActions = [showSquadPanel, showTransfersPanel, showOpponentPanel, showMatchLogPanel];
var menuBtnWidth = 320;
var menuBtnStartX = 80;
var menuBtnY = guiY + 10;
for (var i = 0; i < menuNames.length; i++) {
var btn = new Text2(menuNames[i], {
size: 54,
fill: "#fff"
});
btn.x = menuBtnStartX + i * (menuBtnWidth + 10);
btn.y = menuBtnY;
btn.interactive = true;
btn.idx = i;
btn.down = function (idxCopy) {
return function (x, y, obj) {
menuActions[idxCopy]();
};
}(i);
game.addChild(btn);
}
// Show squad panel by default
showSquadPanel();
}
// --- GAME START ---
function newGame() {
budget = INITIAL_BUDGET;
initPlayers();
initTransferList();
opponentTeam = makeOpponentTeam();
matchInProgress = false;
matchLog = [];
matchResult = null;
selectedPlayerIdx = null;
selectedBenchIdx = null;
initUI();
}
newGame();
// --- END ---