/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1", {
selectedTeam: 0,
season: 1,
matchDay: 1,
teamData: undefined
});
/****
* Classes
****/
var Button = Container.expand(function (label, callback, width, height) {
var self = Container.call(this);
width = width || 300;
height = height || 120;
var button = self.attachAsset('button', {
anchorX: 0.5,
anchorY: 0.5,
width: width,
height: height
});
var labelText = new Text2(label, {
size: 40,
fill: 0xFFFFFF
});
labelText.anchor.set(0.5, 0.5);
self.addChild(labelText);
self.setLabel = function (newLabel) {
labelText.setText(newLabel);
};
self.down = function (x, y, obj) {
// Visual feedback
button.tint = 0x3742fa;
if (callback) {
callback();
}
};
self.up = function (x, y, obj) {
button.tint = 0xffffff;
};
return self;
});
var Match = Container.expand(function (homeTeam, awayTeam) {
var self = Container.call(this);
self.homeTeam = homeTeam;
self.awayTeam = awayTeam;
self.homeGoals = 0;
self.awayGoals = 0;
self.isPlayed = false;
self.matchTime = 0;
self.events = [];
var matchCard = self.attachAsset('matchCard', {
anchorX: 0.5,
anchorY: 0.5
});
var homeText = new Text2(homeTeam.name, {
size: 50,
fill: 0xFFFFFF
});
homeText.anchor.set(1, 0.5);
homeText.x = -100;
self.addChild(homeText);
var scoreText = new Text2("vs", {
size: 60,
fill: 0xFFFFFF
});
scoreText.anchor.set(0.5, 0.5);
self.addChild(scoreText);
var awayText = new Text2(awayTeam.name, {
size: 50,
fill: 0xFFFFFF
});
awayText.anchor.set(0, 0.5);
awayText.x = 100;
self.addChild(awayText);
self.simulateMatch = function () {
if (self.isPlayed) {
return;
}
LK.getSound('whistle').play();
var homeStrength = self.homeTeam.strength;
var awayStrength = self.awayTeam.strength;
// Calculate home advantage (about 10% boost)
homeStrength = Math.floor(homeStrength * 1.1);
// Calculate expected goals based on team strength
var homeExpectedGoals = homeStrength / 20 + Math.random() * 1.5;
var awayExpectedGoals = awayStrength / 25 + Math.random() * 1.2;
// Generate actual goals with Poisson-like distribution
self.homeGoals = Math.floor(getPoissonRandom(homeExpectedGoals));
self.awayGoals = Math.floor(getPoissonRandom(awayExpectedGoals));
// Update team statistics
self.homeTeam.goalsFor += self.homeGoals;
self.homeTeam.goalsAgainst += self.awayGoals;
self.awayTeam.goalsFor += self.awayGoals;
self.awayTeam.goalsAgainst += self.homeGoals;
if (self.homeGoals > self.awayGoals) {
self.homeTeam.points += 3;
self.homeTeam.wins += 1;
self.awayTeam.losses += 1;
} else if (self.homeGoals < self.awayGoals) {
self.awayTeam.points += 3;
self.awayTeam.wins += 1;
self.homeTeam.losses += 1;
} else {
self.homeTeam.points += 1;
self.awayTeam.points += 1;
self.homeTeam.draws += 1;
self.awayTeam.draws += 1;
}
// Generate match events
self.generateEvents();
// Update the score display
scoreText.setText(self.homeGoals + " - " + self.awayGoals);
self.isPlayed = true;
};
self.generateEvents = function () {
// Generate goal events
for (var i = 0; i < self.homeGoals; i++) {
var minute = Math.floor(Math.random() * 90) + 1;
var scorerIndex = Math.floor(Math.random() * self.homeTeam.players.length);
var scorer = self.homeTeam.players[scorerIndex];
self.events.push({
type: "goal",
team: self.homeTeam.name,
player: scorer.name,
minute: minute
});
}
for (var i = 0; i < self.awayGoals; i++) {
var minute = Math.floor(Math.random() * 90) + 1;
var scorerIndex = Math.floor(Math.random() * self.awayTeam.players.length);
var scorer = self.awayTeam.players[scorerIndex];
self.events.push({
type: "goal",
team: self.awayTeam.name,
player: scorer.name,
minute: minute
});
}
// Sort events by minute
self.events.sort(function (a, b) {
return a.minute - b.minute;
});
};
self.getEventText = function () {
var text = "";
for (var i = 0; i < self.events.length; i++) {
var event = self.events[i];
if (event.type === "goal") {
text += event.minute + "' GOAL! " + event.player + " (" + event.team + ")\n";
}
}
return text;
};
self.down = function (x, y, obj) {
if (!self.isPlayed && currentScreen === "fixtures") {
self.simulateMatch();
// Check if this was the selected team's match
var isUserTeam = self.homeTeam.name === teams[userTeamIndex].name || self.awayTeam.name === teams[userTeamIndex].name;
if (isUserTeam) {
showMatchDetails(self);
}
// Check if all matches for current matchday are played
var allPlayed = true;
for (var i = 0; i < currentFixtures.length; i++) {
if (!currentFixtures[i].isPlayed) {
allPlayed = false;
break;
}
}
if (allPlayed) {
showNextMatchdayButton();
}
}
};
return self;
});
var MatchDetailView = Container.expand(function (match) {
var self = Container.call(this);
var background = self.attachAsset('field', {
anchorX: 0.5,
anchorY: 0.5,
width: 1800,
height: 2400
});
background.alpha = 0.7;
var titleText = new Text2(match.homeTeam.name + " vs " + match.awayTeam.name, {
size: 60,
fill: 0xFFFFFF
});
titleText.anchor.set(0.5, 0);
titleText.y = -1000;
self.addChild(titleText);
var scoreText = new Text2(match.homeGoals + " - " + match.awayGoals, {
size: 100,
fill: 0xFFFFFF
});
scoreText.anchor.set(0.5, 0);
scoreText.y = -900;
self.addChild(scoreText);
var eventsText = new Text2(match.getEventText(), {
size: 40,
fill: 0xFFFFFF
});
eventsText.anchor.set(0.5, 0);
eventsText.y = -750;
self.addChild(eventsText);
var closeButton = new Button("CONTINUE", function () {
game.removeChild(self);
});
closeButton.y = 900;
self.addChild(closeButton);
return self;
});
var Player = Container.expand(function (playerData) {
var self = Container.call(this);
self.name = playerData.name;
self.position = playerData.position;
self.age = playerData.age;
self.ovr = playerData.ovr;
self.potential = playerData.potential;
self.value = playerData.value;
self.updateSkills = function () {
// Adjust player skills based on age and potential
if (self.age < 30 && self.ovr < self.potential) {
self.ovr += Math.floor(Math.random() * 3);
if (self.ovr > self.potential) {
self.ovr = self.potential;
}
} else if (self.age > 30) {
self.ovr -= Math.floor(Math.random() * 2);
}
// Update player value based on OVR and age
var ageModifier = 1;
if (self.age > 30) {
ageModifier = 0.8;
} else if (self.age < 23) {
ageModifier = 1.2;
}
self.value = Math.floor(self.ovr * 100000 * ageModifier);
};
return self;
});
var Team = Container.expand(function (teamData) {
var self = Container.call(this);
self.data = teamData;
self.name = teamData.name;
self.players = teamData.players;
self.points = 0;
self.wins = 0;
self.draws = 0;
self.losses = 0;
self.goalsFor = 0;
self.goalsAgainst = 0;
self.calculateTeamStrength = function () {
var totalStrength = 0;
for (var i = 0; i < self.players.length; i++) {
totalStrength += self.players[i].ovr;
}
return Math.floor(totalStrength / self.players.length);
};
self.strength = self.calculateTeamStrength();
return self;
});
var TeamCard = Container.expand(function (team, index) {
var self = Container.call(this);
var isSelected = index === userTeamIndex;
var card = self.attachAsset('teamCard', {
anchorX: 0.5,
anchorY: 0.5
});
if (isSelected) {
card.tint = 0x3742fa;
}
var nameText = new Text2(team.name, {
size: 40,
fill: 0xFFFFFF
});
nameText.anchor.set(0.5, 0);
nameText.y = -80;
self.addChild(nameText);
var strengthText = new Text2("Team Rating: " + team.strength, {
size: 30,
fill: 0xFFFFFF
});
strengthText.anchor.set(0.5, 0.5);
strengthText.y = 0;
self.addChild(strengthText);
var positionText = new Text2("", {
size: 30,
fill: 0xFFFFFF
});
positionText.anchor.set(0.5, 1);
positionText.y = 70;
self.addChild(positionText);
self.updatePosition = function (position) {
positionText.setText(position + ordinalSuffix(position));
};
self.down = function (x, y, obj) {
if (currentScreen === "teamSelection") {
userTeamIndex = index;
storage.selectedTeam = index;
showScreen("mainMenu");
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x005e30
});
/****
* Game Code
****/
// Global Variables
var teams = [];
var fixtures = [];
var userTeamIndex = storage.selectedTeam || 0;
var currentScreen = "loading";
var currentFixtures = [];
var currentMatchday = storage.matchDay || 1;
var season = storage.season || 1;
// UI Elements
var title = new Text2("Turkish Super League", {
size: 90,
fill: 0xFFFFFF
});
title.anchor.set(0.5, 0);
title.y = 150;
LK.gui.top.addChild(title);
var subtitle = new Text2("Manager Simulation", {
size: 60,
fill: 0xFFFFFF
});
subtitle.anchor.set(0.5, 0);
subtitle.y = 250;
LK.gui.top.addChild(subtitle);
var seasonText = new Text2("Season " + season, {
size: 50,
fill: 0xFFFFFF
});
seasonText.anchor.set(0.5, 0);
seasonText.y = 320;
LK.gui.top.addChild(seasonText);
var matchdayText = new Text2("Matchday " + currentMatchday, {
size: 40,
fill: 0xFFFFFF
});
matchdayText.anchor.set(0.5, 0);
matchdayText.y = 380;
LK.gui.top.addChild(matchdayText);
var statusText = new Text2("", {
size: 40,
fill: 0xFFFFFF
});
statusText.anchor.set(0.5, 0);
statusText.y = 440;
LK.gui.top.addChild(statusText);
// Helper Functions
function getPoissonRandom(mean) {
var L = Math.exp(-mean);
var p = 1.0;
var k = 0;
do {
k++;
p *= Math.random();
} while (p > L);
return k - 1;
}
function ordinalSuffix(i) {
var j = i % 10,
k = i % 100;
if (j == 1 && k != 11) {
return "st";
}
if (j == 2 && k != 12) {
return "nd";
}
if (j == 3 && k != 13) {
return "rd";
}
return "th";
}
function createTeams() {
// Initialize with sample Turkish Super League teams
// In a real game, this would be loaded from a data file
var teamData = [{
name: "Galatasaray",
players: generatePlayers(85, 75, 12)
}, {
name: "Fenerbahçe",
players: generatePlayers(84, 76, 12)
}, {
name: "Beşiktaş",
players: generatePlayers(83, 74, 12)
}, {
name: "Trabzonspor",
players: generatePlayers(80, 72, 11)
}, {
name: "Başakşehir",
players: generatePlayers(79, 73, 11)
}, {
name: "Adana Demirspor",
players: generatePlayers(78, 70, 10)
}, {
name: "Konyaspor",
players: generatePlayers(77, 69, 10)
}, {
name: "Alanyaspor",
players: generatePlayers(76, 70, 9)
}, {
name: "Antalyaspor",
players: generatePlayers(75, 69, 9)
}, {
name: "Kayserispor",
players: generatePlayers(74, 68, 8)
}, {
name: "Gaziantep FK",
players: generatePlayers(73, 67, 8)
}, {
name: "Kasımpaşa",
players: generatePlayers(72, 66, 7)
}, {
name: "Sivasspor",
players: generatePlayers(71, 65, 7)
}, {
name: "Hatayspor",
players: generatePlayers(70, 64, 6)
}, {
name: "Giresunspor",
players: generatePlayers(69, 62, 6)
}, {
name: "Ümraniyespor",
players: generatePlayers(68, 60, 5)
}, {
name: "Ankaragücü",
players: generatePlayers(67, 61, 5)
}, {
name: "İstanbulspor",
players: generatePlayers(66, 60, 4)
}];
for (var i = 0; i < teamData.length; i++) {
var team = new Team(teamData[i]);
teams.push(team);
}
// Save team data to storage
if (!storage.teamData) {
storage.teamData = teamData;
}
}
function generatePlayers(maxRating, avgRating, stars) {
var players = [];
var positions = ["GK", "DEF", "MID", "FWD"];
var numPlayers = 24;
// Create 3 star players
for (var i = 0; i < stars; i++) {
var rating = Math.floor(Math.random() * 5) + maxRating - 5;
var age = Math.floor(Math.random() * 8) + 25;
var position = positions[Math.floor(Math.random() * 3) + 1]; // Don't make star GKs
var potential = rating + Math.floor(Math.random() * 5);
players.push(new Player({
name: "Star Player " + (i + 1),
position: position,
age: age,
ovr: rating,
potential: potential,
value: rating * 100000
}));
}
// Fill the rest with regular players
for (var i = stars; i < numPlayers; i++) {
var rating = Math.floor(Math.random() * 10) + avgRating - 5;
var age = Math.floor(Math.random() * 15) + 18;
var position = positions[Math.floor(Math.random() * positions.length)];
var potential = rating;
if (age < 25) {
potential += Math.floor(Math.random() * 10);
}
players.push(new Player({
name: "Player " + (i + 1),
position: position,
age: age,
ovr: rating,
potential: potential,
value: rating * 50000
}));
}
return players;
}
function createFixtures() {
fixtures = [];
// Generate fixtures for a round-robin tournament
// Each team plays against every other team twice (home and away)
var matchdays = (teams.length - 1) * 2;
for (var matchday = 1; matchday <= matchdays; matchday++) {
fixtures[matchday] = [];
for (var i = 0; i < teams.length / 2; i++) {
var home, away;
if (matchday <= teams.length - 1) {
// First half of the season
home = (matchday + i) % (teams.length - 1);
away = (teams.length - 1 - i + matchday) % (teams.length - 1);
// Last team stays fixed
if (i === 0) {
away = teams.length - 1;
}
} else {
// Second half of the season - reverse home/away
var firstHalfMatchday = matchday - (teams.length - 1);
away = (firstHalfMatchday + i) % (teams.length - 1);
home = (teams.length - 1 - i + firstHalfMatchday) % (teams.length - 1);
// Last team stays fixed
if (i === 0) {
home = teams.length - 1;
}
}
var match = new Match(teams[home], teams[away]);
fixtures[matchday].push(match);
}
}
}
function showScreen(screenName) {
currentScreen = screenName;
// Clear the game container first
while (game.children.length > 0) {
game.removeChild(game.children[0]);
}
// Update UI elements
title.visible = true;
subtitle.visible = true;
if (screenName === "loading") {
statusText.setText("Loading game data...");
LK.setTimeout(function () {
if (!storage.teamData) {
showScreen("teamSelection");
} else {
showScreen("mainMenu");
}
}, 1000);
} else if (screenName === "teamSelection") {
subtitle.setText("Select Your Team");
statusText.setText("");
var xPos = -700;
var yPos = 600;
var counter = 0;
for (var i = 0; i < teams.length; i++) {
var teamCard = new TeamCard(teams[i], i);
teamCard.x = xPos + counter % 4 * 450;
teamCard.y = yPos + Math.floor(counter / 4) * 250;
game.addChild(teamCard);
counter++;
}
} else if (screenName === "mainMenu") {
subtitle.setText("Main Menu");
statusText.setText("Managing " + teams[userTeamIndex].name);
var viewTableButton = new Button("LEAGUE TABLE", function () {
showScreen("table");
});
viewTableButton.y = 700;
game.addChild(viewTableButton);
var viewFixturesButton = new Button("FIXTURES", function () {
showScreen("fixtures");
});
viewFixturesButton.y = 850;
game.addChild(viewFixturesButton);
var viewSquadButton = new Button("SQUAD", function () {
showScreen("squad");
});
viewSquadButton.y = 1000;
game.addChild(viewSquadButton);
// Add a field background
var field = LK.getAsset('field', {
anchorX: 0.5,
anchorY: 0.5
});
field.alpha = 0.3;
game.addChildAt(field, 0);
field.x = 2048 / 2;
field.y = 2732 / 2;
// Start ambient sound
LK.playMusic('stadiumAmbience');
} else if (screenName === "table") {
subtitle.setText("League Table");
// Sort teams by points, goal difference, goals scored
var sortedTeams = teams.slice();
sortedTeams.sort(function (a, b) {
if (a.points !== b.points) {
return b.points - a.points;
}
var aGD = a.goalsFor - a.goalsAgainst;
var bGD = b.goalsFor - b.goalsAgainst;
if (aGD !== bGD) {
return bGD - aGD;
}
return b.goalsFor - a.goalsFor;
});
var tableY = 500;
var headerText = new Text2("Pos Team P W D L GF GA GD Pts", {
size: 30,
fill: 0xFFFFFF
});
headerText.anchor.set(0, 0.5);
headerText.x = 200;
headerText.y = tableY;
game.addChild(headerText);
for (var i = 0; i < sortedTeams.length; i++) {
var team = sortedTeams[i];
var played = team.wins + team.draws + team.losses;
var gd = team.goalsFor - team.goalsAgainst;
var gdSign = gd > 0 ? "+" : "";
var highlight = team === teams[userTeamIndex];
var rowText = new Text2((i + 1).toString().padEnd(3) + team.name.padEnd(20) + played.toString().padEnd(5) + team.wins.toString().padEnd(5) + team.draws.toString().padEnd(5) + team.losses.toString().padEnd(5) + team.goalsFor.toString().padEnd(5) + team.goalsAgainst.toString().padEnd(5) + (gdSign + gd).toString().padEnd(5) + team.points.toString(), {
size: 28,
fill: highlight ? "#ffff00" : "#ffffff"
});
rowText.anchor.set(0, 0.5);
rowText.x = 200;
rowText.y = tableY + (i + 1) * 50;
game.addChild(rowText);
// Update TeamCard position information
for (var j = 0; j < game.children.length; j++) {
if (game.children[j] instanceof TeamCard && game.children[j].data === team) {
game.children[j].updatePosition(i + 1);
}
}
}
var backButton = new Button("BACK", function () {
showScreen("mainMenu");
});
backButton.y = 2400;
game.addChild(backButton);
} else if (screenName === "fixtures") {
subtitle.setText("Fixtures - Matchday " + currentMatchday);
// Display current matchday fixtures
currentFixtures = fixtures[currentMatchday];
var startY = 600;
for (var i = 0; i < currentFixtures.length; i++) {
var match = currentFixtures[i];
match.x = 2048 / 2;
match.y = startY + i * 250;
game.addChild(match);
}
var backButton = new Button("BACK", function () {
showScreen("mainMenu");
});
backButton.y = 2400;
game.addChild(backButton);
// Show "Next Matchday" button if all matches are played
var allPlayed = true;
for (var i = 0; i < currentFixtures.length; i++) {
if (!currentFixtures[i].isPlayed) {
allPlayed = false;
break;
}
}
if (allPlayed) {
showNextMatchdayButton();
}
} else if (screenName === "squad") {
subtitle.setText("Squad - " + teams[userTeamIndex].name);
var team = teams[userTeamIndex];
var startY = 600;
var headerText = new Text2("Name Pos Age OVR POT Value", {
size: 30,
fill: 0xFFFFFF
});
headerText.anchor.set(0, 0.5);
headerText.x = 200;
headerText.y = startY - 60;
game.addChild(headerText);
// Sort players by overall rating
var sortedPlayers = team.players.slice();
sortedPlayers.sort(function (a, b) {
return b.ovr - a.ovr;
});
for (var i = 0; i < sortedPlayers.length; i++) {
var player = sortedPlayers[i];
var valueFormatted = (player.value / 1000000).toFixed(1) + "M";
var rowText = new Text2(player.name.padEnd(18) + player.position.padEnd(6) + player.age.toString().padEnd(6) + player.ovr.toString().padEnd(6) + player.potential.toString().padEnd(6) + valueFormatted, {
size: 28,
fill: 0xFFFFFF
});
rowText.anchor.set(0, 0.5);
rowText.x = 200;
rowText.y = startY + i * 50;
game.addChild(rowText);
}
var backButton = new Button("BACK", function () {
showScreen("mainMenu");
});
backButton.y = 2400;
game.addChild(backButton);
}
}
function showNextMatchdayButton() {
var nextButton = new Button("NEXT MATCHDAY", function () {
currentMatchday++;
if (currentMatchday > (teams.length - 1) * 2) {
// End of season
endSeason();
} else {
storage.matchDay = currentMatchday;
matchdayText.setText("Matchday " + currentMatchday);
showScreen("fixtures");
}
});
nextButton.y = 2250;
game.addChild(nextButton);
}
function showMatchDetails(match) {
var detailView = new MatchDetailView(match);
detailView.x = 2048 / 2;
detailView.y = 2732 / 2;
game.addChild(detailView);
if (match.homeGoals > 0 || match.awayGoals > 0) {
LK.getSound('goal').play();
}
}
function endSeason() {
season++;
currentMatchday = 1;
storage.season = season;
storage.matchDay = currentMatchday;
// Reset team stats but keep player development
for (var i = 0; i < teams.length; i++) {
teams[i].points = 0;
teams[i].wins = 0;
teams[i].draws = 0;
teams[i].losses = 0;
teams[i].goalsFor = 0;
teams[i].goalsAgainst = 0;
// Age players and develop them
for (var j = 0; j < teams[i].players.length; j++) {
var player = teams[i].players[j];
player.age++;
player.updateSkills();
}
}
// Regenerate fixtures for the new season
createFixtures();
// Update UI
seasonText.setText("Season " + season);
matchdayText.setText("Matchday " + currentMatchday);
// Show season summary
var summaryView = new Container();
var background = LK.getAsset('field', {
anchorX: 0.5,
anchorY: 0.5
});
background.alpha = 0.7;
summaryView.addChild(background);
var titleText = new Text2("Season " + (season - 1) + " Complete!", {
size: 70,
fill: 0xFFFFFF
});
titleText.anchor.set(0.5, 0);
titleText.y = -1000;
summaryView.addChild(titleText);
// Sort teams by points to find champion
var sortedTeams = teams.slice();
sortedTeams.sort(function (a, b) {
if (a.points !== b.points) {
return b.points - a.points;
}
var aGD = a.goalsFor - a.goalsAgainst;
var bGD = b.goalsFor - b.goalsAgainst;
if (aGD !== bGD) {
return bGD - aGD;
}
return b.goalsFor - a.goalsFor;
});
var championText = new Text2("Champion: " + sortedTeams[0].name, {
size: 60,
fill: 0xFFFF00
});
championText.anchor.set(0.5, 0);
championText.y = -900;
summaryView.addChild(championText);
var userTeamPos = sortedTeams.indexOf(teams[userTeamIndex]) + 1;
var userTeamText = new Text2("Your Team: " + teams[userTeamIndex].name + " (" + userTeamPos + ordinalSuffix(userTeamPos) + " place)", {
size: 50,
fill: 0xFFFFFF
});
userTeamText.anchor.set(0.5, 0);
userTeamText.y = -800;
summaryView.addChild(userTeamText);
var continueButton = new Button("CONTINUE TO SEASON " + season, function () {
game.removeChild(summaryView);
showScreen("fixtures");
});
continueButton.y = 900;
summaryView.addChild(continueButton);
summaryView.x = 2048 / 2;
summaryView.y = 2732 / 2;
game.addChild(summaryView);
}
// Initialize Game
function initGame() {
// Create teams and fixtures
createTeams();
createFixtures();
// Start with team selection or main menu
showScreen("loading");
}
// Game update
game.update = function () {
// Nothing to do in the update loop for now
// This simulation game is mostly event-driven
};
// Start the game
initGame(); /****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1", {
selectedTeam: 0,
season: 1,
matchDay: 1,
teamData: undefined
});
/****
* Classes
****/
var Button = Container.expand(function (label, callback, width, height) {
var self = Container.call(this);
width = width || 300;
height = height || 120;
var button = self.attachAsset('button', {
anchorX: 0.5,
anchorY: 0.5,
width: width,
height: height
});
var labelText = new Text2(label, {
size: 40,
fill: 0xFFFFFF
});
labelText.anchor.set(0.5, 0.5);
self.addChild(labelText);
self.setLabel = function (newLabel) {
labelText.setText(newLabel);
};
self.down = function (x, y, obj) {
// Visual feedback
button.tint = 0x3742fa;
if (callback) {
callback();
}
};
self.up = function (x, y, obj) {
button.tint = 0xffffff;
};
return self;
});
var Match = Container.expand(function (homeTeam, awayTeam) {
var self = Container.call(this);
self.homeTeam = homeTeam;
self.awayTeam = awayTeam;
self.homeGoals = 0;
self.awayGoals = 0;
self.isPlayed = false;
self.matchTime = 0;
self.events = [];
var matchCard = self.attachAsset('matchCard', {
anchorX: 0.5,
anchorY: 0.5
});
var homeText = new Text2(homeTeam.name, {
size: 50,
fill: 0xFFFFFF
});
homeText.anchor.set(1, 0.5);
homeText.x = -100;
self.addChild(homeText);
var scoreText = new Text2("vs", {
size: 60,
fill: 0xFFFFFF
});
scoreText.anchor.set(0.5, 0.5);
self.addChild(scoreText);
var awayText = new Text2(awayTeam.name, {
size: 50,
fill: 0xFFFFFF
});
awayText.anchor.set(0, 0.5);
awayText.x = 100;
self.addChild(awayText);
self.simulateMatch = function () {
if (self.isPlayed) {
return;
}
LK.getSound('whistle').play();
var homeStrength = self.homeTeam.strength;
var awayStrength = self.awayTeam.strength;
// Calculate home advantage (about 10% boost)
homeStrength = Math.floor(homeStrength * 1.1);
// Calculate expected goals based on team strength
var homeExpectedGoals = homeStrength / 20 + Math.random() * 1.5;
var awayExpectedGoals = awayStrength / 25 + Math.random() * 1.2;
// Generate actual goals with Poisson-like distribution
self.homeGoals = Math.floor(getPoissonRandom(homeExpectedGoals));
self.awayGoals = Math.floor(getPoissonRandom(awayExpectedGoals));
// Update team statistics
self.homeTeam.goalsFor += self.homeGoals;
self.homeTeam.goalsAgainst += self.awayGoals;
self.awayTeam.goalsFor += self.awayGoals;
self.awayTeam.goalsAgainst += self.homeGoals;
if (self.homeGoals > self.awayGoals) {
self.homeTeam.points += 3;
self.homeTeam.wins += 1;
self.awayTeam.losses += 1;
} else if (self.homeGoals < self.awayGoals) {
self.awayTeam.points += 3;
self.awayTeam.wins += 1;
self.homeTeam.losses += 1;
} else {
self.homeTeam.points += 1;
self.awayTeam.points += 1;
self.homeTeam.draws += 1;
self.awayTeam.draws += 1;
}
// Generate match events
self.generateEvents();
// Update the score display
scoreText.setText(self.homeGoals + " - " + self.awayGoals);
self.isPlayed = true;
};
self.generateEvents = function () {
// Generate goal events
for (var i = 0; i < self.homeGoals; i++) {
var minute = Math.floor(Math.random() * 90) + 1;
var scorerIndex = Math.floor(Math.random() * self.homeTeam.players.length);
var scorer = self.homeTeam.players[scorerIndex];
self.events.push({
type: "goal",
team: self.homeTeam.name,
player: scorer.name,
minute: minute
});
}
for (var i = 0; i < self.awayGoals; i++) {
var minute = Math.floor(Math.random() * 90) + 1;
var scorerIndex = Math.floor(Math.random() * self.awayTeam.players.length);
var scorer = self.awayTeam.players[scorerIndex];
self.events.push({
type: "goal",
team: self.awayTeam.name,
player: scorer.name,
minute: minute
});
}
// Sort events by minute
self.events.sort(function (a, b) {
return a.minute - b.minute;
});
};
self.getEventText = function () {
var text = "";
for (var i = 0; i < self.events.length; i++) {
var event = self.events[i];
if (event.type === "goal") {
text += event.minute + "' GOAL! " + event.player + " (" + event.team + ")\n";
}
}
return text;
};
self.down = function (x, y, obj) {
if (!self.isPlayed && currentScreen === "fixtures") {
self.simulateMatch();
// Check if this was the selected team's match
var isUserTeam = self.homeTeam.name === teams[userTeamIndex].name || self.awayTeam.name === teams[userTeamIndex].name;
if (isUserTeam) {
showMatchDetails(self);
}
// Check if all matches for current matchday are played
var allPlayed = true;
for (var i = 0; i < currentFixtures.length; i++) {
if (!currentFixtures[i].isPlayed) {
allPlayed = false;
break;
}
}
if (allPlayed) {
showNextMatchdayButton();
}
}
};
return self;
});
var MatchDetailView = Container.expand(function (match) {
var self = Container.call(this);
var background = self.attachAsset('field', {
anchorX: 0.5,
anchorY: 0.5,
width: 1800,
height: 2400
});
background.alpha = 0.7;
var titleText = new Text2(match.homeTeam.name + " vs " + match.awayTeam.name, {
size: 60,
fill: 0xFFFFFF
});
titleText.anchor.set(0.5, 0);
titleText.y = -1000;
self.addChild(titleText);
var scoreText = new Text2(match.homeGoals + " - " + match.awayGoals, {
size: 100,
fill: 0xFFFFFF
});
scoreText.anchor.set(0.5, 0);
scoreText.y = -900;
self.addChild(scoreText);
var eventsText = new Text2(match.getEventText(), {
size: 40,
fill: 0xFFFFFF
});
eventsText.anchor.set(0.5, 0);
eventsText.y = -750;
self.addChild(eventsText);
var closeButton = new Button("CONTINUE", function () {
game.removeChild(self);
});
closeButton.y = 900;
self.addChild(closeButton);
return self;
});
var Player = Container.expand(function (playerData) {
var self = Container.call(this);
self.name = playerData.name;
self.position = playerData.position;
self.age = playerData.age;
self.ovr = playerData.ovr;
self.potential = playerData.potential;
self.value = playerData.value;
self.updateSkills = function () {
// Adjust player skills based on age and potential
if (self.age < 30 && self.ovr < self.potential) {
self.ovr += Math.floor(Math.random() * 3);
if (self.ovr > self.potential) {
self.ovr = self.potential;
}
} else if (self.age > 30) {
self.ovr -= Math.floor(Math.random() * 2);
}
// Update player value based on OVR and age
var ageModifier = 1;
if (self.age > 30) {
ageModifier = 0.8;
} else if (self.age < 23) {
ageModifier = 1.2;
}
self.value = Math.floor(self.ovr * 100000 * ageModifier);
};
return self;
});
var Team = Container.expand(function (teamData) {
var self = Container.call(this);
self.data = teamData;
self.name = teamData.name;
self.players = teamData.players;
self.points = 0;
self.wins = 0;
self.draws = 0;
self.losses = 0;
self.goalsFor = 0;
self.goalsAgainst = 0;
self.calculateTeamStrength = function () {
var totalStrength = 0;
for (var i = 0; i < self.players.length; i++) {
totalStrength += self.players[i].ovr;
}
return Math.floor(totalStrength / self.players.length);
};
self.strength = self.calculateTeamStrength();
return self;
});
var TeamCard = Container.expand(function (team, index) {
var self = Container.call(this);
var isSelected = index === userTeamIndex;
var card = self.attachAsset('teamCard', {
anchorX: 0.5,
anchorY: 0.5
});
if (isSelected) {
card.tint = 0x3742fa;
}
var nameText = new Text2(team.name, {
size: 40,
fill: 0xFFFFFF
});
nameText.anchor.set(0.5, 0);
nameText.y = -80;
self.addChild(nameText);
var strengthText = new Text2("Team Rating: " + team.strength, {
size: 30,
fill: 0xFFFFFF
});
strengthText.anchor.set(0.5, 0.5);
strengthText.y = 0;
self.addChild(strengthText);
var positionText = new Text2("", {
size: 30,
fill: 0xFFFFFF
});
positionText.anchor.set(0.5, 1);
positionText.y = 70;
self.addChild(positionText);
self.updatePosition = function (position) {
positionText.setText(position + ordinalSuffix(position));
};
self.down = function (x, y, obj) {
if (currentScreen === "teamSelection") {
userTeamIndex = index;
storage.selectedTeam = index;
showScreen("mainMenu");
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x005e30
});
/****
* Game Code
****/
// Global Variables
var teams = [];
var fixtures = [];
var userTeamIndex = storage.selectedTeam || 0;
var currentScreen = "loading";
var currentFixtures = [];
var currentMatchday = storage.matchDay || 1;
var season = storage.season || 1;
// UI Elements
var title = new Text2("Turkish Super League", {
size: 90,
fill: 0xFFFFFF
});
title.anchor.set(0.5, 0);
title.y = 150;
LK.gui.top.addChild(title);
var subtitle = new Text2("Manager Simulation", {
size: 60,
fill: 0xFFFFFF
});
subtitle.anchor.set(0.5, 0);
subtitle.y = 250;
LK.gui.top.addChild(subtitle);
var seasonText = new Text2("Season " + season, {
size: 50,
fill: 0xFFFFFF
});
seasonText.anchor.set(0.5, 0);
seasonText.y = 320;
LK.gui.top.addChild(seasonText);
var matchdayText = new Text2("Matchday " + currentMatchday, {
size: 40,
fill: 0xFFFFFF
});
matchdayText.anchor.set(0.5, 0);
matchdayText.y = 380;
LK.gui.top.addChild(matchdayText);
var statusText = new Text2("", {
size: 40,
fill: 0xFFFFFF
});
statusText.anchor.set(0.5, 0);
statusText.y = 440;
LK.gui.top.addChild(statusText);
// Helper Functions
function getPoissonRandom(mean) {
var L = Math.exp(-mean);
var p = 1.0;
var k = 0;
do {
k++;
p *= Math.random();
} while (p > L);
return k - 1;
}
function ordinalSuffix(i) {
var j = i % 10,
k = i % 100;
if (j == 1 && k != 11) {
return "st";
}
if (j == 2 && k != 12) {
return "nd";
}
if (j == 3 && k != 13) {
return "rd";
}
return "th";
}
function createTeams() {
// Initialize with sample Turkish Super League teams
// In a real game, this would be loaded from a data file
var teamData = [{
name: "Galatasaray",
players: generatePlayers(85, 75, 12)
}, {
name: "Fenerbahçe",
players: generatePlayers(84, 76, 12)
}, {
name: "Beşiktaş",
players: generatePlayers(83, 74, 12)
}, {
name: "Trabzonspor",
players: generatePlayers(80, 72, 11)
}, {
name: "Başakşehir",
players: generatePlayers(79, 73, 11)
}, {
name: "Adana Demirspor",
players: generatePlayers(78, 70, 10)
}, {
name: "Konyaspor",
players: generatePlayers(77, 69, 10)
}, {
name: "Alanyaspor",
players: generatePlayers(76, 70, 9)
}, {
name: "Antalyaspor",
players: generatePlayers(75, 69, 9)
}, {
name: "Kayserispor",
players: generatePlayers(74, 68, 8)
}, {
name: "Gaziantep FK",
players: generatePlayers(73, 67, 8)
}, {
name: "Kasımpaşa",
players: generatePlayers(72, 66, 7)
}, {
name: "Sivasspor",
players: generatePlayers(71, 65, 7)
}, {
name: "Hatayspor",
players: generatePlayers(70, 64, 6)
}, {
name: "Giresunspor",
players: generatePlayers(69, 62, 6)
}, {
name: "Ümraniyespor",
players: generatePlayers(68, 60, 5)
}, {
name: "Ankaragücü",
players: generatePlayers(67, 61, 5)
}, {
name: "İstanbulspor",
players: generatePlayers(66, 60, 4)
}];
for (var i = 0; i < teamData.length; i++) {
var team = new Team(teamData[i]);
teams.push(team);
}
// Save team data to storage
if (!storage.teamData) {
storage.teamData = teamData;
}
}
function generatePlayers(maxRating, avgRating, stars) {
var players = [];
var positions = ["GK", "DEF", "MID", "FWD"];
var numPlayers = 24;
// Create 3 star players
for (var i = 0; i < stars; i++) {
var rating = Math.floor(Math.random() * 5) + maxRating - 5;
var age = Math.floor(Math.random() * 8) + 25;
var position = positions[Math.floor(Math.random() * 3) + 1]; // Don't make star GKs
var potential = rating + Math.floor(Math.random() * 5);
players.push(new Player({
name: "Star Player " + (i + 1),
position: position,
age: age,
ovr: rating,
potential: potential,
value: rating * 100000
}));
}
// Fill the rest with regular players
for (var i = stars; i < numPlayers; i++) {
var rating = Math.floor(Math.random() * 10) + avgRating - 5;
var age = Math.floor(Math.random() * 15) + 18;
var position = positions[Math.floor(Math.random() * positions.length)];
var potential = rating;
if (age < 25) {
potential += Math.floor(Math.random() * 10);
}
players.push(new Player({
name: "Player " + (i + 1),
position: position,
age: age,
ovr: rating,
potential: potential,
value: rating * 50000
}));
}
return players;
}
function createFixtures() {
fixtures = [];
// Generate fixtures for a round-robin tournament
// Each team plays against every other team twice (home and away)
var matchdays = (teams.length - 1) * 2;
for (var matchday = 1; matchday <= matchdays; matchday++) {
fixtures[matchday] = [];
for (var i = 0; i < teams.length / 2; i++) {
var home, away;
if (matchday <= teams.length - 1) {
// First half of the season
home = (matchday + i) % (teams.length - 1);
away = (teams.length - 1 - i + matchday) % (teams.length - 1);
// Last team stays fixed
if (i === 0) {
away = teams.length - 1;
}
} else {
// Second half of the season - reverse home/away
var firstHalfMatchday = matchday - (teams.length - 1);
away = (firstHalfMatchday + i) % (teams.length - 1);
home = (teams.length - 1 - i + firstHalfMatchday) % (teams.length - 1);
// Last team stays fixed
if (i === 0) {
home = teams.length - 1;
}
}
var match = new Match(teams[home], teams[away]);
fixtures[matchday].push(match);
}
}
}
function showScreen(screenName) {
currentScreen = screenName;
// Clear the game container first
while (game.children.length > 0) {
game.removeChild(game.children[0]);
}
// Update UI elements
title.visible = true;
subtitle.visible = true;
if (screenName === "loading") {
statusText.setText("Loading game data...");
LK.setTimeout(function () {
if (!storage.teamData) {
showScreen("teamSelection");
} else {
showScreen("mainMenu");
}
}, 1000);
} else if (screenName === "teamSelection") {
subtitle.setText("Select Your Team");
statusText.setText("");
var xPos = -700;
var yPos = 600;
var counter = 0;
for (var i = 0; i < teams.length; i++) {
var teamCard = new TeamCard(teams[i], i);
teamCard.x = xPos + counter % 4 * 450;
teamCard.y = yPos + Math.floor(counter / 4) * 250;
game.addChild(teamCard);
counter++;
}
} else if (screenName === "mainMenu") {
subtitle.setText("Main Menu");
statusText.setText("Managing " + teams[userTeamIndex].name);
var viewTableButton = new Button("LEAGUE TABLE", function () {
showScreen("table");
});
viewTableButton.y = 700;
game.addChild(viewTableButton);
var viewFixturesButton = new Button("FIXTURES", function () {
showScreen("fixtures");
});
viewFixturesButton.y = 850;
game.addChild(viewFixturesButton);
var viewSquadButton = new Button("SQUAD", function () {
showScreen("squad");
});
viewSquadButton.y = 1000;
game.addChild(viewSquadButton);
// Add a field background
var field = LK.getAsset('field', {
anchorX: 0.5,
anchorY: 0.5
});
field.alpha = 0.3;
game.addChildAt(field, 0);
field.x = 2048 / 2;
field.y = 2732 / 2;
// Start ambient sound
LK.playMusic('stadiumAmbience');
} else if (screenName === "table") {
subtitle.setText("League Table");
// Sort teams by points, goal difference, goals scored
var sortedTeams = teams.slice();
sortedTeams.sort(function (a, b) {
if (a.points !== b.points) {
return b.points - a.points;
}
var aGD = a.goalsFor - a.goalsAgainst;
var bGD = b.goalsFor - b.goalsAgainst;
if (aGD !== bGD) {
return bGD - aGD;
}
return b.goalsFor - a.goalsFor;
});
var tableY = 500;
var headerText = new Text2("Pos Team P W D L GF GA GD Pts", {
size: 30,
fill: 0xFFFFFF
});
headerText.anchor.set(0, 0.5);
headerText.x = 200;
headerText.y = tableY;
game.addChild(headerText);
for (var i = 0; i < sortedTeams.length; i++) {
var team = sortedTeams[i];
var played = team.wins + team.draws + team.losses;
var gd = team.goalsFor - team.goalsAgainst;
var gdSign = gd > 0 ? "+" : "";
var highlight = team === teams[userTeamIndex];
var rowText = new Text2((i + 1).toString().padEnd(3) + team.name.padEnd(20) + played.toString().padEnd(5) + team.wins.toString().padEnd(5) + team.draws.toString().padEnd(5) + team.losses.toString().padEnd(5) + team.goalsFor.toString().padEnd(5) + team.goalsAgainst.toString().padEnd(5) + (gdSign + gd).toString().padEnd(5) + team.points.toString(), {
size: 28,
fill: highlight ? "#ffff00" : "#ffffff"
});
rowText.anchor.set(0, 0.5);
rowText.x = 200;
rowText.y = tableY + (i + 1) * 50;
game.addChild(rowText);
// Update TeamCard position information
for (var j = 0; j < game.children.length; j++) {
if (game.children[j] instanceof TeamCard && game.children[j].data === team) {
game.children[j].updatePosition(i + 1);
}
}
}
var backButton = new Button("BACK", function () {
showScreen("mainMenu");
});
backButton.y = 2400;
game.addChild(backButton);
} else if (screenName === "fixtures") {
subtitle.setText("Fixtures - Matchday " + currentMatchday);
// Display current matchday fixtures
currentFixtures = fixtures[currentMatchday];
var startY = 600;
for (var i = 0; i < currentFixtures.length; i++) {
var match = currentFixtures[i];
match.x = 2048 / 2;
match.y = startY + i * 250;
game.addChild(match);
}
var backButton = new Button("BACK", function () {
showScreen("mainMenu");
});
backButton.y = 2400;
game.addChild(backButton);
// Show "Next Matchday" button if all matches are played
var allPlayed = true;
for (var i = 0; i < currentFixtures.length; i++) {
if (!currentFixtures[i].isPlayed) {
allPlayed = false;
break;
}
}
if (allPlayed) {
showNextMatchdayButton();
}
} else if (screenName === "squad") {
subtitle.setText("Squad - " + teams[userTeamIndex].name);
var team = teams[userTeamIndex];
var startY = 600;
var headerText = new Text2("Name Pos Age OVR POT Value", {
size: 30,
fill: 0xFFFFFF
});
headerText.anchor.set(0, 0.5);
headerText.x = 200;
headerText.y = startY - 60;
game.addChild(headerText);
// Sort players by overall rating
var sortedPlayers = team.players.slice();
sortedPlayers.sort(function (a, b) {
return b.ovr - a.ovr;
});
for (var i = 0; i < sortedPlayers.length; i++) {
var player = sortedPlayers[i];
var valueFormatted = (player.value / 1000000).toFixed(1) + "M";
var rowText = new Text2(player.name.padEnd(18) + player.position.padEnd(6) + player.age.toString().padEnd(6) + player.ovr.toString().padEnd(6) + player.potential.toString().padEnd(6) + valueFormatted, {
size: 28,
fill: 0xFFFFFF
});
rowText.anchor.set(0, 0.5);
rowText.x = 200;
rowText.y = startY + i * 50;
game.addChild(rowText);
}
var backButton = new Button("BACK", function () {
showScreen("mainMenu");
});
backButton.y = 2400;
game.addChild(backButton);
}
}
function showNextMatchdayButton() {
var nextButton = new Button("NEXT MATCHDAY", function () {
currentMatchday++;
if (currentMatchday > (teams.length - 1) * 2) {
// End of season
endSeason();
} else {
storage.matchDay = currentMatchday;
matchdayText.setText("Matchday " + currentMatchday);
showScreen("fixtures");
}
});
nextButton.y = 2250;
game.addChild(nextButton);
}
function showMatchDetails(match) {
var detailView = new MatchDetailView(match);
detailView.x = 2048 / 2;
detailView.y = 2732 / 2;
game.addChild(detailView);
if (match.homeGoals > 0 || match.awayGoals > 0) {
LK.getSound('goal').play();
}
}
function endSeason() {
season++;
currentMatchday = 1;
storage.season = season;
storage.matchDay = currentMatchday;
// Reset team stats but keep player development
for (var i = 0; i < teams.length; i++) {
teams[i].points = 0;
teams[i].wins = 0;
teams[i].draws = 0;
teams[i].losses = 0;
teams[i].goalsFor = 0;
teams[i].goalsAgainst = 0;
// Age players and develop them
for (var j = 0; j < teams[i].players.length; j++) {
var player = teams[i].players[j];
player.age++;
player.updateSkills();
}
}
// Regenerate fixtures for the new season
createFixtures();
// Update UI
seasonText.setText("Season " + season);
matchdayText.setText("Matchday " + currentMatchday);
// Show season summary
var summaryView = new Container();
var background = LK.getAsset('field', {
anchorX: 0.5,
anchorY: 0.5
});
background.alpha = 0.7;
summaryView.addChild(background);
var titleText = new Text2("Season " + (season - 1) + " Complete!", {
size: 70,
fill: 0xFFFFFF
});
titleText.anchor.set(0.5, 0);
titleText.y = -1000;
summaryView.addChild(titleText);
// Sort teams by points to find champion
var sortedTeams = teams.slice();
sortedTeams.sort(function (a, b) {
if (a.points !== b.points) {
return b.points - a.points;
}
var aGD = a.goalsFor - a.goalsAgainst;
var bGD = b.goalsFor - b.goalsAgainst;
if (aGD !== bGD) {
return bGD - aGD;
}
return b.goalsFor - a.goalsFor;
});
var championText = new Text2("Champion: " + sortedTeams[0].name, {
size: 60,
fill: 0xFFFF00
});
championText.anchor.set(0.5, 0);
championText.y = -900;
summaryView.addChild(championText);
var userTeamPos = sortedTeams.indexOf(teams[userTeamIndex]) + 1;
var userTeamText = new Text2("Your Team: " + teams[userTeamIndex].name + " (" + userTeamPos + ordinalSuffix(userTeamPos) + " place)", {
size: 50,
fill: 0xFFFFFF
});
userTeamText.anchor.set(0.5, 0);
userTeamText.y = -800;
summaryView.addChild(userTeamText);
var continueButton = new Button("CONTINUE TO SEASON " + season, function () {
game.removeChild(summaryView);
showScreen("fixtures");
});
continueButton.y = 900;
summaryView.addChild(continueButton);
summaryView.x = 2048 / 2;
summaryView.y = 2732 / 2;
game.addChild(summaryView);
}
// Initialize Game
function initGame() {
// Create teams and fixtures
createTeams();
createFixtures();
// Start with team selection or main menu
showScreen("loading");
}
// Game update
game.update = function () {
// Nothing to do in the update loop for now
// This simulation game is mostly event-driven
};
// Start the game
initGame();