/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/****
* Classes
****/
var Button = Container.expand(function () {
var self = Container.call(this);
var bg = self.attachAsset('button', {
anchorX: 0.5,
anchorY: 0.5
});
var label = new Text2('Button', {
size: 40,
fill: 0xFFFFFF
});
label.anchor.set(0.5, 0.5);
self.addChild(label);
self.setLabel = function (text) {
label.setText(text);
};
self.down = function () {
tween(bg, {
scaleX: 0.95,
scaleY: 0.95
}, {
duration: 100
});
LK.getSound('select').play();
};
self.up = function () {
tween(bg, {
scaleX: 1,
scaleY: 1
}, {
duration: 100
});
if (self.onClick) {
self.onClick();
}
};
return self;
});
var DeveloperCard = Container.expand(function () {
var self = Container.call(this);
var bg = self.attachAsset('card', {
anchorX: 0.5,
anchorY: 0.5
});
var icon = self.attachAsset('developerIcon', {
anchorX: 0.5,
anchorY: 0.5,
y: -100
});
var nameText = new Text2('Developer', {
size: 30,
fill: 0xFFFFFF
});
nameText.anchor.set(0.5, 0.5);
nameText.y = -20;
self.addChild(nameText);
var specialtyText = new Text2('Graphics', {
size: 25,
fill: 0xFFC107
});
specialtyText.anchor.set(0.5, 0.5);
specialtyText.y = 20;
self.addChild(specialtyText);
var costText = new Text2('Cost: $100', {
size: 25,
fill: 0x4CAF50
});
costText.anchor.set(0.5, 0.5);
costText.y = 60;
self.addChild(costText);
var skillText = new Text2('Skill: 5', {
size: 25,
fill: 0x2196F3
});
skillText.anchor.set(0.5, 0.5);
skillText.y = 100;
self.addChild(skillText);
self.developerData = null;
self.setDeveloper = function (data) {
self.developerData = data;
nameText.setText(data.name);
specialtyText.setText(data.specialty);
costText.setText('Cost: $' + data.cost);
skillText.setText('Skill: ' + data.skill);
var specialtyColors = {
'Graphics': 0xff5722,
'Sound': 0x9c27b0,
'Gameplay': 0x2196f3
};
icon.tint = specialtyColors[data.specialty] || 0xffc107;
};
self.down = function () {
if (self.onClick) {
self.onClick(self.developerData);
}
};
return self;
});
var FeatureCard = Container.expand(function () {
var self = Container.call(this);
var bg = self.attachAsset('card', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.8,
scaleY: 0.8
});
var icon = self.attachAsset('featureIcon', {
anchorX: 0.5,
anchorY: 0.5,
y: -80
});
var nameText = new Text2('Feature', {
size: 25,
fill: 0xFFFFFF
});
nameText.anchor.set(0.5, 0.5);
nameText.y = -20;
self.addChild(nameText);
var typeText = new Text2('Type', {
size: 20,
fill: 0x2196F3
});
typeText.anchor.set(0.5, 0.5);
typeText.y = 10;
self.addChild(typeText);
var pointsText = new Text2('Points: 0', {
size: 20,
fill: 0x4CAF50
});
pointsText.anchor.set(0.5, 0.5);
pointsText.y = 40;
self.addChild(pointsText);
self.featureData = null;
self.selected = false;
self.setFeature = function (data) {
self.featureData = data;
nameText.setText(data.name);
typeText.setText(data.type);
pointsText.setText('Points: ' + data.basePoints + ' | Cost: $' + data.cost);
var typeColors = {
'Graphics': 0xff5722,
'Sound': 0x9c27b0,
'Gameplay': 0x2196f3
};
icon.tint = typeColors[data.type] || 0xffc107;
};
self.setSelected = function (selected) {
self.selected = selected;
bg.tint = selected ? 0xe94560 : 0xffffff;
};
self.down = function () {
if (self.onClick) {
self.onClick(self);
}
};
return self;
});
var GameHistoryCard = Container.expand(function () {
var self = Container.call(this);
var bg = self.attachAsset('card', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.5,
scaleY: 0.6
});
var nameText = new Text2('Game Name', {
size: 30,
fill: 0xFFFFFF
});
nameText.anchor.set(0.5, 0.5);
nameText.y = -30;
self.addChild(nameText);
var salesText = new Text2('Sales: 0', {
size: 25,
fill: 0x4CAF50
});
salesText.anchor.set(0.5, 0.5);
salesText.y = 10;
self.addChild(salesText);
self.gameData = null;
self.setGameData = function (data) {
self.gameData = data;
nameText.setText(data.name);
var salesInfo = data.currentDailySales > 0 ? 'Sales: ' + data.totalSales + ' (Active)' : 'Sales: ' + data.totalSales + ' (Ended)';
salesText.setText(salesInfo);
bg.tint = data.currentDailySales > 0 ? 0x0f3460 : 0x16213e;
};
self.down = function () {
if (self.onClick) {
self.onClick(self.gameData);
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x1a1a2e
});
/****
* Game Code
****/
// Game state
function _typeof2(o) {
"@babel/helpers - typeof";
return _typeof2 = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) {
return typeof o;
} : function (o) {
return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o;
}, _typeof2(o);
}
function _typeof(o) {
"@babel/helpers - typeof";
return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) {
return typeof o;
} : function (o) {
return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o;
}, _typeof(o);
}
var gameState = {
money: 50000,
developers: [],
currentProject: null,
completedGames: 0,
marketTrends: [],
currentDay: 1,
releasedGames: [],
maxHireableDevelopers: 1,
studioLevel: 1,
studioUpgradeCost: 5000,
fans: 0,
// Toplam fan sayısı
mainCharacter: {
name: "You",
level: 1,
upgradeCost: 2000,
skill: 2,
specialty: "All",
featurePoints: {
Graphics: 1,
Sound: 1,
Gameplay: 1
}
},
gameHistory: [],
researchedFeatures: {
Graphics: [],
Sound: [],
Gameplay: [],
GameGenres: []
},
currentResearch: null,
// --- Feature selection limit per category ---
featureSelectionLimit: {
Graphics: 1,
Sound: 1,
Gameplay: 1
}
};
// Current game name being created
var currentGameName = '';
// Game name display at top
var gameNameDisplay = new Text2('', {
size: 45,
fill: 0xFFFFFF
});
gameNameDisplay.anchor.set(0.5, 0);
gameNameDisplay.y = 10;
LK.gui.top.addChild(gameNameDisplay);
// Available developers pool
var developerPool = [{
name: 'Alex',
specialty: 'Graphics',
skill: 3,
cost: 4000
}, {
name: 'Sam',
specialty: 'Sound',
skill: 4,
cost: 4000
}, {
name: 'Jordan',
specialty: 'Gameplay',
skill: 5,
cost: 4000
}, {
name: 'Morgan',
specialty: 'Graphics',
skill: 6,
cost: 8000
}, {
name: 'Casey',
specialty: 'Sound',
skill: 7,
cost: 8000
}, {
name: 'Drew',
specialty: 'Gameplay',
skill: 8,
cost: 8000
}, {
name: 'Taylor',
specialty: 'Graphics',
skill: 9,
cost: 12000
}, {
name: 'Jamie',
specialty: 'Sound',
skill: 10,
cost: 12000
}, {
name: 'Robin',
specialty: 'Gameplay',
skill: 11,
cost: 12000
}];
// Available features - expanded with research requirements
var featurePool = [{
name: 'Pixel Art',
type: 'Graphics',
basePoints: 3,
cost: 2000,
requiresResearch: false
}, {
name: '3D Models',
type: 'Graphics',
basePoints: 5,
cost: 2000,
requiresResearch: false
}, {
name: 'Particle Effects',
type: 'Graphics',
basePoints: 4,
cost: 2000,
requiresResearch: false
}, {
name: 'Soundtrack',
type: 'Sound',
basePoints: 3,
cost: 2000,
requiresResearch: false
}, {
name: 'Voice Acting',
type: 'Sound',
basePoints: 6,
cost: 2000,
requiresResearch: false
}, {
name: 'Sound Effects',
type: 'Sound',
basePoints: 4,
cost: 2000,
requiresResearch: false
}, {
name: 'RPG Elements',
type: 'Gameplay',
basePoints: 5,
cost: 2000,
requiresResearch: false
}, {
name: 'Multiplayer',
type: 'Gameplay',
basePoints: 7,
cost: 2000,
requiresResearch: false
}, {
name: 'Puzzles',
type: 'Gameplay',
basePoints: 4,
cost: 2000,
requiresResearch: false
}, {
name: 'Open World',
type: 'Gameplay',
basePoints: 8,
cost: 2000,
requiresResearch: false
}, {
name: 'Shaders',
type: 'Graphics',
basePoints: 6,
cost: 4000,
requiresResearch: true
}, {
name: 'Ray Tracing',
type: 'Graphics',
basePoints: 10,
cost: 6000,
requiresResearch: true
}, {
name: 'Motion Capture',
type: 'Graphics',
basePoints: 8,
cost: 4000,
requiresResearch: true
}, {
name: 'Procedural Generation',
type: 'Graphics',
basePoints: 7,
cost: 4000,
requiresResearch: true
}, {
name: 'Dynamic Lighting',
type: 'Graphics',
basePoints: 6,
cost: 4000,
requiresResearch: true
}, {
name: 'Orchestral Score',
type: 'Sound',
basePoints: 8,
cost: 4000,
requiresResearch: true
}, {
name: '3D Audio',
type: 'Sound',
basePoints: 7,
cost: 4000,
requiresResearch: true
}, {
name: 'Dynamic Music',
type: 'Sound',
basePoints: 6,
cost: 4000,
requiresResearch: true
}, {
name: 'Environmental Audio',
type: 'Sound',
basePoints: 5,
cost: 4000,
requiresResearch: true
}, {
name: 'Foley Effects',
type: 'Sound',
basePoints: 6,
cost: 4000,
requiresResearch: true
}, {
name: 'Physics Engine',
type: 'Gameplay',
basePoints: 9,
cost: 6000,
requiresResearch: true
}, {
name: 'AI Systems',
type: 'Gameplay',
basePoints: 10,
cost: 6000,
requiresResearch: true
}, {
name: 'Skill Trees',
type: 'Gameplay',
basePoints: 6,
cost: 4000,
requiresResearch: true
}, {
name: 'Crafting System',
type: 'Gameplay',
basePoints: 7,
cost: 4000,
requiresResearch: true
}, {
name: 'Dialogue System',
type: 'Gameplay',
basePoints: 5,
cost: 4000,
requiresResearch: true
}];
// Game genres that can be researched
var gameGenres = [{
name: 'Action',
baseMultiplier: 1.2,
trendChance: 0.3,
researchCost: 4000,
requiresResearch: false
}, {
name: 'Adventure',
baseMultiplier: 1.1,
trendChance: 0.25,
researchCost: 4000,
requiresResearch: false
}, {
name: 'Puzzle',
baseMultiplier: 1.0,
trendChance: 0.2,
researchCost: 4000,
requiresResearch: false
}, {
name: 'Racing',
baseMultiplier: 1.3,
trendChance: 0.35,
researchCost: 8000,
requiresResearch: true
}, {
name: 'Strategy',
baseMultiplier: 1.4,
trendChance: 0.3,
researchCost: 8000,
requiresResearch: true
}, {
name: 'Simulation',
baseMultiplier: 1.2,
trendChance: 0.25,
researchCost: 8000,
requiresResearch: true
}, {
name: 'RPG',
baseMultiplier: 1.5,
trendChance: 0.4,
researchCost: 12000,
requiresResearch: true
}, {
name: 'FPS',
baseMultiplier: 1.4,
trendChance: 0.35,
researchCost: 12000,
requiresResearch: true
}, {
name: 'Horror',
baseMultiplier: 1.3,
trendChance: 0.25,
researchCost: 12000,
requiresResearch: true
}, {
name: 'Sports',
baseMultiplier: 1.2,
trendChance: 0.3,
researchCost: 12000,
requiresResearch: true
}];
// UI Elements
var moneyText = new Text2('Money: $10000', {
size: 50,
fill: 0x4CAF50
});
moneyText.anchor.set(1, 0);
moneyText.x = 0;
moneyText.y = 0;
LK.gui.topRight.addChild(moneyText);
var developersText = new Text2('Developers: 0', {
size: 40,
fill: 0xFFFFFF
});
developersText.anchor.set(1, 0);
developersText.x = 0;
developersText.y = moneyText.y + moneyText.height + 8;
LK.gui.topRight.addChild(developersText);
var gamesText = new Text2('Games Released: 0', {
size: 40,
fill: 0xFFC107
});
gamesText.anchor.set(1, 0);
gamesText.x = 0;
gamesText.y = developersText.y + developersText.height + 8;
LK.gui.topRight.addChild(gamesText);
// Fan count and bonus UI
var fanText = new Text2('Fan: 0', {
size: 40,
fill: 0x2196F3
});
fanText.anchor.set(1, 0);
fanText.x = 0;
fanText.y = gamesText.y + gamesText.height + 8;
LK.gui.topRight.addChild(fanText);
var fanBonusText = new Text2('Sales Bonus: %0', {
size: 32,
fill: 0x4CAF50
});
fanBonusText.anchor.set(1, 0);
fanBonusText.x = 0;
fanBonusText.y = fanText.y + fanText.height + 8;
LK.gui.topRight.addChild(fanBonusText);
var dayText = new Text2('Day: 1', {
size: 40,
fill: 0x2196F3
});
dayText.anchor.set(1, 0);
dayText.x = 0;
dayText.y = fanBonusText.y + fanBonusText.height + 8;
LK.gui.topRight.addChild(dayText);
// --- Sales & Revenue Log UI ---
var salesLogContainer = new Container();
salesLogContainer.x = 2048 - 40; // right align
salesLogContainer.y = 220; // just below dayText
LK.gui.topRight.addChild(salesLogContainer);
var salesLogEntries = []; // keep references to Text2 objects for updating/removal
function updateSalesLog() {
// Remove old entries
for (var i = 0; i < salesLogEntries.length; i++) {
salesLogEntries[i].destroy();
}
salesLogEntries = [];
// Show up to 5 most recent games (active and ended)
var allGames = gameState.releasedGames.concat(gameState.gameHistory);
var recentGames = allGames.slice(-5).reverse();
var y = 0;
for (var i = 0; i < recentGames.length; i++) {
var g = recentGames[i];
var isActive = g.currentDailySales > 0;
var pricePerCopy = typeof g.price === "number" ? g.price : 1;
var revenue = Math.floor((g.currentDailySales || 0) * pricePerCopy);
var txt = new Text2(g.name + ': +' + (g.currentDailySales || 0) + ' | $' + revenue, {
size: 28,
fill: isActive ? 0x4CAF50 : 0x888888
});
txt.anchor.set(1, 0);
txt.x = 0;
txt.y = y;
salesLogContainer.addChild(txt);
salesLogEntries.push(txt);
y += 36;
}
}
// Main menu container
var mainMenu = new Container();
game.addChild(mainMenu);
// --- How to Play Button and Info Popup ---
var howToPlayBtn = new Button();
howToPlayBtn.setLabel('How to Play?');
howToPlayBtn.x = 1024;
howToPlayBtn.y = 180;
howToPlayBtn.onClick = function () {
// Remove previous popup if any
if (mainMenu.howToPlayPopup) {
mainMenu.howToPlayPopup.destroy();
mainMenu.howToPlayPopup = null;
}
var popup = new Container();
popup.x = 1024;
popup.y = 600;
var bg = LK.getAsset('card', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2.5,
scaleY: 2.2
});
bg.tint = 0x16213e;
popup.addChild(bg);
var infoText = new Text2("Welcome to Game Dev Studio!\n\n" + "• Hire talented developers to join your team.\n" + "• Start new projects and select the best features for your games.\n" + "• Follow market trends and research new technologies to stay ahead.\n" + "• Release your games, earn money, and gain fans.\n" + "• Upgrade your studio to hire more developers and unlock new possibilities.\n" + "• Compete with rival companies and become the top game studio!\n\n" + "Tip: Use the main menu to access hiring, research, platforms, and more.", {
size: 36,
fill: 0xFFFFFF,
align: "center"
});
infoText.anchor.set(0.5, 0.5);
infoText.x = 0;
infoText.y = -40;
popup.addChild(infoText);
var closeBtn = new Button();
closeBtn.setLabel('Close');
closeBtn.x = 0;
closeBtn.y = 320;
closeBtn.onClick = function () {
if (mainMenu.howToPlayPopup) {
mainMenu.howToPlayPopup.destroy();
mainMenu.howToPlayPopup = null;
}
};
popup.addChild(closeBtn);
mainMenu.addChild(popup);
mainMenu.howToPlayPopup = popup;
};
mainMenu.addChild(howToPlayBtn);
var titleText = new Text2('Game Dev Studio', {
size: 80,
fill: 0xFFFFFF
});
titleText.anchor.set(0.5, 0.5);
titleText.x = 1024;
titleText.y = 300;
mainMenu.addChild(titleText);
var hireDeveloperBtn = new Button();
hireDeveloperBtn.setLabel('Hire Developer');
hireDeveloperBtn.x = 1024;
hireDeveloperBtn.y = 750;
hireDeveloperBtn.onClick = showHireMenu;
mainMenu.addChild(hireDeveloperBtn);
var startProjectBtn = new Button();
startProjectBtn.setLabel('Start Project');
startProjectBtn.x = 1024;
startProjectBtn.y = 900;
startProjectBtn.onClick = showProjectMenu;
mainMenu.addChild(startProjectBtn);
var allGamesBtn = new Button();
allGamesBtn.setLabel('All Released Games');
allGamesBtn.x = 1024;
allGamesBtn.y = 1050;
allGamesBtn.onClick = showAllGamesMenu;
mainMenu.addChild(allGamesBtn);
var researchBtn = new Button();
researchBtn.setLabel('Research');
researchBtn.x = 1024;
researchBtn.y = 1200;
researchBtn.onClick = showResearchMenu;
mainMenu.addChild(researchBtn);
// (Game Engine button removed)
// --- Bank Button ---
var bankBtn = new Button();
bankBtn.setLabel('Bank');
bankBtn.x = 1024;
bankBtn.y = 1550;
bankBtn.onClick = showBankMenu;
mainMenu.addChild(bankBtn);
// --- Platform Button ---
var platformBtn = new Button();
platformBtn.setLabel('Platform');
platformBtn.x = 1024;
platformBtn.y = 1650;
platformBtn.onClick = showPlatformMenu;
mainMenu.addChild(platformBtn);
// --- Fan Button ---
var fanBtn = new Button();
fanBtn.setLabel('Fan');
fanBtn.x = 1024;
fanBtn.y = 1800;
fanBtn.onClick = showFanMenu;
mainMenu.addChild(fanBtn);
// --- Fan Store Button ---
var fanStoreBtn = new Button();
fanStoreBtn.setLabel('Fan Store');
fanStoreBtn.x = 1024;
fanStoreBtn.y = 1920;
fanStoreBtn.onClick = showFanStoreMenu;
mainMenu.addChild(fanStoreBtn);
// --- Rivals Button ---
var rivalsBtn = new Button();
rivalsBtn.setLabel('Rivals');
rivalsBtn.x = 1024;
rivalsBtn.y = 2040; // 2 satır altı (120px aralık)
rivalsBtn.onClick = showRivalsMenu;
mainMenu.addChild(rivalsBtn);
// --- Rivals Games Button ---
var rivalsGamesBtn = new Button();
rivalsGamesBtn.setLabel('Rivals Games');
rivalsGamesBtn.x = 1024;
rivalsGamesBtn.y = 2160; // Rivals butonunun hemen altında
rivalsGamesBtn.onClick = showRivalsGamesMenu;
mainMenu.addChild(rivalsGamesBtn);
// --- Bank Menu UI ---
var bankMenu = new Container();
bankMenu.visible = false;
game.addChild(bankMenu);
var bankTitle = new Text2('Bank', {
size: 60,
fill: 0xFFFFFF
});
bankTitle.anchor.set(0.5, 0.5);
bankTitle.x = 1024;
bankTitle.y = 200;
bankMenu.addChild(bankTitle);
// Bilgi yazısı: Banka sistemi hakkında açıklama (Geri tuşunun 3 satır yukarısına)
var bankInfoText = new Text2("Bank System:\n" + "- You must have no outstanding debt to take a new loan.\n" + "- If you pay off a loan early, you pay 10% extra of the original amount.\n" + "- When a loan matures, no extra interest is added; the debt waits until paid.\n" + "- You can deposit up to 50% of your cash as a deposit.\n" + "- When a deposit matures, interest stops. Use the withdraw button to collect your money.", {
size: 32,
fill: 0xFFC107,
align: "center"
});
bankInfoText.anchor.set(0.5, 1);
bankInfoText.x = 1024;
bankInfoText.y = 2400 - 3 * 50; // 3 satır yukarı (her satır ~50px)
bankMenu.addChild(bankInfoText);
var bankBackBtn = new Button();
bankBackBtn.setLabel('Back');
bankBackBtn.x = 1024;
bankBackBtn.y = 2400;
bankBackBtn.onClick = function () {
bankMenu.visible = false;
mainMenu.visible = true;
};
bankMenu.addChild(bankBackBtn);
// --- Bank state ---
if (!gameState.bank) {
gameState.bank = {
credit: 0,
creditDueDay: 0,
deposit: 0,
depositDueDay: 0
};
}
// --- Show Bank Menu function ---
function showBankMenu() {
mainMenu.visible = false;
bankMenu.visible = true;
// Remove old UI except title and back and info text
for (var i = bankMenu.children.length - 1; i >= 0; i--) {
var child = bankMenu.children[i];
if (child !== bankTitle && child !== bankBackBtn && child !== bankInfoText) {
child.destroy();
}
}
// Re-add info text if not present
if (!bankMenu.children.includes(bankInfoText)) {
bankMenu.addChild(bankInfoText);
}
// Info text
var infoText = new Text2('You can take a loan or make a deposit.', {
size: 36,
fill: 0x4CAF50
});
infoText.anchor.set(0.5, 0.5);
infoText.x = 1024;
infoText.y = 350;
bankMenu.addChild(infoText);
// --- Credit Section ---
var creditTitle = new Text2('Take Loan', {
size: 40,
fill: 0xFFC107
});
creditTitle.anchor.set(0.5, 0.5);
creditTitle.x = 1024;
creditTitle.y = 500;
bankMenu.addChild(creditTitle);
var creditAmount = 10000;
var creditInterest = 0.15; // %15 faiz
var creditDuration = 10; // 10 gün vade
var creditBtn = new Button();
creditBtn.setLabel('Take Loan (15% interest, 10 days, Limit: 20% of cash)');
creditBtn.x = 1024;
creditBtn.y = 600;
creditBtn.onClick = function () {
// Prevent new credit if there is any unpaid debt (even if overdue)
if (gameState.bank.credit > 0) {
// Show notification
var notif = new Container();
var bg = LK.getAsset('card', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2,
scaleY: 0.5
});
bg.tint = 0xE94560;
notif.addChild(bg);
var txt = new Text2('You must pay your previous loan first!', {
size: 32,
fill: 0xFFFFFF
});
txt.anchor.set(0.5, 0.5);
notif.addChild(txt);
notif.x = 1024;
notif.y = 800;
notif.alpha = 0;
game.addChild(notif);
tween(notif, {
alpha: 1
}, {
duration: 400,
onFinish: function onFinish() {
LK.setTimeout(function () {
tween(notif, {
alpha: 0
}, {
duration: 400,
onFinish: function onFinish() {
notif.destroy();
}
});
}, 1500);
}
});
return;
}
// Calculate credit limit as 20% of current cash (rounded down to nearest 1000)
var maxCredit = Math.floor(gameState.money * 0.2 / 1000) * 1000;
if (maxCredit < 1000) maxCredit = 1000; // Minimum 1000₺
var creditInterest = 0.15; // %15 faiz
var creditDuration = 10; // 10 gün vade
if (maxCredit <= 0) {
// Show notification for no available credit
var notif = new Container();
var bg = LK.getAsset('card', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2,
scaleY: 0.5
});
bg.tint = 0xE94560;
notif.addChild(bg);
var txt = new Text2('No loan limit! (You have too little cash)', {
size: 32,
fill: 0xFFFFFF
});
txt.anchor.set(0.5, 0.5);
notif.addChild(txt);
notif.x = 1024;
notif.y = 800;
notif.alpha = 0;
game.addChild(notif);
tween(notif, {
alpha: 1
}, {
duration: 400,
onFinish: function onFinish() {
LK.setTimeout(function () {
tween(notif, {
alpha: 0
}, {
duration: 400,
onFinish: function onFinish() {
notif.destroy();
}
});
}, 1500);
}
});
return;
}
// Grant credit
gameState.money += maxCredit;
gameState.bank.credit = maxCredit * (1 + creditInterest);
gameState.bank.creditDueDay = gameState.currentDay + creditDuration;
updateUI();
showBankMenu();
LK.getSound('success').play();
};
bankMenu.addChild(creditBtn);
var creditStatus = '';
if (gameState.bank.credit > 0 && gameState.currentDay < gameState.bank.creditDueDay) {
creditStatus = 'Remaining Debt: ' + Math.round(gameState.bank.credit) + ' | Due Day: ' + gameState.bank.creditDueDay;
} else if (gameState.bank.credit > 0 && gameState.currentDay >= gameState.bank.creditDueDay) {
creditStatus = 'Loan matured! Debt: ' + Math.round(gameState.bank.credit);
} else {
creditStatus = 'No active loan.';
}
var creditStatusText = new Text2(creditStatus, {
size: 30,
fill: 0xFFFFFF
});
creditStatusText.anchor.set(0.5, 0.5);
creditStatusText.x = 1024;
creditStatusText.y = 670;
bankMenu.addChild(creditStatusText);
// --- Deposit Section ---
var depositTitle = new Text2('Make Deposit', {
size: 40,
fill: 0x2196F3
});
depositTitle.anchor.set(0.5, 0.5);
depositTitle.x = 1024;
depositTitle.y = 850;
bankMenu.addChild(depositTitle);
// Ava: Mevduat yatırma oranı, nakit paramızın maksimum %50'sine kadar olmalı
var depositInterest = 0.10; // %10 faiz
var depositDuration = 10; // 10 gün vade
// Hesaplanan maksimum mevduat miktarı (en az 1000₺, 1000'lik katlar)
var maxDeposit = Math.floor(gameState.money * 0.5 / 1000) * 1000;
if (maxDeposit < 1000) maxDeposit = 1000;
var depositAmount = maxDeposit;
var depositBtn = new Button();
depositBtn.setLabel(maxDeposit + ' Deposit (10% interest, 10 days)');
depositBtn.x = 1024;
depositBtn.y = 950;
depositBtn.onClick = function () {
// Only allow one active deposit at a time
if (gameState.bank.deposit > 0 && gameState.currentDay < gameState.bank.depositDueDay) {
// Show notification
var notif = new Container();
var bg = LK.getAsset('card', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2,
scaleY: 0.5
});
bg.tint = 0xE94560;
notif.addChild(bg);
var txt = new Text2('Your previous deposit is still maturing!', {
size: 32,
fill: 0xFFFFFF
});
txt.anchor.set(0.5, 0.5);
notif.addChild(txt);
notif.x = 1024;
notif.y = 1150;
notif.alpha = 0;
game.addChild(notif);
tween(notif, {
alpha: 1
}, {
duration: 400,
onFinish: function onFinish() {
LK.setTimeout(function () {
tween(notif, {
alpha: 0
}, {
duration: 400,
onFinish: function onFinish() {
notif.destroy();
}
});
}, 1500);
}
});
return;
}
if (gameState.money < depositAmount) {
// Show notification
var notif = new Container();
var bg = LK.getAsset('card', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2,
scaleY: 0.5
});
bg.tint = 0xE94560;
notif.addChild(bg);
var txt = new Text2('Not enough money!', {
size: 32,
fill: 0xFFFFFF
});
txt.anchor.set(0.5, 0.5);
notif.addChild(txt);
notif.x = 1024;
notif.y = 1150;
notif.alpha = 0;
game.addChild(notif);
tween(notif, {
alpha: 1
}, {
duration: 400,
onFinish: function onFinish() {
LK.setTimeout(function () {
tween(notif, {
alpha: 0
}, {
duration: 400,
onFinish: function onFinish() {
notif.destroy();
}
});
}, 1500);
}
});
return;
}
gameState.money -= depositAmount;
gameState.bank.deposit = depositAmount * (1 + depositInterest);
gameState.bank.depositDueDay = gameState.currentDay + depositDuration;
updateUI();
showBankMenu();
LK.getSound('success').play();
};
bankMenu.addChild(depositBtn);
var depositStatus = '';
if (gameState.bank.deposit > 0 && gameState.currentDay < gameState.bank.depositDueDay) {
depositStatus = 'Deposit: ' + Math.round(gameState.bank.deposit) + ' | Due Day: ' + gameState.bank.depositDueDay;
} else if (gameState.bank.deposit > 0 && gameState.currentDay >= gameState.bank.depositDueDay) {
depositStatus = 'Deposit matured! Withdrawable: ' + Math.round(gameState.bank.deposit);
} else {
depositStatus = 'No active deposit.';
}
var depositStatusText = new Text2(depositStatus, {
size: 30,
fill: 0xFFFFFF
});
depositStatusText.anchor.set(0.5, 0.5);
depositStatusText.x = 1024;
depositStatusText.y = 1020;
bankMenu.addChild(depositStatusText);
// --- Deposit Withdraw Button (if matured) ---
if (gameState.bank.deposit > 0 && gameState.currentDay >= gameState.bank.depositDueDay) {
var withdrawBtn = new Button();
withdrawBtn.setLabel('Withdraw Deposit (+ ' + Math.round(gameState.bank.deposit) + ')');
withdrawBtn.x = 1024;
withdrawBtn.y = 1100;
withdrawBtn.onClick = function () {
gameState.money += Math.round(gameState.bank.deposit);
gameState.bank.deposit = 0;
gameState.bank.depositDueDay = 0;
updateUI();
showBankMenu();
LK.getSound('success').play();
};
bankMenu.addChild(withdrawBtn);
}
// --- Credit Pay Button (if matured or early) ---
// Early payment: allow if credit > 0 and not overdue
if (gameState.bank.credit > 0 && gameState.currentDay < gameState.bank.creditDueDay) {
var earlyPayBtn = new Button();
// Early payment is original credit + 10% of original credit (not 10% of current debt)
// Calculate original credit amount (principal)
var originalCredit = Math.round(gameState.bank.credit / 1.15); // since credit = principal * 1.15
var earlyPayAmount = Math.round(originalCredit * 1.10); // %10 fazlası
earlyPayBtn.setLabel('Pay Early (-' + earlyPayAmount + ', 10% interest)');
earlyPayBtn.x = 1024;
earlyPayBtn.y = 750;
earlyPayBtn.onClick = function () {
if (gameState.money >= earlyPayAmount) {
gameState.money -= earlyPayAmount;
gameState.bank.credit = 0;
gameState.bank.creditDueDay = 0;
updateUI();
showBankMenu();
LK.getSound('success').play();
} else {
// Show notification
var notif = new Container();
var bg = LK.getAsset('card', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2,
scaleY: 0.5
});
bg.tint = 0xE94560;
notif.addChild(bg);
var txt = new Text2('Not enough money!', {
size: 32,
fill: 0xFFFFFF
});
txt.anchor.set(0.5, 0.5);
notif.addChild(txt);
notif.x = 1024;
notif.y = 900;
notif.alpha = 0;
game.addChild(notif);
tween(notif, {
alpha: 1
}, {
duration: 400,
onFinish: function onFinish() {
LK.setTimeout(function () {
tween(notif, {
alpha: 0
}, {
duration: 400,
onFinish: function onFinish() {
notif.destroy();
}
});
}, 1500);
}
});
}
};
bankMenu.addChild(earlyPayBtn);
}
// Normal payment: if matured or overdue
if (gameState.bank.credit > 0 && gameState.currentDay >= gameState.bank.creditDueDay) {
var payBtn = new Button();
payBtn.setLabel('Pay Loan (-' + Math.round(gameState.bank.credit) + ')');
payBtn.x = 1024;
payBtn.y = 750;
payBtn.onClick = function () {
if (gameState.money >= Math.round(gameState.bank.credit)) {
gameState.money -= Math.round(gameState.bank.credit);
gameState.bank.credit = 0;
gameState.bank.creditDueDay = 0;
updateUI();
showBankMenu();
LK.getSound('success').play();
} else {
// Show notification
var notif = new Container();
var bg = LK.getAsset('card', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2,
scaleY: 0.5
});
bg.tint = 0xE94560;
notif.addChild(bg);
var txt = new Text2('Not enough money!', {
size: 32,
fill: 0xFFFFFF
});
txt.anchor.set(0.5, 0.5);
notif.addChild(txt);
notif.x = 1024;
notif.y = 900;
notif.alpha = 0;
game.addChild(notif);
tween(notif, {
alpha: 1
}, {
duration: 400,
onFinish: function onFinish() {
LK.setTimeout(function () {
tween(notif, {
alpha: 0
}, {
duration: 400,
onFinish: function onFinish() {
notif.destroy();
}
});
}, 1500);
}
});
}
};
bankMenu.addChild(payBtn);
}
}
// --- Rivals Games Menu UI ---
var rivalsGamesMenu = new Container();
rivalsGamesMenu.visible = false;
game.addChild(rivalsGamesMenu);
var rivalsGamesTitle = new Text2('Rivals Games', {
size: 60,
fill: 0xFFFFFF
});
rivalsGamesTitle.anchor.set(0.5, 0.5);
rivalsGamesTitle.x = 1024;
rivalsGamesTitle.y = 200;
rivalsGamesMenu.addChild(rivalsGamesTitle);
var rivalsGamesBackBtn = new Button();
rivalsGamesBackBtn.setLabel('Geri');
rivalsGamesBackBtn.x = 1024;
rivalsGamesBackBtn.y = 2400;
rivalsGamesBackBtn.onClick = function () {
rivalsGamesMenu.visible = false;
mainMenu.visible = true;
};
rivalsGamesMenu.addChild(rivalsGamesBackBtn);
// --- Helper: Show Rivals Games Menu ---
function showRivalsGamesMenu() {
mainMenu.visible = false;
rivalsGamesMenu.visible = true;
// Eski kartları temizle (başlık ve geri hariç)
for (var i = rivalsGamesMenu.children.length - 1; i >= 0; i--) {
var child = rivalsGamesMenu.children[i];
if (child !== rivalsGamesTitle && child !== rivalsGamesBackBtn) {
child.destroy();
}
}
// Tüm rakiplerin çıkardığı oyunları topla
var allRivalGames = [];
for (var i = 0; i < gameState.rivals.length; i++) {
var rival = gameState.rivals[i];
if (rival.games && rival.games.length > 0) {
for (var j = 0; j < rival.games.length; j++) {
var g = rival.games[j];
// Her oyun için rakip adı ekle
allRivalGames.push({
name: g.name,
revenue: g.revenue,
releaseDay: g.releaseDay,
rivalName: rival.name
});
}
}
}
// Oyunları en yeniye göre sırala (büyükten küçüğe)
allRivalGames.sort(function (a, b) {
return b.releaseDay - a.releaseDay;
});
// Hiç oyun yoksa bilgi göster
if (allRivalGames.length === 0) {
var noRivalGamesText = new Text2('No rival has released a game yet', {
size: 40,
fill: 0xFFFFFF
});
noRivalGamesText.anchor.set(0.5, 0.5);
noRivalGamesText.x = 1024;
noRivalGamesText.y = 600;
rivalsGamesMenu.addChild(noRivalGamesText);
return;
}
// 4 sütun, 7 satır grid (28 oyun gösterilecek şekilde)
var cols = 4;
var xStart = 320,
yStart = 440 * 1.1,
xSpacing = 370 * 1.1,
ySpacing = 180 * 1.1;
for (var i = 0; i < allRivalGames.length && i < 28; i++) {
var game = allRivalGames[i];
var col = i % cols,
row = Math.floor(i / cols);
var container = new Container();
container.x = xStart + col * xSpacing;
container.y = yStart + row * ySpacing;
// Kart arka planı
var bg = LK.getAsset('card', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.0,
scaleY: 0.45
});
container.addChild(bg);
// Oyun adı
var nameText = new Text2(game.name, {
size: 28,
fill: 0xFFFFFF
});
nameText.anchor.set(0.5, 0.5);
nameText.y = -30;
container.addChild(nameText);
// Rakip firma adı
var rivalText = new Text2('Company: ' + game.rivalName, {
size: 24,
fill: 0x2196F3
});
rivalText.anchor.set(0.5, 0.5);
rivalText.y = 10;
container.addChild(rivalText);
// Gelir veya Zarar
var revenueLabel = 'Gelir: $' + game.revenue;
var revenueColor = 0x4CAF50;
if (typeof game.revenue === "number" && game.revenue === 0) {
// Zarar varsa, revenue 0 olarak tutuluyor, ama aslında zarar vardı.
// Oyun objesinde orijinal zarar bilgisini bulmak için rakip firmanın oyunlarını arayalım.
var actualLoss = 0;
for (var ri = 0; ri < gameState.rivals.length; ri++) {
var rival = gameState.rivals[ri];
if (rival.name === game.rivalName && rival.games && rival.games.length > 0) {
for (var gj = 0; gj < rival.games.length; gj++) {
var g2 = rival.games[gj];
if (g2.name === game.name && g2.releaseDay === game.releaseDay) {
// Orijinal revenue negatifse, onu göster
if (typeof g2._originalLoss === "number" && g2._originalLoss > 0) {
actualLoss = g2._originalLoss;
} else if (typeof g2._originalRevenue === "number" && g2._originalRevenue < 0) {
actualLoss = -g2._originalRevenue;
}
}
}
}
}
revenueLabel = 'Loss: $' + (actualLoss > 0 ? actualLoss : 0);
revenueColor = 0xE94560;
}
var revenueText = new Text2(revenueLabel, {
size: 24,
fill: revenueColor
});
revenueText.anchor.set(0.5, 0.5);
revenueText.y = 40;
container.addChild(revenueText);
// Çıkış günü
var dayText = new Text2('Day: ' + game.releaseDay, {
size: 22,
fill: 0xFFC107
});
dayText.anchor.set(0.5, 0.5);
dayText.y = 70;
container.addChild(dayText);
rivalsGamesMenu.addChild(container);
}
}
// --- Rivals Menu UI ---
var rivalsMenu = new Container();
rivalsMenu.visible = false;
game.addChild(rivalsMenu);
var rivalsTitle = new Text2('Rival Companies', {
size: 60,
fill: 0xFFFFFF
});
rivalsTitle.anchor.set(0.5, 0.5);
rivalsTitle.x = 1024;
rivalsTitle.y = 200;
rivalsMenu.addChild(rivalsTitle);
var rivalsBackBtn = new Button();
rivalsBackBtn.setLabel('Back');
rivalsBackBtn.x = 1024;
rivalsBackBtn.y = 2400;
rivalsBackBtn.onClick = function () {
rivalsMenu.visible = false;
mainMenu.visible = true;
};
rivalsMenu.addChild(rivalsBackBtn);
// --- Rivals Data ---
if (!gameState.rivals) {
// 28 popüler firma, her biri 20-30 günde bir oyun çıkarır
var rivalNames = ["PixelForge", "BitMasters", "RetroSoft", "NextGen Games", "Funbyte", "DreamPixel", "CodeCrafters", "GameNest", "Playverse", "IndieGiant", "ArcadiaWorks", "QuantumPlay", "StudioNova", "BlueBox", "RedShift", "MegaFun", "GameWave", "Starbyte", "EpicPlay", "VirtuaDev",
// 8 yeni firma
"NeonPixel", "TurboPlay", "GameSmiths", "HyperNova", "PlayMakers", "PixelPioneers", "FunLab", "InfinityGames"];
gameState.rivals = [];
for (var i = 0; i < rivalNames.length; i++) {
var baseValue = 100000 + Math.floor(Math.random() * 100000); // 100k-200k arası başlangıç değeri
var rival = {
name: rivalNames[i],
value: baseValue,
ownedPercent: 0,
// Oyuncunun sahip olduğu yüzde
games: [],
lastReleaseDay: 1 + Math.floor(Math.random() * 10),
// İlk oyun çıkış günü
releaseInterval: 20 + Math.floor(Math.random() * 11),
// 20-30 gün arası
avgRevenue: 0 // Son 3 oyunun ortalaması
};
gameState.rivals.push(rival);
}
// Oyuncunun şirket değeri başlangıçta: anlık nakit paramın %20'si + sahip olunan şirketlerin değerleri toplamı
var cash = gameState.money || 0;
var cashPart = cash * 0.20;
var ownedValueSum = 0;
if (gameState.rivals && gameState.rivals.length > 0) {
for (var i = 0; i < gameState.rivals.length; i++) {
var rival = gameState.rivals[i];
if (rival.ownedPercent && rival.ownedPercent > 0) {
ownedValueSum += Math.floor((rival.value || 0) * (rival.ownedPercent / 100));
}
}
}
gameState.companyValue = Math.floor(cashPart + ownedValueSum);
}
// --- Helper: Rival yeni oyun çıkarır ---
function rivalReleaseGame(rival, day) {
// Oyun ismi ve gelirini üret
var gameNames = ["Super", "Mega", "Ultra", "Epic", "Legend", "Pixel", "Quest", "Saga", "Chronicles", "World"];
var gameSuffix = ["Adventure", "Battle", "Story", "Kingdom", "Odyssey", "Arena", "Tycoon", "Empire", "Run", "Hero"];
var name = gameNames[Math.floor(Math.random() * gameNames.length)] + " " + gameSuffix[Math.floor(Math.random() * gameSuffix.length)];
// Rakip oyun kazancı, rakip şirket değerinin %1-%20 aralığında kâr veya %1-%20 aralığında zarar olacak şekilde ayarlandı
var percent = (Math.random() < 0.5 ? -1 : 1) * (0.01 + Math.random() * 0.19); // -0.01 ile -0.20 veya +0.01 ile +0.20 arası
var baseValue = rival.value || 100000;
var revenue = Math.floor(baseValue * Math.abs(percent));
var originalRevenue = revenue;
if (percent < 0) {
revenue = -revenue;
}
var originalLoss = 0;
if (revenue < 0) {
originalLoss = -revenue;
revenue = 0;
}
var game = {
name: name,
releaseDay: day,
revenue: revenue,
_originalRevenue: percent < 0 ? -originalRevenue : originalRevenue,
_originalLoss: originalLoss
};
rival.games.push(game);
// Sadece son 3 oyunun ortalamasını tut
if (rival.games.length > 3) rival.games = rival.games.slice(-3);
// Firma değerini anlık olarak kâr/zarara göre değiştir: kâr ise artır, zarar ise azalt
if (revenue > 0) {
rival.value += revenue + Math.floor(revenue * 0.1);
} else if (originalLoss > 0) {
rival.value -= originalLoss;
}
if (rival.value < 0) rival.value = 0;
// Son 3 oyunun ortalamasını güncelle
var sum = 0;
for (var i = 0; i < rival.games.length; i++) sum += rival.games[i].revenue;
rival.avgRevenue = Math.floor(sum / rival.games.length);
}
// --- Helper: Oyuncu rakipten hisse satın alır ---
function buyRivalShare(rival, percent) {
var price = Math.floor(rival.value * percent / 100);
if (gameState.money >= price && rival.ownedPercent + percent <= 100) {
gameState.money -= price;
rival.ownedPercent += percent;
// --- Ava: Satın alınan %10'luk hisse için alış fiyatını kaydet ---
if (!rival.sharePurchaseHistory) rival.sharePurchaseHistory = [];
for (var i = 0; i < percent / 10; i++) {
rival.sharePurchaseHistory.push(price);
}
// Ava: Increase player's company value by the purchased share percent of the rival's value
if (!gameState.companyValue) gameState.companyValue = 0;
gameState.companyValue += Math.floor(rival.value * (percent / 100));
updateUI();
LK.getSound('success').play();
showRivalsMenu();
}
}
// --- Helper: Rakiplerden oyuncuya gelir aktarımı ---
function processRivalIncome() {
for (var i = 0; i < gameState.rivals.length; i++) {
var rival = gameState.rivals[i];
if (rival.ownedPercent > 0 && rival.avgRevenue > 0) {
var income = Math.floor(rival.avgRevenue * (rival.ownedPercent / 100));
gameState.money += income;
}
}
}
// --- Rivals Menu Show ---
function showRivalsMenu() {
mainMenu.visible = false;
rivalsMenu.visible = true;
// Eski kartları temizle
for (var i = rivalsMenu.children.length - 1; i >= 0; i--) {
var child = rivalsMenu.children[i];
if (child !== rivalsTitle && child !== rivalsBackBtn) {
child.destroy();
}
}
// 4 sütunlu grid, 7 satır (ekrana sığacak şekilde 28 firma için)
// YENİ: yStart bir satır aşağı (ör: +40px), fontlar 30, hizalama güncellendi
var cols = 4;
var xStart = 320,
yStart = 440 * 1.1,
// 1 satır aşağı
xSpacing = 370 * 1.1,
ySpacing = 260 * 1.1;
for (var i = 0; i < gameState.rivals.length; i++) {
var rival = gameState.rivals[i];
var col = i % cols,
row = Math.floor(i / cols);
var container = new Container();
container.x = xStart + col * xSpacing;
container.y = yStart + row * ySpacing;
// Kart arka planı
var bg = LK.getAsset('card', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.0,
scaleY: 0.55
});
container.addChild(bg);
// Firma adı
var nameText = new Text2(rival.name, {
size: 30,
fill: 0xFFFFFF
});
nameText.anchor.set(0.5, 0.5);
nameText.y = -50;
container.addChild(nameText);
// Değer
var valueText = new Text2('Value: $' + rival.value, {
size: 30,
fill: 0x4CAF50
});
valueText.anchor.set(0.5, 0.5);
valueText.y = -10;
container.addChild(valueText);
// Sahip olunan yüzde
var ownedText = new Text2('Ownership: %' + rival.ownedPercent, {
size: 30,
fill: rival.ownedPercent >= 100 ? 0xFFC107 : 0x2196F3
});
ownedText.anchor.set(0.5, 0.5);
ownedText.y = 30;
container.addChild(ownedText);
// Son oyun(lar)
var lastGame = rival.games.length > 0 ? rival.games[rival.games.length - 1] : null;
var lastGameText = "";
if (lastGame) {
if (typeof lastGame.revenue === "number" && lastGame.revenue === 0) {
// Zarar miktarını göster
var actualLoss = 0;
if (typeof lastGame._originalLoss === "number" && lastGame._originalLoss > 0) {
actualLoss = lastGame._originalLoss;
} else if (typeof lastGame._originalRevenue === "number" && lastGame._originalRevenue < 0) {
actualLoss = -lastGame._originalRevenue;
}
lastGameText = "Last Game: " + lastGame.name + " (Loss: $" + (actualLoss > 0 ? actualLoss : 0) + ")";
} else {
lastGameText = "Last Game: " + lastGame.name + " ($" + lastGame.revenue + ")";
}
} else {
lastGameText = "No games yet";
}
var gameText = new Text2(lastGameText, {
size: 30,
fill: 0xFFFFFF
});
gameText.anchor.set(0.5, 0.5);
gameText.y = 70;
container.addChild(gameText);
// Sadece 1 tane %10'luk buton göster, %100 olana kadar
if (rival.ownedPercent < 100) {
var percent = 10;
var price = Math.floor(rival.value * percent / 100);
var buyBtn = new Button();
buyBtn.setLabel('Buy 10% ($' + price + ')');
buyBtn.x = -90;
buyBtn.y = 120;
buyBtn.scaleX = 0.7;
buyBtn.scaleY = 0.7;
buyBtn.onClick = function (rival, percent) {
return function () {
buyRivalShare(rival, percent);
};
}(rival, percent);
container.addChild(buyBtn);
// --- %10 Sat butonu ---
if (rival.ownedPercent >= 10) {
// --- Ava: Satış fiyatı, ilk alış fiyatına göre hesaplanmalı! ---
// Satın alınan her %10'luk hisse için alış fiyatını kaydet
if (!rival.sharePurchaseHistory) rival.sharePurchaseHistory = [];
// Eğer sharePurchaseHistory eksikse, eski kayıtlara göre doldur (eski kayıtsız oyunlar için)
var ownedShares = Math.floor(rival.ownedPercent / 10);
while (rival.sharePurchaseHistory.length < ownedShares) {
// Eski oyunlarda, ilk alış fiyatı olarak o anki değeri kaydet
rival.sharePurchaseHistory.push(Math.floor(rival.value * 0.1));
}
// Satılacak ilk %10'luk hissenin alış fiyatı
var sellPrice = rival.sharePurchaseHistory.length > 0 ? rival.sharePurchaseHistory[0] : price;
var sellBtn = new Button();
sellBtn.setLabel('Sell 10% (+$' + sellPrice + ')');
sellBtn.x = 90;
sellBtn.y = 120;
sellBtn.scaleX = 0.7;
sellBtn.scaleY = 0.7;
sellBtn.onClick = function (rival, percent) {
return function () {
// Satış işlemi: %10 hisseyi sat, para al, şirket değerini azalt
if (rival.ownedPercent >= percent && rival.sharePurchaseHistory && rival.sharePurchaseHistory.length > 0) {
rival.ownedPercent -= percent;
var soldPrice = rival.sharePurchaseHistory.shift();
gameState.money += soldPrice;
// Ava: Satınca şirket değerini de orantılı azalt
if (!gameState.companyValue) gameState.companyValue = 0;
gameState.companyValue -= Math.floor(rival.value * (percent / 100));
if (gameState.companyValue < 0) gameState.companyValue = 0;
updateUI();
LK.getSound('success').play();
showRivalsMenu();
}
};
}(rival, percent);
container.addChild(sellBtn);
}
} else {
// %100 ise, gelirinin tamamı oyuncuya geçer
var fullText = new Text2('All income is yours!', {
size: 30,
fill: 0xFFC107
});
fullText.anchor.set(0.5, 0.5);
fullText.y = 120;
container.addChild(fullText);
}
rivalsMenu.addChild(container);
}
// Rivals sayfasına girince şirket değerini anlık olarak güncelle
var cash = gameState.money || 0;
var cashPart = cash * 0.20;
var ownedValueSum = 0;
if (gameState.rivals && gameState.rivals.length > 0) {
for (var i = 0; i < gameState.rivals.length; i++) {
var rival = gameState.rivals[i];
if (rival.ownedPercent && rival.ownedPercent > 0) {
ownedValueSum += Math.floor((rival.value || 0) * (rival.ownedPercent / 100));
}
}
}
gameState.companyValue = Math.floor(cashPart + ownedValueSum);
// Oyuncu şirket değeri göster
if (rivalsMenu.companyValueText) rivalsMenu.companyValueText.destroy();
var companyValueText = new Text2('Your Company Value: $' + (gameState.companyValue || 0), {
size: 38,
fill: 0xE94560
});
companyValueText.anchor.set(0.5, 0.5);
companyValueText.x = 1024;
companyValueText.y = 350;
rivalsMenu.addChild(companyValueText);
rivalsMenu.companyValueText = companyValueText;
}
// --- Her gün başında rakipler yeni oyun çıkarır ve gelirler işlenir ---
if (!gameState._rivalLastDay) gameState._rivalLastDay = gameState.currentDay;
var _oldGameUpdate = game.update;
game.update = function () {
// Her gün başında
if (gameState.currentDay !== gameState._rivalLastDay) {
for (var i = 0; i < gameState.rivals.length; i++) {
var rival = gameState.rivals[i];
if (!rival.lastReleaseDay) rival.lastReleaseDay = 1;
if (!rival.releaseInterval) rival.releaseInterval = 25;
if (gameState.currentDay - rival.lastReleaseDay >= rival.releaseInterval) {
rivalReleaseGame(rival, gameState.currentDay);
rival.lastReleaseDay = gameState.currentDay;
}
}
// Oyuncuya rakiplerden gelir aktar
processRivalIncome();
// Oyuncu şirket değeri: Son 3 oyunun ortalamasının 5 katı + 50k
var myAvg = 0;
if (gameState.releasedGames && gameState.releasedGames.length > 0) {
var sum = 0,
count = 0;
for (var i = gameState.releasedGames.length - 1; i >= 0 && count < 3; i--, count++) {
var g = gameState.releasedGames[i];
var pricePerCopy = typeof g.price === "number" ? g.price : 1;
sum += (g.totalSales || 0) * pricePerCopy;
}
if (count > 0) myAvg = Math.floor(sum / count);
}
// --- Ava: Şirket değeri, anlık nakit paramın %20'si + aldığım şirketlerin değerleri toplamı olarak hesaplanır ---
var cash = gameState.money || 0;
var cashPart = cash * 0.20;
var ownedValueSum = 0;
if (gameState.rivals && gameState.rivals.length > 0) {
for (var i = 0; i < gameState.rivals.length; i++) {
var rival = gameState.rivals[i];
if (rival.ownedPercent && rival.ownedPercent > 0) {
ownedValueSum += Math.floor((rival.value || 0) * (rival.ownedPercent / 100));
}
}
}
gameState.companyValue = Math.floor(cashPart + ownedValueSum);
gameState._rivalLastDay = gameState.currentDay;
}
if (_oldGameUpdate) _oldGameUpdate();
};
// --- Fan Menu UI ---
var fanMenu = new Container();
fanMenu.visible = false;
game.addChild(fanMenu);
var fanTitle = new Text2('Fan Shop', {
size: 60,
fill: 0xFFFFFF
});
fanTitle.anchor.set(0.5, 0.5);
fanTitle.x = 1024;
fanTitle.y = 200;
fanMenu.addChild(fanTitle);
var fanBackBtn = new Button();
fanBackBtn.setLabel('Back');
fanBackBtn.x = 1024;
fanBackBtn.y = 2400;
fanBackBtn.onClick = function () {
fanMenu.visible = false;
mainMenu.visible = true;
};
fanMenu.addChild(fanBackBtn);
// Fan products (each gives fans)
var fanProducts = [{
name: "T-shirt",
price: 400,
fans: 40,
desc: "Studio t-shirt, gives 40 fans."
}, {
name: "Poster",
price: 800,
fans: 100,
desc: "Game poster, gives 100 fans."
}, {
name: "Mug",
price: 1500,
fans: 200,
desc: "Studio mug, gives 200 fans."
}, {
name: "Keychain",
price: 2500,
fans: 350,
desc: "Studio keychain, gives 350 fans."
}, {
name: "Mousepad",
price: 3500,
fans: 500,
desc: "Studio mousepad, gives 500 fans."
}, {
name: "Figure",
price: 6000,
fans: 900,
desc: "Collector's figure, gives 900 fans."
}, {
name: "Collector's Pack",
price: 12000,
fans: 2000,
desc: "Special collector's pack, gives 2000 fans."
}, {
name: "Hoodie",
price: 20000,
fans: 3500,
desc: "Studio hoodie, gives 3500 fans."
}, {
name: "Limited Edition Art",
price: 35000,
fans: 6000,
desc: "Limited edition art, gives 6000 fans."
}, {
name: "VIP Fan Club Membership",
price: 50000,
fans: 10000,
desc: "VIP fan club membership, gives 10000 fans."
}];
// --- Fan Store Products (20 items, computers and game-related) ---
var fanStoreProducts = [{
name: "Retro PC",
price: 2000,
desc: "Classic 80s computer.",
type: "hardware"
}, {
name: "Game Console",
price: 3000,
desc: "Legendary game console.",
type: "hardware"
}, {
name: "Joystick",
price: 500,
desc: "Retro joystick.",
type: "accessory"
}, {
name: "Gaming Mouse",
price: 800,
desc: "Precision gaming mouse.",
type: "accessory"
}, {
name: "Keyboard",
price: 700,
desc: "Mechanical keyboard.",
type: "accessory"
}, {
name: "Gaming Headset",
price: 1200,
desc: "Surround sound headset.",
type: "accessory"
}, {
name: "Game Magazine",
price: 300,
desc: "Collector's magazine.",
type: "magazine"
}, {
name: "Game Cartridge",
price: 600,
desc: "Rare game cartridge.",
type: "game"
}, {
name: "Collector's Edition",
price: 5000,
desc: "Special collector's box.",
type: "game"
}, {
name: "Game Poster",
price: 400,
desc: "Classic game poster.",
type: "poster"
}, {
name: "Desktop PC",
price: 4000,
desc: "Powerful desktop PC.",
type: "hardware"
}, {
name: "Laptop",
price: 3500,
desc: "Portable gaming laptop.",
type: "hardware"
}, {
name: "Gaming Mousepad",
price: 350,
desc: "Large mousepad.",
type: "accessory"
}, {
name: "Game Figure",
price: 900,
desc: "Collector's figure.",
type: "figure"
}, {
name: "Game Keychain",
price: 200,
desc: "Game-themed keychain.",
type: "accessory"
}, {
name: "Game T-shirt",
price: 250,
desc: "Game logo t-shirt.",
type: "clothing"
}, {
name: "Game Hoodie",
price: 600,
desc: "Warm hoodie.",
type: "clothing"
}, {
name: "Game Art",
price: 1500,
desc: "Artistic game painting.",
type: "poster"
}, {
name: "Mouse Wristband",
price: 150,
desc: "Comfortable wristband.",
type: "accessory"
}, {
name: "Sticker Pack",
price: 100,
desc: "Pack of 10 stickers.",
type: "accessory"
},
// --- 5 new products added ---
{
name: "RGB LED Strip",
price: 450,
desc: "Colorful LED strip for your game room.",
type: "accessory"
}, {
name: "Mouse Stand",
price: 300,
desc: "Stylish mouse stand.",
type: "accessory"
}, {
name: "Game Notebook",
price: 200,
desc: "Game-themed notebook for taking notes.",
type: "stationery"
}, {
name: "Game Pen Set",
price: 120,
desc: "Set of 5 game-themed pens.",
type: "stationery"
}, {
name: "Game Puzzle",
price: 600,
desc: "500-piece game-themed puzzle.",
type: "game"
}];
// --- Fan Store Menu UI ---
var fanStoreMenu = new Container();
fanStoreMenu.visible = false;
game.addChild(fanStoreMenu);
var fanStoreTitle = new Text2('Fan Store', {
size: 60,
fill: 0xFFFFFF
});
fanStoreTitle.anchor.set(0.5, 0.5);
fanStoreTitle.x = 1024;
fanStoreTitle.y = 200;
fanStoreMenu.addChild(fanStoreTitle);
var fanStoreBackBtn = new Button();
fanStoreBackBtn.setLabel('Back');
fanStoreBackBtn.x = 1024;
fanStoreBackBtn.y = 2400;
fanStoreBackBtn.onClick = function () {
fanStoreMenu.visible = false;
mainMenu.visible = true;
};
fanStoreMenu.addChild(fanStoreBackBtn);
// Helper for showing the fan menu
function showFanMenu() {
mainMenu.visible = false;
fanMenu.visible = true;
// Remove old product cards/buttons
for (var i = fanMenu.children.length - 1; i >= 0; i--) {
var child = fanMenu.children[i];
if (child !== fanTitle && child !== fanBackBtn) {
child.destroy();
}
}
// Show all products in a grid: 2 columns per row
var yStart = 500;
var xStart = 700;
var xSpacing = 600;
var ySpacing = 300;
var cols = 2;
for (var i = 0; i < fanProducts.length; i++) {
var prod = fanProducts[i];
var container = new Container();
var col = i % cols;
var row = Math.floor(i / cols);
container.x = xStart + col * xSpacing;
container.y = yStart + row * ySpacing;
// Card background
var bg = LK.getAsset('card', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.2,
scaleY: 0.7
});
container.addChild(bg);
// Product name
var nameText = new Text2(prod.name, {
size: 40,
fill: 0xFFFFFF
});
nameText.anchor.set(0.5, 0.5);
nameText.y = -60;
container.addChild(nameText);
// Description
var descText = new Text2(prod.desc, {
size: 28,
fill: 0xFFC107
});
descText.anchor.set(0.5, 0.5);
descText.y = 0;
container.addChild(descText);
// Price
var priceText = new Text2('Price: $' + prod.price, {
size: 30,
fill: 0x4CAF50
});
priceText.anchor.set(0.5, 0.5);
priceText.y = 50;
container.addChild(priceText);
// Buy button
var buyBtn = new Button();
buyBtn.setLabel('Buy (+ ' + prod.fans + ' fan)');
buyBtn.x = 0;
buyBtn.y = 120;
buyBtn.onClick = function (prod) {
return function () {
if (gameState.money >= prod.price) {
gameState.money -= prod.price;
if (!gameState.fans) gameState.fans = 0;
gameState.fans += prod.fans;
updateUI();
LK.getSound('success').play();
showFanMenu();
}
};
}(prod);
container.addChild(buyBtn);
fanMenu.addChild(container);
}
// Show current fan count at top
if (fanMenu.fanCountText) fanMenu.fanCountText.destroy();
var fanCountText = new Text2('Total Fans: ' + (gameState.fans || 0), {
size: 45,
fill: 0x2196F3
});
fanCountText.anchor.set(0.5, 0.5);
fanCountText.x = 1024;
fanCountText.y = 400;
fanMenu.addChild(fanCountText);
fanMenu.fanCountText = fanCountText;
}
// Helper for showing the fan store menu
function showFanStoreMenu() {
mainMenu.visible = false;
fanStoreMenu.visible = true;
// Remove old product cards/buttons
for (var i = fanStoreMenu.children.length - 1; i >= 0; i--) {
var child = fanStoreMenu.children[i];
if (child !== fanStoreTitle && child !== fanStoreBackBtn) {
child.destroy();
}
}
// Show all products in a grid: 5 columns per row, 4 rows (ekrana sığacak şekilde %20 büyütülmüş ve hizalanmış)
// 20 ürün için 5x4 grid
var yStart = 550;
var xStart = 180;
var xSpacing = 385; // %20 büyütülmüş kartlar için aralık artırıldı
var ySpacing = 310; // %20 büyütülmüş kartlar için aralık artırıldı
var cols = 5;
for (var i = 0; i < fanStoreProducts.length; i++) {
var prod = fanStoreProducts[i];
var container = new Container();
var col = i % cols;
var row = Math.floor(i / cols);
container.x = xStart + col * xSpacing;
container.y = yStart + row * ySpacing;
// Card background
var bg = LK.getAsset('card', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.84,
// 0.7 * 1.2 = 0.84, %20 büyütme
scaleY: 0.6 // 0.5 * 1.2 = 0.6, %20 büyütme
});
container.addChild(bg);
// Product name
var nameText = new Text2(prod.name, {
size: 34,
fill: 0xFFFFFF
});
nameText.anchor.set(0.5, 0.5);
nameText.y = -45;
container.addChild(nameText);
// Description
var descText = new Text2(prod.desc, {
size: 22,
fill: 0xFFC107
});
descText.anchor.set(0.5, 0.5);
descText.y = 0;
container.addChild(descText);
// Price (Satış fiyatı: alış fiyatı + %10 kâr)
var salePrice = Math.round(prod.price * 1.1);
var priceText = new Text2('Sale Price: $' + salePrice + ' (Cost: $' + prod.price + ')', {
size: 24,
fill: 0x4CAF50
});
priceText.anchor.set(0.5, 0.5);
priceText.y = 38;
container.addChild(priceText);
// Buy button for Fan Store products
var buyBtn = new Button();
buyBtn.setLabel('Buy (for Fans)');
// Scale down by 30%
buyBtn.scaleX = 0.7;
buyBtn.scaleY = 0.7;
// Move button lower to visually separate from price
buyBtn.x = 0;
buyBtn.y = 120;
buyBtn.onClick = function (prod) {
return function () {
// Only allow if player has enough money AND at least 50 fans
if (gameState.money >= prod.price && (gameState.fans || 0) >= 50) {
gameState.money -= prod.price;
// Track owned count for each product
if (!prod.owned) prod.owned = 0;
prod.owned += 1;
// Deduct 50 fans per purchase
gameState.fans -= 50;
updateUI();
LK.getSound('success').play();
showFanStoreMenu();
}
};
}(prod);
container.addChild(buyBtn);
// Show owned count if any
if (prod.owned && prod.owned > 0) {
var ownedText = new Text2('Owned: ' + prod.owned, {
size: 22,
fill: 0x2196F3
});
ownedText.anchor.set(0.5, 0.5);
ownedText.y = 65;
container.addChild(ownedText);
}
fanStoreMenu.addChild(container);
}
// Show current fan count at top
if (fanStoreMenu.fanCountText) fanStoreMenu.fanCountText.destroy();
var fanCountText = new Text2('Total Fans: ' + (gameState.fans || 0), {
size: 45,
fill: 0x2196F3
});
fanCountText.anchor.set(0.5, 0.5);
fanCountText.x = 1024;
fanCountText.y = 400;
fanStoreMenu.addChild(fanCountText);
fanStoreMenu.fanCountText = fanCountText;
// --- Ava: Weekly Sales, Weekly Revenue, Total Products Sold ---
// Find last week's sales log
var lastLog = null;
if (gameState.fanStoreAutoSaleLog && gameState.fanStoreAutoSaleLog.length > 0) {
lastLog = gameState.fanStoreAutoSaleLog[gameState.fanStoreAutoSaleLog.length - 1];
}
var weeklySalesCount = 0;
var weeklyRevenue = 0;
var weeklyProductCount = 0;
if (lastLog) {
for (var i = 0; i < lastLog.sales.length; i++) {
weeklySalesCount += lastLog.sales[i].qty;
weeklyProductCount += 1;
}
weeklyRevenue = lastLog.totalRevenue;
}
// Info text about profit margin
if (fanStoreMenu.profitInfoText) fanStoreMenu.profitInfoText.destroy();
var profitInfoText = new Text2("Fan products are sold at 10% above purchase price (e.g. $500 product is sold for $550).", {
size: 30,
fill: 0x4CAF50,
align: "center"
});
profitInfoText.anchor.set(0.5, 1);
profitInfoText.x = 1024;
// Move 2 lines higher (assume 2x line height, ~64px per line for size 30)
profitInfoText.y = fanStoreBackBtn.y - 120 - 64 * 2;
fanStoreMenu.addChild(profitInfoText);
fanStoreMenu.profitInfoText = profitInfoText;
// Ava: Each product purchase costs 50 Fans.
if (fanStoreMenu.fanCostInfoText) fanStoreMenu.fanCostInfoText.destroy();
var fanCostInfoText = new Text2("Each product purchase costs 50 Fans.", {
size: 28,
fill: 0x4CAF50,
align: "center"
});
fanCostInfoText.anchor.set(0.5, 1);
fanCostInfoText.x = 1024;
fanCostInfoText.y = profitInfoText.y + 40;
fanStoreMenu.addChild(fanCostInfoText);
fanStoreMenu.fanCostInfoText = fanCostInfoText;
// Ava: Each product sale costs 100 Fans.
if (fanStoreMenu.fanSaleCostInfoText) fanStoreMenu.fanSaleCostInfoText.destroy();
var fanSaleCostInfoText = new Text2("Each product sale costs 100 Fans.", {
size: 28,
fill: 0x4CAF50,
align: "center"
});
fanSaleCostInfoText.anchor.set(0.5, 1);
fanSaleCostInfoText.x = 1024;
fanSaleCostInfoText.y = fanCostInfoText.y + 40;
fanStoreMenu.addChild(fanSaleCostInfoText);
fanStoreMenu.fanSaleCostInfoText = fanSaleCostInfoText;
// Calculate total number of products sold since the beginning
var totalProductSold = 0;
if (gameState.fanStoreAutoSaleLog && gameState.fanStoreAutoSaleLog.length > 0) {
for (var i = 0; i < gameState.fanStoreAutoSaleLog.length; i++) {
var log = gameState.fanStoreAutoSaleLog[i];
if (log && log.sales && log.sales.length > 0) {
for (var j = 0; j < log.sales.length; j++) {
totalProductSold += log.sales[j].qty;
}
}
}
}
// Compose info text
var weeklyInfoText = "Weekly Sales: " + weeklySalesCount + "\nWeekly Revenue: $" + weeklyRevenue + "\nTotal Products Sold: " + totalProductSold;
if (fanStoreMenu.weeklyInfoText) fanStoreMenu.weeklyInfoText.destroy();
var infoText = new Text2(weeklyInfoText, {
size: 32,
fill: 0xFFC107,
align: "center"
});
infoText.anchor.set(0.5, 1);
infoText.x = 1024;
infoText.y = fanStoreBackBtn.y - 60;
fanStoreMenu.addChild(infoText);
fanStoreMenu.weeklyInfoText = infoText;
}
// --- Fan Store: Günlük orantılı satış sistemi ---
// Her gün başında, mevcut fan sayısına orantılı olarak sahip olunan Store ürünlerinden satış yapılır
if (typeof gameState.fanStoreAutoSaleLog === "undefined") {
gameState.fanStoreAutoSaleLog = [];
}
// Yardımcı: Rastgele tamsayı [min, max]
function getRandomIntFanStore(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}
// Günlük fan store satış fonksiyonu
function processFanStoreDailySale() {
var totalFans = gameState.fans || 0;
if (totalFans < 1) return; // En az 1 fan olmalı
// Satış yapılacak toplam ürün adedi: her 100 fan için 1 satış, ancak 100'den az fan varsa da 1 satış yapılır
var saleCount = Math.floor(totalFans / 100);
if (saleCount < 1 && totalFans > 0) saleCount = 1;
// Satış için yeterli fan yoksa, satış yapılmaz
if (gameState.fans < 100) return;
// Satılabilir ürünler: sadece owned > 0 olanlar
var ownedProducts = fanStoreProducts.filter(function (prod) {
return prod.owned && prod.owned > 0;
});
if (ownedProducts.length === 0) return; // Satılacak ürün yoksa çık
// Satışları orantılı dağıt: fan sayısına göre, sahip olunan ürünlerden rastgele seçerek
var sales = [];
var totalRevenue = 0;
var fansBefore = gameState.fans;
var fansToLose = 0;
// Her ürün için, sahip olunan adede ve toplam fan sayısına göre satış miktarı belirle
// Her ürün için: (ürün owned / toplam owned) * saleCount kadar satış
var totalOwned = 0;
for (var i = 0; i < ownedProducts.length; i++) {
totalOwned += ownedProducts[i].owned;
}
// Her ürün için satış miktarını hesapla
var remainingSaleCount = saleCount;
for (var i = 0; i < ownedProducts.length; i++) {
var prod = ownedProducts[i];
// Oranla dağıt, en az 1 satılabilir
var prodSale = Math.floor(prod.owned / totalOwned * saleCount);
if (prodSale < 1 && remainingSaleCount > 0) prodSale = 1;
if (prodSale > prod.owned) prodSale = prod.owned;
if (prodSale > remainingSaleCount) prodSale = remainingSaleCount;
if (prodSale > 0) {
sales.push({
name: prod.name,
price: prod.price,
qty: prodSale
});
// Owned azalt
prod.owned -= prodSale;
// Kâr ekle (Satış fiyatı: alış fiyatı + %10 kâr)
// Satış fiyatı = alış fiyatı * 1.1, kâr = alış fiyatı * 0.1
var salePrice = Math.round(prod.price * 1.1);
totalRevenue += salePrice * prodSale;
// Fan kaybı: her satışta 100 fan kaybı, ancak toplu olarak gün sonunda uygula
fansToLose += prodSale * 100; // Her ürün satışı 100 fan maliyetindedir
remainingSaleCount -= prodSale;
}
if (remainingSaleCount <= 0) break;
}
// Eğer yeterli fan yoksa, satış miktarını azalt
if (fansToLose > gameState.fans) {
// Kaç ürün satılabilir?
var maxSales = Math.floor(gameState.fans / 100);
// Satışları yeniden dağıt
var totalReduced = 0;
for (var i = 0; i < sales.length; i++) {
if (totalReduced + sales[i].qty > maxSales) {
sales[i].qty = Math.max(0, maxSales - totalReduced);
}
totalReduced += sales[i].qty;
}
// Owned'ları tekrar güncelle (fazla azaltılmışsa geri ekle)
for (var i = 0; i < ownedProducts.length; i++) {
var prod = ownedProducts[i];
var sale = sales.find(function (s) {
return s.name === prod.name;
});
if (sale) {
var sold = sale.qty;
var originallyReduced = prod.owned + sold;
prod.owned += originallyReduced - sold;
}
}
// fansToLose'u güncelle
fansToLose = maxSales * 100;
// totalRevenue'u güncelle
totalRevenue = 0;
for (var i = 0; i < sales.length; i++) {
var salePrice = Math.round(sales[i].price * 1.1);
totalRevenue += salePrice * sales[i].qty;
}
}
// Para ekle
gameState.money += totalRevenue;
// Fan sayısını azalt: toplamda 100 fan/ürün, ancak en fazla mevcut fan kadar
var fansAfter = gameState.fans;
if (fansToLose > 0) {
if (fansToLose > gameState.fans) fansToLose = gameState.fans;
gameState.fans -= fansToLose;
fansAfter = gameState.fans;
}
// Satış kaydını logla
var logEntry = {
day: gameState.currentDay,
sales: sales,
totalRevenue: totalRevenue,
fansBefore: fansBefore,
fansAfter: fansAfter
};
gameState.fanStoreAutoSaleLog.push(logEntry);
// Bildirim gösterme (popup kaldırıldı)
updateUI();
}
// --- Her gün başında fan store satışını tetikle ---
// Günlük ilerleme kodunda çağrılacak, game.update içinde dayTimer >= 180 kısmında
// --- Platform Menu UI ---
var platformMenu = new Container();
platformMenu.visible = false;
game.addChild(platformMenu);
var platformTitle = new Text2('Platforms', {
size: 60,
fill: 0xFFFFFF
});
platformTitle.anchor.set(0.5, 0.5);
platformTitle.x = 1024;
platformTitle.y = 200;
platformMenu.addChild(platformTitle);
var platformBackBtn = new Button();
platformBackBtn.setLabel('Back');
platformBackBtn.x = 1024;
platformBackBtn.y = 2400;
platformBackBtn.onClick = function () {
platformMenu.visible = false;
mainMenu.visible = true;
};
platformMenu.addChild(platformBackBtn);
// --- Drag-to-scroll for platformMenu ---
var platformMenuDrag = {
dragging: false,
lastY: 0,
startY: 0,
startMenuY: 0,
minY: 0,
maxY: 0
};
// Calculate scroll bounds after platforms are rendered
function updatePlatformMenuScrollBounds() {
// Find min/max y for scrolling (platformMenu children)
var minY = 0,
maxY = 0;
for (var i = 0; i < platformMenu.children.length; i++) {
var child = platformMenu.children[i];
if (child !== platformTitle && child !== platformBackBtn) {
if (minY === 0 || child.y < minY) minY = child.y;
if (child.y > maxY) maxY = child.y;
}
}
// Allow scrolling so that last row is visible, but not too far up
platformMenuDrag.minY = Math.min(0, 800 - maxY);
platformMenuDrag.maxY = 0;
}
platformMenu.interactive = true;
platformMenu.down = function (x, y, obj) {
platformMenuDrag.dragging = true;
platformMenuDrag.lastY = y;
platformMenuDrag.startY = y;
platformMenuDrag.startMenuY = platformMenu.y || 0;
updatePlatformMenuScrollBounds();
};
platformMenu.move = function (x, y, obj) {
if (!platformMenuDrag.dragging) return;
var dy = y - platformMenuDrag.lastY;
var newY = (platformMenu.y || 0) + dy;
// Clamp scroll
if (newY < platformMenuDrag.minY) newY = platformMenuDrag.minY;
if (newY > platformMenuDrag.maxY) newY = platformMenuDrag.maxY;
platformMenu.y = newY;
platformMenuDrag.lastY = y;
};
platformMenu.up = function (x, y, obj) {
platformMenuDrag.dragging = false;
};
// --- Platform data (moved up to fix ReferenceError) ---
// Each platform gets a salesBonus: 0.02 * (index+1) for 2% more per platform
var platforms = [{
name: "PC",
year: 1981,
researched: true,
owned: true,
researchCost: 0,
price: 0
}, {
name: "Commodore 64",
year: 1982,
researched: false,
owned: false,
researchCost: 4000,
price: 4000
}, {
name: "NES",
year: 1983,
researched: false,
owned: false,
researchCost: 4000,
price: 4000
}, {
name: "Sega Master System",
year: 1985,
researched: false,
owned: false,
researchCost: 4000,
price: 4000
}, {
name: "Game Boy",
year: 1989,
researched: false,
owned: false,
researchCost: 4000,
price: 4000
}, {
name: "Super Nintendo",
year: 1990,
researched: false,
owned: false,
researchCost: 4000,
price: 4000
}, {
name: "Sega Genesis",
year: 1990,
researched: false,
owned: false,
researchCost: 4000,
price: 4000
}, {
name: "PlayStation",
year: 1994,
researched: true,
owned: true,
researchCost: 0,
price: 0
}, {
name: "Sega Saturn",
year: 1994,
researched: false,
owned: false,
researchCost: 4000,
price: 4000
}, {
name: "Nintendo 64",
year: 1996,
researched: false,
owned: false,
researchCost: 4000,
price: 4000
}, {
name: "Dreamcast",
year: 1998,
researched: false,
owned: false,
researchCost: 4000,
price: 4000
}, {
name: "PlayStation 2",
year: 2000,
researched: false,
owned: false,
researchCost: 4000,
price: 8000
}, {
name: "GameCube",
year: 2001,
researched: false,
owned: false,
researchCost: 8000,
price: 8000
}, {
name: "Xbox",
year: 2001,
researched: false,
owned: false,
researchCost: 8000,
price: 8000
}, {
name: "Game Boy Advance",
year: 2001,
researched: false,
owned: false,
researchCost: 8000,
price: 8000
}, {
name: "PlayStation Portable",
year: 2004,
researched: false,
owned: false,
researchCost: 8000,
price: 8000
}, {
name: "Nintendo DS",
year: 2004,
researched: false,
owned: false,
researchCost: 8000,
price: 8000
}, {
name: "Xbox 360",
year: 2005,
researched: false,
owned: false,
researchCost: 8000,
price: 8000
}, {
name: "Wii",
year: 2006,
researched: false,
owned: false,
researchCost: 8000,
price: 8000
}, {
name: "PlayStation 3",
year: 2006,
researched: false,
owned: false,
researchCost: 8000,
price: 8000
}, {
name: "PlayStation Vita",
year: 2011,
researched: false,
owned: false,
researchCost: 12000,
price: 12000
}, {
name: "Nintendo 3DS",
year: 2011,
researched: false,
owned: false,
researchCost: 12000,
price: 12000
}, {
name: "Wii U",
year: 2012,
researched: false,
owned: false,
researchCost: 12000,
price: 12000
}, {
name: "PlayStation 4",
year: 2013,
researched: false,
owned: false,
researchCost: 12000,
price: 12000
}, {
name: "Xbox One",
year: 2013,
researched: false,
owned: false,
researchCost: 12000,
price: 12000
}, {
name: "Nintendo Switch",
year: 2017,
researched: false,
owned: false,
researchCost: 16000,
price: 16000
}, {
name: "PlayStation 5",
year: 2020,
researched: false,
owned: false,
researchCost: 16000,
price: 16000
}, {
name: "Xbox Series X",
year: 2020,
researched: false,
owned: false,
researchCost: 16000,
price: 16000
}, {
name: "Steam Deck",
year: 2022,
researched: false,
owned: false,
researchCost: 16000,
price: 16000
}, {
name: "Mobile",
year: 2007,
researched: false,
owned: false,
researchCost: 8000,
price: 8000
}, {
name: "Ouya",
year: 2013,
researched: false,
owned: false,
researchCost: 4000,
price: 4000
}];
// Add salesBonus to each platform (2% per platform, starting from 2%)
for (var i = 0; i < platforms.length; i++) {
platforms[i].salesBonus = 0.02 * (i + 1);
}
// Sort platforms by year ascending
platforms.sort(function (a, b) {
return a.year - b.year;
});
// Helper for showing the platform menu
function showPlatformMenu() {
mainMenu.visible = false;
platformMenu.visible = true;
platformMenu.y = 0; // Reset scroll position on open
// Remove old platform cards/buttons
for (var i = platformMenu.children.length - 1; i >= 0; i--) {
var child = platformMenu.children[i];
if (child !== platformTitle && child !== platformBackBtn) {
child.destroy();
}
}
// Platform data
// Use the global, sorted platforms array
// Store platform state in gameState if not already
if (!gameState.platforms) {
gameState.platforms = {};
for (var i = 0; i < platforms.length; i++) {
var plat = platforms[i];
gameState.platforms[plat.name] = {
researched: plat.researched,
owned: plat.owned
};
}
gameState.selectedPlatform = "PC";
}
// Defensive: ensure all platforms in the list have an entry in gameState.platforms
for (var i = 0; i < platforms.length; i++) {
var plat = platforms[i];
if (!gameState.platforms[plat.name]) {
gameState.platforms[plat.name] = {
researched: plat.researched,
owned: plat.owned
};
}
}
// Show all platforms in a grid: 4 columns per row, 7 rows (ekrana sığacak şekilde 28 platform için)
var yStart = 500;
var xStart = 220; // leftmost card center (for 4 columns, more margin for 7 rows)
var xSpacing = 420; // horizontal distance between columns (wider for 4 columns)
var ySpacing = 220; // vertical spacing (keep as is)
var cols = 4;
for (var i = 0; i < platforms.length; i++) {
var plat = platforms[i];
var container = new Container();
var col = i % cols;
var row = Math.floor(i / cols);
container.x = xStart + col * xSpacing;
container.y = yStart + row * ySpacing;
// Card background
var bg = LK.getAsset('card', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.0,
scaleY: 0.35
});
container.addChild(bg);
// Platform name
var nameText = new Text2(plat.name, {
size: 35,
fill: 0xFFFFFF
});
nameText.anchor.set(0.5, 0.5);
nameText.y = -30;
container.addChild(nameText);
// Year
var yearText = new Text2('Year: ' + plat.year, {
size: 28,
fill: 0x4CAF50
});
yearText.anchor.set(0.5, 0.5);
yearText.y = 10;
container.addChild(yearText);
// Sales bonus
var bonusText = new Text2('Sales Bonus: +' + Math.round(plat.salesBonus * 100) + '%', {
size: 24,
fill: 0x2196F3
});
bonusText.anchor.set(0.5, 0.5);
bonusText.y = 40;
container.addChild(bonusText);
// Research or Buy button
var platState;
if (gameState.platforms && _typeof2(gameState.platforms) === "object") {
if (!gameState.platforms[plat.name]) {
gameState.platforms[plat.name] = {
researched: plat.researched,
owned: plat.owned
};
}
platState = gameState.platforms[plat.name];
} else {
platState = {
researched: plat.researched,
owned: plat.owned
};
}
if (!platState.owned) {
var buyBtn = new Button();
buyBtn.setLabel('Buy ($' + plat.price + ')');
buyBtn.x = 0;
buyBtn.y = 100;
buyBtn.onClick = function (plat, platState) {
return function () {
if (gameState.money >= plat.price) {
gameState.money -= plat.price;
// Find the correct platState again (by name) to avoid closure bug
if (gameState.platforms && gameState.platforms[plat.name]) {
gameState.platforms[plat.name].owned = true;
gameState.platforms[plat.name].researched = true; // Mark as researched on purchase
}
updateUI();
LK.getSound('success').play();
showPlatformMenu();
}
};
}(plat, platState);
container.addChild(buyBtn);
} else {
var ownedText = new Text2('Available', {
size: 28,
fill: 0xFFC107
});
ownedText.anchor.set(0.5, 0.5);
ownedText.y = 100;
container.addChild(ownedText);
// No select button for owned platforms
}
platformMenu.addChild(container);
}
// Update scroll bounds after all cards are added
updatePlatformMenuScrollBounds && updatePlatformMenuScrollBounds();
// Add info text at the bottom of the platformMenu
if (platformMenu.platformInfoText) {
platformMenu.platformInfoText.destroy();
}
var platformInfoText = new Text2('To use a platform, purchase it from the platform page in the main menu.', {
size: 32,
fill: 0xFFC107
});
platformInfoText.anchor.set(0.5, 0.5);
platformInfoText.x = 1024;
platformInfoText.y = 2500;
platformMenu.addChild(platformInfoText);
platformMenu.platformInfoText = platformInfoText;
}
// (Game Engine menu and related UI removed)
// --- Upgrade Button and Menu ---
var upgradeBtn = new Button();
upgradeBtn.setLabel('Yükselt');
upgradeBtn.x = 1024;
upgradeBtn.y = 1350;
upgradeBtn.onClick = showUpgradeMenu;
mainMenu.addChild(upgradeBtn);
var upgradeMenu = new Container();
upgradeMenu.visible = false;
game.addChild(upgradeMenu);
var upgradeTitle = new Text2('Studio Upgrades', {
size: 60,
fill: 0xFFFFFF
});
upgradeTitle.anchor.set(0.5, 0.5);
upgradeTitle.x = 1024;
upgradeTitle.y = 200;
upgradeMenu.addChild(upgradeTitle);
var studioLevelText = new Text2('', {
size: 40,
fill: 0xFFC107
});
studioLevelText.anchor.set(0.5, 0.5);
studioLevelText.x = 1024;
studioLevelText.y = 350;
upgradeMenu.addChild(studioLevelText);
var studioUpgradeCostText = new Text2('', {
size: 35,
fill: 0x4CAF50
});
studioUpgradeCostText.anchor.set(0.5, 0.5);
studioUpgradeCostText.x = 1024;
studioUpgradeCostText.y = 420;
upgradeMenu.addChild(studioUpgradeCostText);
var studioUpgradeBtn = new Button();
studioUpgradeBtn.setLabel('Stüdyo Seviyesini Yükselt');
studioUpgradeBtn.x = 1024;
studioUpgradeBtn.y = 500;
studioUpgradeBtn.onClick = function () {
if (gameState.money >= gameState.studioUpgradeCost) {
gameState.money -= gameState.studioUpgradeCost;
gameState.studioLevel += 1;
gameState.maxHireableDevelopers += 1;
gameState.studioUpgradeCost = Math.floor(gameState.studioUpgradeCost * 1.7);
updateUI();
showUpgradeMenu();
LK.getSound('success').play();
}
};
upgradeMenu.addChild(studioUpgradeBtn);
// --- Main Character Section ---
var mainCharTitle = new Text2('Main Character', {
size: 40,
fill: 0xFFFFFF
});
mainCharTitle.anchor.set(0.5, 0.5);
mainCharTitle.x = 1024;
mainCharTitle.y = 700;
upgradeMenu.addChild(mainCharTitle);
var mainCharLevelText = new Text2('', {
size: 35,
fill: 0xFFC107
});
mainCharLevelText.anchor.set(0.5, 0.5);
mainCharLevelText.x = 1024;
mainCharLevelText.y = 770;
upgradeMenu.addChild(mainCharLevelText);
var mainCharSkillText = new Text2('', {
size: 30,
fill: 0x2196F3
});
mainCharSkillText.anchor.set(0.5, 0.5);
mainCharSkillText.x = 1024;
mainCharSkillText.y = 820;
upgradeMenu.addChild(mainCharSkillText);
var mainCharUpgradeCostText = new Text2('', {
size: 30,
fill: 0x4CAF50
});
mainCharUpgradeCostText.anchor.set(0.5, 0.5);
mainCharUpgradeCostText.x = 1024;
mainCharUpgradeCostText.y = 870;
upgradeMenu.addChild(mainCharUpgradeCostText);
var mainCharUpgradeBtn = new Button();
mainCharUpgradeBtn.setLabel('Upgrade Main Character');
mainCharUpgradeBtn.x = 1024;
mainCharUpgradeBtn.y = 950;
mainCharUpgradeBtn.onClick = function () {
if (gameState.money >= gameState.mainCharacter.upgradeCost) {
gameState.money -= gameState.mainCharacter.upgradeCost;
gameState.mainCharacter.level += 1;
gameState.mainCharacter.skill += 1;
// Each level, increase all feature points by 1
gameState.mainCharacter.featurePoints.Graphics += 1;
gameState.mainCharacter.featurePoints.Sound += 1;
gameState.mainCharacter.featurePoints.Gameplay += 1;
gameState.mainCharacter.upgradeCost = Math.floor(gameState.mainCharacter.upgradeCost * 1.8);
updateUI();
showUpgradeMenu();
LK.getSound('success').play();
}
};
upgradeMenu.addChild(mainCharUpgradeBtn);
var backFromUpgradeBtn = new Button();
backFromUpgradeBtn.setLabel('Back');
backFromUpgradeBtn.x = 1024;
backFromUpgradeBtn.y = 2400;
backFromUpgradeBtn.onClick = function () {
upgradeMenu.visible = false;
mainMenu.visible = true;
};
upgradeMenu.addChild(backFromUpgradeBtn);
function showUpgradeMenu() {
mainMenu.visible = false;
upgradeMenu.visible = true;
studioLevelText.setText('Studio Level: ' + gameState.studioLevel);
studioUpgradeCostText.setText('Upgrade Cost: $' + gameState.studioUpgradeCost);
mainCharLevelText.setText('Main Character Level: ' + gameState.mainCharacter.level);
mainCharSkillText.setText('Each Feature Point: ' + 'Graphics: ' + gameState.mainCharacter.featurePoints.Graphics + ', Sound: ' + gameState.mainCharacter.featurePoints.Sound + ', Gameplay: ' + gameState.mainCharacter.featurePoints.Gameplay);
mainCharUpgradeCostText.setText('Upgrade Cost: $' + gameState.mainCharacter.upgradeCost);
}
// Research menu container
var researchMenu = new Container();
researchMenu.visible = false;
game.addChild(researchMenu);
var researchTitle = new Text2('Research Lab', {
size: 60,
fill: 0xFFFFFF
});
researchTitle.anchor.set(0.5, 0.5);
researchTitle.x = 1024;
researchTitle.y = 200;
researchMenu.addChild(researchTitle);
var researchBackBtn = new Button();
researchBackBtn.setLabel('Back');
researchBackBtn.x = 1024;
researchBackBtn.y = 2400;
researchBackBtn.onClick = function () {
researchMenu.visible = false;
mainMenu.visible = true;
};
researchMenu.addChild(researchBackBtn);
// Research category menu
var researchCategoryMenu = new Container();
researchCategoryMenu.visible = false;
game.addChild(researchCategoryMenu);
var categoryTitle = new Text2('', {
size: 60,
fill: 0xFFFFFF
});
categoryTitle.anchor.set(0.5, 0.5);
categoryTitle.x = 1024;
categoryTitle.y = 200;
researchCategoryMenu.addChild(categoryTitle);
var categoryBackBtn = new Button();
categoryBackBtn.setLabel('Back');
categoryBackBtn.x = 1024;
categoryBackBtn.y = 2400;
categoryBackBtn.onClick = function () {
researchCategoryMenu.visible = false;
researchMenu.visible = true;
};
researchCategoryMenu.addChild(categoryBackBtn);
// Name game menu container
var nameGameMenu = new Container();
nameGameMenu.visible = false;
game.addChild(nameGameMenu);
var nameGameTitle = new Text2('Name Your Game', {
size: 60,
fill: 0xFFFFFF
});
nameGameTitle.anchor.set(0.5, 0.5);
nameGameTitle.x = 1024;
nameGameTitle.y = 200;
nameGameMenu.addChild(nameGameTitle);
// --- Ava: Add a text input area for entering a custom game name ---
var gameNameInput = new Text2('', {
size: 50,
fill: 0x4CAF50
});
gameNameInput.anchor.set(0.5, 0.5);
gameNameInput.x = 1024;
gameNameInput.y = 400;
nameGameMenu.addChild(gameNameInput);
// Add a background for the input area
var inputBg = LK.getAsset('button', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2.2,
scaleY: 1.1
});
inputBg.x = 1024;
inputBg.y = 400;
inputBg.alpha = 0.25;
nameGameMenu.addChildAt(inputBg, nameGameMenu.children.indexOf(gameNameInput));
// --- Ava: Add a blinking cursor to indicate input ---
var cursor = new Text2('|', {
size: 50,
fill: 0x4CAF50
});
cursor.anchor.set(0, 0.5);
cursor.x = 0;
cursor.y = 0;
cursor.visible = false;
nameGameMenu.addChild(cursor);
// --- Ava: Show prompt below input area ---
var inputPrompt = new Text2('Tap the input area to enter a game name', {
size: 30,
fill: 0xFFFFFF
});
inputPrompt.anchor.set(0.5, 0.5);
inputPrompt.x = 1024;
inputPrompt.y = 500;
nameGameMenu.addChild(inputPrompt);
// --- Ava: Simple tap-to-edit for mobile/desktop ---
// Track input state
var isEditingGameName = false;
var inputBlinkTimer = 0;
// Helper to update the cursor position
function updateGameNameCursor() {
if (!isEditingGameName) {
cursor.visible = false;
return;
}
// Place cursor at end of text
var textWidth = gameNameInput.width || 0;
cursor.x = gameNameInput.x + textWidth / 2 + 8;
cursor.y = gameNameInput.y;
cursor.visible = true;
}
// Helper to start editing
function startEditingGameName() {
isEditingGameName = true;
inputPrompt.setText('Type your game name (max 24 chars)');
updateGameNameCursor();
cursor.visible = true;
inputBlinkTimer = 0;
}
// Helper to stop editing
function stopEditingGameName() {
isEditingGameName = false;
inputPrompt.setText('Tap the input area to enter a game name');
cursor.visible = false;
}
// --- Ava: Input area tap handler ---
inputBg.interactive = true;
inputBg.down = function () {
startEditingGameName();
LK.getSound('select').play();
};
// --- Ava: Simulate text input for mobile/desktop ---
// Listen for text input events using LK's input event system (cross-platform, sandbox-safe)
if (!game._avaGameNameInputListener) {
game._avaGameNameInputListener = function (e) {
if (!isEditingGameName) return;
var key = e && (e.key || e.data || '');
if (key === 'Enter' || key === 'Done') {
stopEditingGameName();
return;
}
if (key === 'Backspace') {
if (currentGameName.length > 0) {
currentGameName = currentGameName.slice(0, -1);
gameNameInput.setText(currentGameName);
updateGameNameCursor();
}
return;
}
// Only allow visible ASCII, max 24 chars
if (typeof key === 'string' && key.length === 1 && currentGameName.length < 24 && /^[\w\s\-!?.']$/.test(key)) {
currentGameName += key;
gameNameInput.setText(currentGameName);
updateGameNameCursor();
}
};
// Use LK's event system for input (works for both desktop and mobile)
LK.on('input', game._avaGameNameInputListener);
LK.on('keydown', game._avaGameNameInputListener);
}
// --- Ava: Blinking cursor animation in game.update ---
var _oldGameUpdateForInput = game.update;
game.update = function () {
if (_oldGameUpdateForInput) _oldGameUpdateForInput();
if (isEditingGameName) {
inputBlinkTimer++;
if (inputBlinkTimer % 60 < 30) {
cursor.visible = true;
} else {
cursor.visible = false;
}
updateGameNameCursor();
} else {
cursor.visible = false;
}
};
var randomNameBtn = new Button();
randomNameBtn.setLabel('Random Name');
randomNameBtn.x = 1024;
randomNameBtn.y = 700;
randomNameBtn.onClick = generateRandomName;
nameGameMenu.addChild(randomNameBtn);
var confirmNameBtn = new Button();
confirmNameBtn.setLabel('Confirm Name');
confirmNameBtn.x = 1024;
confirmNameBtn.y = 850;
confirmNameBtn.onClick = confirmGameName;
nameGameMenu.addChild(confirmNameBtn);
var backFromNameBtn = new Button();
backFromNameBtn.setLabel('Back');
backFromNameBtn.x = 1024;
backFromNameBtn.y = 1000;
backFromNameBtn.onClick = function () {
nameGameMenu.visible = false;
mainMenu.visible = true;
gameNameInput.setText('');
currentGameName = '';
};
nameGameMenu.addChild(backFromNameBtn);
// Simple tap-to-edit name input
var nameInputBg = LK.getAsset('button', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2,
scaleY: 1
});
nameInputBg.x = 1024;
nameInputBg.y = 400;
nameInputBg.alpha = 0.3;
nameGameMenu.addChild(nameInputBg);
nameInputBg.interactive = true;
nameInputBg.down = function () {
// Simulate simple text input with preset options
var names = ['Game Studio Pro', 'Developer Tycoon', 'Code Master', 'Pixel Dreams', 'Game Maker Plus'];
var randomIndex = Math.floor(Math.random() * names.length);
currentGameName = names[randomIndex];
gameNameInput.setText(currentGameName);
LK.getSound('select').play();
};
// Move gameNameInput to be on top
nameGameMenu.removeChild(gameNameInput);
nameGameMenu.addChild(gameNameInput);
// All games menu container
var allGamesMenu = new Container();
allGamesMenu.visible = false;
game.addChild(allGamesMenu);
var allGamesTitle = new Text2('All Released Games', {
size: 60,
fill: 0xFFFFFF
});
allGamesTitle.anchor.set(0.5, 0.5);
allGamesTitle.x = 1024;
allGamesTitle.y = 200;
allGamesMenu.addChild(allGamesTitle);
var noGamesText = new Text2('No games released yet', {
size: 40,
fill: 0xFFFFFF
});
noGamesText.anchor.set(0.5, 0.5);
noGamesText.x = 1024;
noGamesText.y = 600;
noGamesText.visible = false;
allGamesMenu.addChild(noGamesText);
var backFromAllGamesBtn = new Button();
backFromAllGamesBtn.setLabel('Back');
backFromAllGamesBtn.x = 1024;
backFromAllGamesBtn.y = 2400;
backFromAllGamesBtn.onClick = function () {
allGamesMenu.visible = false;
mainMenu.visible = true;
};
allGamesMenu.addChild(backFromAllGamesBtn);
// Game detail view container
var gameDetailView = new Container();
gameDetailView.visible = false;
game.addChild(gameDetailView);
var detailBackBtn = new Button();
detailBackBtn.setLabel('Back to Games List');
detailBackBtn.x = 1024;
detailBackBtn.y = 2400;
detailBackBtn.onClick = function () {
gameDetailView.visible = false;
allGamesMenu.visible = true;
};
gameDetailView.addChild(detailBackBtn);
// Hire menu container
var hireMenu = new Container();
hireMenu.visible = false;
game.addChild(hireMenu);
var hireTitle = new Text2('Hire Developer', {
size: 60,
fill: 0xFFFFFF
});
hireTitle.anchor.set(0.5, 0.5);
hireTitle.x = 1024;
hireTitle.y = 200;
hireMenu.addChild(hireTitle);
var backFromHireBtn = new Button();
backFromHireBtn.setLabel('Back');
backFromHireBtn.x = 1024;
backFromHireBtn.y = 2400;
backFromHireBtn.onClick = function () {
hireMenu.visible = false;
mainMenu.visible = true;
};
hireMenu.addChild(backFromHireBtn);
// Project menu container
var projectMenu = new Container();
projectMenu.visible = false;
game.addChild(projectMenu);
var projectTitle = new Text2('New Project', {
size: 60,
fill: 0xFFFFFF
});
projectTitle.anchor.set(0.5, 0.5);
projectTitle.x = 1024;
projectTitle.y = 200;
projectMenu.addChild(projectTitle);
var selectFeaturesText = new Text2('Özellikleri Seç:', {
size: 40,
fill: 0xFFFFFF
});
selectFeaturesText.anchor.set(0.5, 0.5);
selectFeaturesText.x = 1024;
selectFeaturesText.y = 300;
projectMenu.addChild(selectFeaturesText);
var startDevelopmentBtn = new Button();
startDevelopmentBtn.setLabel('Start Development');
startDevelopmentBtn.x = 1024;
startDevelopmentBtn.y = 2200;
startDevelopmentBtn.onClick = startDevelopment;
projectMenu.addChild(startDevelopmentBtn);
// Add Back button to New Project page
var backFromProjectBtn = new Button();
backFromProjectBtn.setLabel('Back');
backFromProjectBtn.x = 1024;
backFromProjectBtn.y = 2350;
backFromProjectBtn.onClick = function () {
projectMenu.visible = false;
mainMenu.visible = true;
selectedFeatures = [];
featureCards.forEach(function (card) {
card.setSelected(false);
});
selectedFeatureByCategory.Graphics = null;
selectedFeatureByCategory.Sound = null;
selectedFeatureByCategory.Gameplay = null;
projectMenu.selectedGenre = null;
// Restore persistent buttons if missing (for next open)
if (projectMenu.priceBtn && projectMenu.children.indexOf(projectMenu.priceBtn) === -1) {
projectMenu.addChild(projectMenu.priceBtn);
}
if (projectMenu.platformBtn && projectMenu.children.indexOf(projectMenu.platformBtn) === -1) {
projectMenu.addChild(projectMenu.platformBtn);
}
if (projectMenu.gameGenresResearchBtn && projectMenu.children.indexOf(projectMenu.gameGenresResearchBtn) === -1) {
projectMenu.addChild(projectMenu.gameGenresResearchBtn);
}
};
projectMenu.addChild(backFromProjectBtn);
// Feature category menu
var featureCategoryMenu = new Container();
featureCategoryMenu.visible = false;
game.addChild(featureCategoryMenu);
var categoryMenuTitle = new Text2('', {
size: 60,
fill: 0xFFFFFF
});
categoryMenuTitle.anchor.set(0.5, 0.5);
categoryMenuTitle.x = 1024;
categoryMenuTitle.y = 200;
featureCategoryMenu.addChild(categoryMenuTitle);
var selectedFeaturesText = new Text2('Selected: 0/5', {
size: 40,
fill: 0xFFFFFF
});
selectedFeaturesText.anchor.set(0.5, 0.5);
selectedFeaturesText.x = 1024;
selectedFeaturesText.y = 300;
featureCategoryMenu.addChild(selectedFeaturesText);
var categoryBackBtn = new Button();
categoryBackBtn.setLabel('Back to Categories');
categoryBackBtn.x = 1024;
categoryBackBtn.y = 2350;
categoryBackBtn.onClick = function () {
featureCategoryMenu.visible = false;
projectMenu.visible = true;
// Restore persistent buttons if missing
if (projectMenu.priceBtn && projectMenu.children.indexOf(projectMenu.priceBtn) === -1) {
projectMenu.addChild(projectMenu.priceBtn);
}
if (projectMenu.platformBtn && projectMenu.children.indexOf(projectMenu.platformBtn) === -1) {
projectMenu.addChild(projectMenu.platformBtn);
}
if (projectMenu.gameGenresResearchBtn && projectMenu.children.indexOf(projectMenu.gameGenresResearchBtn) === -1) {
projectMenu.addChild(projectMenu.gameGenresResearchBtn);
}
// Update total cost in project menu
var totalCost = 0;
selectedFeatures.forEach(function (f) {
totalCost += f.cost;
});
if (projectMenu.totalCostText) {
projectMenu.totalCostText.setText('Total Cost: $' + totalCost);
}
// Update selectedFeatureByCategory to first selected per category, but do not remove extra selections
['Graphics', 'Sound', 'Gameplay'].forEach(function (cat) {
var found = false;
for (var i = 0; i < selectedFeatures.length; i++) {
if (selectedFeatures[i].type === cat) {
if (!found) {
selectedFeatureByCategory[cat] = selectedFeatures[i];
found = true;
}
}
}
if (!found) selectedFeatureByCategory[cat] = null;
});
};
featureCategoryMenu.addChild(categoryBackBtn);
// --- Game Genres Research menu for projectMenu ---
var projectGenresResearchMenu = new Container();
projectGenresResearchMenu.visible = false;
game.addChild(projectGenresResearchMenu);
var projectGenresResearchTitle = new Text2('Game Genres Research', {
size: 60,
fill: 0xFFFFFF
});
projectGenresResearchTitle.anchor.set(0.5, 0.5);
projectGenresResearchTitle.x = 1024;
projectGenresResearchTitle.y = 200;
projectGenresResearchMenu.addChild(projectGenresResearchTitle);
var projectGenresResearchBackBtn = new Button();
projectGenresResearchBackBtn.setLabel('Back');
projectGenresResearchBackBtn.x = 1024;
projectGenresResearchBackBtn.y = 2400;
projectGenresResearchBackBtn.onClick = function () {
projectGenresResearchMenu.visible = false;
projectMenu.visible = true;
// Restore persistent buttons if missing
if (projectMenu.priceBtn && projectMenu.children.indexOf(projectMenu.priceBtn) === -1) {
projectMenu.addChild(projectMenu.priceBtn);
}
if (projectMenu.platformBtn && projectMenu.children.indexOf(projectMenu.platformBtn) === -1) {
projectMenu.addChild(projectMenu.platformBtn);
}
if (projectMenu.gameGenresResearchBtn && projectMenu.children.indexOf(projectMenu.gameGenresResearchBtn) === -1) {
projectMenu.addChild(projectMenu.gameGenresResearchBtn);
}
};
projectGenresResearchMenu.addChild(projectGenresResearchBackBtn);
function showProjectGenresResearchMenu() {
projectMenu.visible = false;
projectGenresResearchMenu.visible = true;
// Remove old genre buttons
for (var i = projectGenresResearchMenu.children.length - 1; i >= 0; i--) {
var child = projectGenresResearchMenu.children[i];
if (child !== projectGenresResearchTitle && child !== projectGenresResearchBackBtn) {
child.destroy();
}
}
// Show researched genres as selectable, and unresearched as buttons
var yStart = 400;
var researched = gameState.researchedFeatures.GameGenres;
gameGenres.forEach(function (genre, idx) {
if (!genre.requiresResearch || researched.indexOf(genre.name) !== -1) {
// Make researched genres selectable (only one can be selected)
var isSelected = projectMenu.selectedGenre && projectMenu.selectedGenre.name === genre.name;
var genreBtn = new Button();
genreBtn.setLabel(genre.name + (isSelected ? ' (Selected)' : ' (Researched)'));
genreBtn.x = 1024;
genreBtn.y = yStart + idx * 120;
if (isSelected) {
// Highlight selected genre
genreBtn.children[0].tint = 0xe94560;
}
genreBtn.onClick = function (g) {
return function () {
projectMenu.selectedGenre = g;
// Sync selected genre to gameState for persistence
gameState.selectedGenre = g;
LK.getSound('select').play();
if (projectMenu.genreText) {
projectMenu.genreText.setText('Selected Genre: ' + (projectMenu.selectedGenre ? projectMenu.selectedGenre.name : 'None'));
}
showProjectGenresResearchMenu();
};
}(genre);
projectGenresResearchMenu.addChild(genreBtn);
} else {
var btn = new Button();
btn.setLabel(genre.name + ' ($' + genre.researchCost + ')');
btn.x = 1024;
btn.y = yStart + idx * 120;
btn.onClick = function (g) {
return function () {
if (gameState.money >= g.researchCost && !gameState.currentResearch) {
gameState.money -= g.researchCost;
gameState.currentResearch = {
name: g.name,
category: 'GameGenres',
timeRemaining: 180
};
updateUI();
LK.getSound('select').play();
showProjectGenresResearchMenu();
}
};
}(genre);
projectGenresResearchMenu.addChild(btn);
}
});
}
// Development screen
var developmentScreen = new Container();
developmentScreen.visible = false;
game.addChild(developmentScreen);
var devTitle = new Text2('Developing Game', {
size: 60,
fill: 0xFFFFFF
});
devTitle.anchor.set(0.5, 0.5);
devTitle.x = 1024;
devTitle.y = 200;
developmentScreen.addChild(devTitle);
var targetScoreText = new Text2('Target Score: 100', {
size: 40,
fill: 0xFFFFFF
});
targetScoreText.anchor.set(0.5, 0.5);
targetScoreText.x = 1024;
targetScoreText.y = 400;
developmentScreen.addChild(targetScoreText);
var currentScoreText = new Text2('Current Score: 0', {
size: 40,
fill: 0x4CAF50
});
currentScoreText.anchor.set(0.5, 0.5);
currentScoreText.x = 1024;
currentScoreText.y = 500;
developmentScreen.addChild(currentScoreText);
var progressBarBg = LK.getAsset('progressBar', {
anchorX: 0.5,
anchorY: 0.5
});
progressBarBg.x = 1024;
progressBarBg.y = 700;
developmentScreen.addChild(progressBarBg);
var progressBarFill = LK.getAsset('progressFill', {
anchorX: 0,
anchorY: 0.5
});
progressBarFill.x = 624;
progressBarFill.y = 700;
progressBarFill.scaleX = 0;
developmentScreen.addChild(progressBarFill);
var releaseBtn = new Button();
releaseBtn.setLabel('Release Game!');
releaseBtn.x = 1024;
releaseBtn.y = 900;
releaseBtn.visible = false;
releaseBtn.onClick = releaseGame;
developmentScreen.addChild(releaseBtn);
// Market trends display
var trendsContainer = new Container();
trendsContainer.x = 1024;
trendsContainer.y = 1200;
developmentScreen.addChild(trendsContainer);
var trendsTitle = new Text2('Market Trends:', {
size: 35,
fill: 0xFF5722
});
trendsTitle.anchor.set(0.5, 0.5);
trendsContainer.addChild(trendsTitle);
// Arrays for UI elements
var developerCards = [];
var featureCards = [];
var selectedFeatures = [];
// Track selected feature per category for new project
var selectedFeatureByCategory = {
Graphics: null,
Sound: null,
Gameplay: null
};
// Functions
function updateUI() {
moneyText.setText('Money: $' + gameState.money);
developersText.setText('Developers: ' + gameState.developers.length);
gamesText.setText('Games Released: ' + gameState.completedGames);
// Sync gameState.currentDay with the dayText UI (top right Day ilerlemesi)
var dayFromUI = 1;
if (typeof dayText.text === "string") {
var match = dayText.text.match(/Day:\s*(\d+)/);
if (match && match[1]) {
dayFromUI = parseInt(match[1], 10);
if (!isNaN(dayFromUI)) {
gameState.currentDay = dayFromUI;
}
}
}
dayText.setText('Day: ' + gameState.currentDay);
// Fan UI
fanText.setText('Fan: ' + (gameState.fans || 0));
// Calculate fan bonus: 100000 fans = %100 bonus, scale linearly up to that point, max 100%
// Platform-specific: always use the selected platform's salesBonus
var fanBonus = 0;
var selectedPlatformObj = null;
if (gameState.selectedPlatform) {
for (var pi = 0; pi < platforms.length; pi++) {
if (platforms[pi].name === gameState.selectedPlatform) {
selectedPlatformObj = platforms[pi];
break;
}
}
}
if (gameState.fans && gameState.fans > 0) {
fanBonus = gameState.fans / 100000 * 100; // 100000 fan = %100 bonus
if (fanBonus > 100) fanBonus = 100;
}
var displayFanBonus = 0;
if (selectedPlatformObj && typeof selectedPlatformObj.salesBonus === "number") {
displayFanBonus = Math.round(fanBonus * selectedPlatformObj.salesBonus); // platforma göre çarp
} else {
displayFanBonus = Math.round(fanBonus);
}
fanBonusText.setText('Satış Bonusu: %' + displayFanBonus);
}
function showResearchMenu() {
mainMenu.visible = false;
researchMenu.visible = true;
// Clear existing buttons
for (var i = researchMenu.children.length - 1; i >= 0; i--) {
if (researchMenu.children[i] instanceof Button && researchMenu.children[i] !== researchBackBtn) {
researchMenu.children[i].destroy();
}
}
// Create category buttons
var categories = ['Graphics', 'Sound', 'Gameplay', 'GameGenres'];
categories.forEach(function (category, index) {
var btn = new Button();
var displayName = category === 'GameGenres' ? 'Game Genres' : category;
btn.setLabel(displayName + ' Research');
btn.x = 1024;
btn.y = 400 + index * 150;
btn.onClick = function () {
showResearchCategory(category);
};
researchMenu.addChild(btn);
});
}
function showResearchCategory(category) {
researchMenu.visible = false;
researchCategoryMenu.visible = true;
var displayName = category === 'GameGenres' ? 'Game Genres' : category;
categoryTitle.setText(displayName + ' Research');
// Clear existing items
for (var i = researchCategoryMenu.children.length - 1; i >= 0; i--) {
var child = researchCategoryMenu.children[i];
if (child !== categoryTitle && child !== categoryBackBtn) {
child.destroy();
}
}
// Get researchable items for this category
var items = [];
if (category === 'GameGenres') {
items = gameGenres.filter(function (genre) {
return genre.requiresResearch && gameState.researchedFeatures.GameGenres.indexOf(genre.name) === -1;
});
} else {
items = featurePool.filter(function (feature) {
return feature.type === category && feature.requiresResearch && gameState.researchedFeatures[category].indexOf(feature.name) === -1;
});
}
// Display research items
items.forEach(function (item, index) {
var container = new Container();
container.x = 1024;
container.y = 400 + index * 120;
var bg = LK.getAsset('card', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2,
scaleY: 0.4
});
container.addChild(bg);
var nameText = new Text2(item.name, {
size: 30,
fill: 0xFFFFFF
});
nameText.anchor.set(0.5, 0.5);
nameText.y = -20;
container.addChild(nameText);
var cost = category === 'GameGenres' ? item.researchCost : item.cost * 3;
var costText = new Text2('Research Cost: $' + cost, {
size: 25,
fill: 0x4CAF50
});
costText.anchor.set(0.5, 0.5);
costText.y = 20;
container.addChild(costText);
container.interactive = true;
container.down = function () {
if (gameState.money >= cost && !gameState.currentResearch) {
gameState.money -= cost;
gameState.currentResearch = {
name: item.name,
category: category,
timeRemaining: 180 // 3 seconds
};
updateUI();
LK.getSound('select').play();
showResearchCategory(category);
}
};
researchCategoryMenu.addChild(container);
});
// Add research option to increase selection limit for this category (if not already maxed)
if (category === 'Graphics' || category === 'Sound' || category === 'Gameplay') {
var maxLimit = 5;
var currentLimit = 1;
if (gameState.featureSelectionLimit && typeof gameState.featureSelectionLimit[category] === "number") {
currentLimit = gameState.featureSelectionLimit[category];
}
if (currentLimit < maxLimit) {
var y = 400 + items.length * 120 + 60;
var limitContainer = new Container();
limitContainer.x = 1024;
limitContainer.y = y;
var bg2 = LK.getAsset('card', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2,
scaleY: 0.4
});
limitContainer.addChild(bg2);
var limitText = new Text2('Seçim Limiti Artır: ' + category + ' (' + currentLimit + ' → ' + (currentLimit + 1) + ')', {
size: 30,
fill: 0xFFC107
});
limitText.anchor.set(0.5, 0.5);
limitText.y = -20;
limitContainer.addChild(limitText);
var limitCost = 8000 * currentLimit;
var limitCostText = new Text2('Araştırma Maliyeti: $' + limitCost, {
size: 25,
fill: 0x4CAF50
});
limitCostText.anchor.set(0.5, 0.5);
limitCostText.y = 20;
limitContainer.addChild(limitCostText);
limitContainer.interactive = true;
limitContainer.down = function () {
if (gameState.money >= limitCost && !gameState.currentResearch) {
gameState.money -= limitCost;
gameState.currentResearch = {
name: 'IncreaseLimit_' + category,
category: 'IncreaseLimit_' + category,
timeRemaining: 180
};
updateUI();
LK.getSound('select').play();
showResearchCategory(category);
}
};
researchCategoryMenu.addChild(limitContainer);
}
}
// Add a Back button specifically for Game Genres, Gameplay, Graphics, and Sound Research page
if (category === 'GameGenres' || category === 'Gameplay' || category === 'Graphics' || category === 'Sound') {
// Remove previous genre/gameplay/graphics/sound back button if any
if (researchCategoryMenu.genreBackBtn) {
researchCategoryMenu.removeChild(researchCategoryMenu.genreBackBtn);
researchCategoryMenu.genreBackBtn.destroy();
researchCategoryMenu.genreBackBtn = null;
}
var genreBackBtn = new Button();
genreBackBtn.setLabel('Back');
genreBackBtn.x = 1024;
genreBackBtn.y = 2400;
genreBackBtn.onClick = function () {
researchCategoryMenu.visible = false;
researchMenu.visible = true;
updateGlobalBackBtn && updateGlobalBackBtn();
};
researchCategoryMenu.addChild(genreBackBtn);
researchCategoryMenu.genreBackBtn = genreBackBtn;
}
// Show current research if any
if (gameState.currentResearch) {
var researchInfo = new Text2('Currently researching: ' + gameState.currentResearch.name, {
size: 35,
fill: 0xFFC107
});
researchInfo.anchor.set(0.5, 0.5);
researchInfo.x = 1024;
researchInfo.y = 300;
researchCategoryMenu.addChild(researchInfo);
}
}
function showNameGameMenu() {
mainMenu.visible = false;
nameGameMenu.visible = true;
currentGameName = '';
gameNameInput.setText('');
}
function generateRandomName() {
var prefixes = ['Super', 'Mega', 'Ultra', 'Epic', 'Legendary', 'Amazing', 'Incredible', 'Fantastic'];
var genres = ['Adventure', 'Quest', 'Battle', 'World', 'Kingdom', 'Legend', 'Saga', 'Chronicles'];
var suffixes = ['2000', 'X', 'Plus', 'HD', 'Remastered', 'Ultimate', 'Deluxe', 'Pro'];
var name = prefixes[Math.floor(Math.random() * prefixes.length)] + ' ' + genres[Math.floor(Math.random() * genres.length)] + ' ' + suffixes[Math.floor(Math.random() * suffixes.length)];
currentGameName = name;
gameNameInput.setText(name);
LK.getSound('select').play();
}
function confirmGameName() {
if (currentGameName && currentGameName.length > 0) {
// Store the game name for later use
nameGameMenu.visible = false;
// If projectMenu is hidden, show it again (for project flow)
if (!mainMenu.visible && projectMenu) {
projectMenu.visible = true;
} else {
mainMenu.visible = true;
}
LK.getSound('success').play();
// Update game name display
gameNameDisplay.setText('Next Game: ' + currentGameName);
// Show confirmation message
var confirmText = new Text2('Next game will be: ' + currentGameName, {
size: 30,
fill: 0x4CAF50
});
confirmText.anchor.set(0.5, 0.5);
confirmText.x = 1024;
confirmText.y = 1050;
confirmText.alpha = 0;
mainMenu.addChild(confirmText);
tween(confirmText, {
alpha: 1
}, {
duration: 500,
onFinish: function onFinish() {
LK.setTimeout(function () {
tween(confirmText, {
alpha: 0
}, {
duration: 500,
onFinish: function onFinish() {
confirmText.destroy();
}
});
}, 2000);
}
});
}
}
function showAllGamesMenu() {
mainMenu.visible = false;
allGamesMenu.visible = true;
// Clear existing game cards
var cardsToRemove = [];
allGamesMenu.children.forEach(function (child) {
if (child instanceof GameHistoryCard) {
cardsToRemove.push(child);
}
});
cardsToRemove.forEach(function (card) {
card.destroy();
});
// Show all games (both active and completed)
var allGames = gameState.releasedGames.concat(gameState.gameHistory);
if (allGames.length === 0) {
noGamesText.visible = true;
} else {
noGamesText.visible = false;
allGames.forEach(function (game, index) {
var card = new GameHistoryCard();
card.setGameData(game);
card.x = 1024;
card.y = 400 + index * 150;
card.onClick = showGameDetail;
allGamesMenu.addChild(card);
});
}
}
function showGameDetail(gameData) {
allGamesMenu.visible = false;
gameDetailView.visible = true;
// Clear previous content
for (var i = gameDetailView.children.length - 1; i >= 0; i--) {
if (gameDetailView.children[i] !== detailBackBtn) {
gameDetailView.children[i].destroy();
}
}
// Game title
var titleText = new Text2(gameData.name, {
size: 60,
fill: 0xFFFFFF
});
titleText.anchor.set(0.5, 0.5);
titleText.x = 1024;
titleText.y = 200;
gameDetailView.addChild(titleText);
// Release info
var releaseText = new Text2('Released on Day ' + gameData.releaseDay, {
size: 35,
fill: 0x2196F3
});
releaseText.anchor.set(0.5, 0.5);
releaseText.x = 1024;
releaseText.y = 300;
gameDetailView.addChild(releaseText);
// Sales info
var salesStatus = gameData.currentDailySales > 0 ? 'Active' : 'Ended';
var salesText = new Text2('Total Sales: ' + gameData.totalSales + ' copies (' + salesStatus + ')', {
size: 35,
fill: 0x4CAF50
});
salesText.anchor.set(0.5, 0.5);
salesText.x = 1024;
salesText.y = 380;
gameDetailView.addChild(salesText);
// Show total earned money (use actual price and revenue formula)
var pricePerCopy = typeof gameData.price === "number" ? gameData.price : 1;
var totalMoneyEarned = Math.floor((gameData.totalSales || 0) * pricePerCopy);
var moneyText = new Text2('Total Money Earned: $' + totalMoneyEarned, {
size: 32,
fill: 0xFFC107
});
moneyText.anchor.set(0.5, 0.5);
moneyText.x = 1024;
moneyText.y = 420;
gameDetailView.addChild(moneyText);
// Score info
var scoreText = new Text2('Score: ' + Math.floor(gameData.score) + ' / ' + gameData.targetScore, {
size: 35,
fill: 0xFFC107
});
scoreText.anchor.set(0.5, 0.5);
scoreText.x = 1024;
scoreText.y = 460;
gameDetailView.addChild(scoreText);
// Show price per copy
if (typeof gameData.price === "number") {
var priceText = new Text2('Oyun Fiyatı: $' + gameData.price, {
size: 32,
fill: 0xFFC107
});
priceText.anchor.set(0.5, 0.5);
priceText.x = 1024;
priceText.y = 500;
gameDetailView.addChild(priceText);
}
// Genre info
if (gameData.genre) {
var genreText = new Text2('Genre: ' + gameData.genre.name, {
size: 35,
fill: 0x9C27B0
});
genreText.anchor.set(0.5, 0.5);
genreText.x = 1024;
genreText.y = 540;
gameDetailView.addChild(genreText);
}
// Features title
var featuresTitle = new Text2('Features Used:', {
size: 40,
fill: 0xFFFFFF
});
featuresTitle.anchor.set(0.5, 0.5);
featuresTitle.x = 1024;
featuresTitle.y = 600;
gameDetailView.addChild(featuresTitle);
// Display features
gameData.features.forEach(function (feature, index) {
var featureText = new Text2('• ' + feature.name + ' (' + feature.type + ')', {
size: 30,
fill: 0x2196F3
});
featureText.anchor.set(0.5, 0.5);
featureText.x = 1024;
featureText.y = 680 + index * 40;
gameDetailView.addChild(featureText);
});
// Developers title
var devsTitle = new Text2('Developed by:', {
size: 40,
fill: 0xFFFFFF
});
devsTitle.anchor.set(0.5, 0.5);
devsTitle.x = 1024;
devsTitle.y = 1000;
gameDetailView.addChild(devsTitle);
// Display developers if stored
if (gameData.developers) {
gameData.developers.forEach(function (dev, index) {
var devText = new Text2('• ' + dev.name + ' (' + dev.specialty + ', Skill: ' + dev.skill + ')', {
size: 30,
fill: 0xFFC107
});
devText.anchor.set(0.5, 0.5);
devText.x = 1024;
devText.y = 1080 + index * 40;
gameDetailView.addChild(devText);
});
}
// Show reviews if present
if (gameData.reviews && gameData.reviews.length > 0) {
var reviewsTitle = new Text2('Reviews:', {
size: 40,
fill: 0xFFFFFF
});
reviewsTitle.anchor.set(0.5, 0.5);
reviewsTitle.x = 1024;
reviewsTitle.y = 1400;
gameDetailView.addChild(reviewsTitle);
// Show average review score
var avgScore = 0;
for (var i = 0; i < gameData.reviews.length; i++) {
avgScore += gameData.reviews[i].score;
}
avgScore = Math.round(avgScore / gameData.reviews.length);
var avgScoreText = new Text2('Average Score: ' + avgScore + '/100', {
size: 35,
fill: avgScore >= 80 ? 0x4CAF50 : avgScore >= 60 ? 0xFFC107 : 0xE94560
});
avgScoreText.anchor.set(0.5, 0.5);
avgScoreText.x = 1024;
avgScoreText.y = 1460;
gameDetailView.addChild(avgScoreText);
// Show up to 10 reviews
gameData.reviews.forEach(function (review, idx) {
var reviewText = new Text2(review.company + ": " + review.score + "/100 - " + review.text, {
size: 28,
fill: 0xFFFFFF
});
reviewText.anchor.set(0.5, 0.5);
reviewText.x = 1024;
reviewText.y = 1540 + idx * 60;
gameDetailView.addChild(reviewText);
});
}
}
function showHireMenu() {
mainMenu.visible = false;
hireMenu.visible = true;
// Clear existing cards
developerCards.forEach(function (card) {
card.destroy();
});
developerCards = [];
// Show available developers info
var infoText = new Text2('Available Developers: ' + gameState.maxHireableDevelopers, {
size: 35,
fill: 0xFFC107
});
infoText.anchor.set(0.5, 0.5);
infoText.x = 1024;
infoText.y = 350;
hireMenu.addChild(infoText);
// Show main character as always hired
var mainCharCard = new DeveloperCard();
mainCharCard.setDeveloper({
name: gameState.mainCharacter.name,
specialty: "All",
skill: gameState.mainCharacter.skill,
cost: 0
});
mainCharCard.x = 1024;
mainCharCard.y = 600;
mainCharCard.developerData = {
name: gameState.mainCharacter.name,
specialty: "All",
skill: gameState.mainCharacter.skill,
cost: 0
};
mainCharCard.down = function () {};
hireMenu.addChild(mainCharCard);
developerCards.push(mainCharCard);
// Create developer cards as a grid, restrict hiring to studio level
var availableDevelopers = developerPool.filter(function (dev) {
return !gameState.developers.some(function (hired) {
return hired.name === dev.name;
});
});
// Only allow hiring up to maxHireableDevelopers (studioLevel+1, including main character)
var canHireCount = gameState.maxHireableDevelopers - gameState.developers.length;
if (canHireCount < 0) canHireCount = 0;
// Arrange developer cards in a grid (3 per row)
var cardsPerRow = 3;
var cardSpacingX = 400;
var cardSpacingY = 500;
var startX = 1024 - cardSpacingX;
var startY = 1000;
availableDevelopers.forEach(function (dev, index) {
var card = new DeveloperCard();
card.setDeveloper(dev);
var col = index % cardsPerRow;
var row = Math.floor(index / cardsPerRow);
card.x = startX + col * cardSpacingX;
card.y = startY + row * cardSpacingY;
// If we can't hire more, gray out the card and disable click
if (index >= canHireCount) {
card.alpha = 0.4;
card.down = function () {
// Optionally show a message or play a sound
LK.getSound('select').play();
};
// Show a message overlay
var lockText = new Text2('Stüdyo seviyesini yükseltmelisin', {
size: 28,
fill: 0xE94560
});
lockText.anchor.set(0.5, 0.5);
lockText.y = 160;
card.addChild(lockText);
} else {
card.onClick = function (developer) {
if (gameState.money >= developer.cost) {
gameState.money -= developer.cost;
gameState.developers.push({
name: developer.name,
specialty: developer.specialty,
skill: developer.skill,
cost: developer.cost,
assignedFeature: null // Only 1 feature can be assigned
});
updateUI();
LK.getSound('hire').play();
showHireMenu(); // Refresh menu
}
};
}
hireMenu.addChild(card);
developerCards.push(card);
});
}
function showFeatureCategory(category) {
projectMenu.visible = false;
featureCategoryMenu.visible = true;
categoryMenuTitle.setText(category + ' Features');
selectedFeaturesText.setText('Selected: ' + selectedFeatures.length);
// Clear existing feature cards
for (var i = featureCategoryMenu.children.length - 1; i >= 0; i--) {
var child = featureCategoryMenu.children[i];
if (child instanceof FeatureCard) {
child.destroy();
}
}
// Get available features for this category
var availableFeatures = featurePool.filter(function (feature) {
return feature.type === category && (!feature.requiresResearch || gameState.researchedFeatures[feature.type].indexOf(feature.name) !== -1);
});
// Create feature cards
availableFeatures.forEach(function (feature, index) {
var card = new FeatureCard();
card.setFeature(feature);
card.x = 400 + index % 4 * 250;
card.y = 500 + Math.floor(index / 4) * 350;
// Set selected state if already selected
var isSelected = selectedFeatures.some(function (f) {
return f.name === feature.name;
});
card.setSelected(isSelected);
// Highlight trending features
if (gameState.marketTrends.indexOf(feature.type) !== -1) {
var trendIcon = LK.getAsset('trendIcon', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.3,
scaleY: 0.3
});
trendIcon.x = 100;
trendIcon.y = -100;
card.addChild(trendIcon);
}
card.onClick = function (clickedCard) {
var cat = category;
// Determine max selection for this category
var maxPerCategory = 1;
if (gameState.featureSelectionLimit && typeof gameState.featureSelectionLimit[cat] === "number") {
maxPerCategory = gameState.featureSelectionLimit[cat];
}
// Count how many are already selected in this category
var selectedInCategory = selectedFeatures.filter(function (f) {
return f.type === cat;
}).length;
// If already selected, deselect
if (clickedCard.selected) {
clickedCard.setSelected(false);
selectedFeatures = selectedFeatures.filter(function (f) {
return f !== clickedCard.featureData;
});
// If this was the only selected in category, clear selectedFeatureByCategory
if (selectedFeatureByCategory[cat] && selectedFeatureByCategory[cat].name === clickedCard.featureData.name) {
selectedFeatureByCategory[cat] = null;
}
} else {
// Only allow up to maxPerCategory selections per category
if (selectedInCategory >= maxPerCategory) {
// Show notification
var notification = new Container();
game.addChild(notification);
var bg = LK.getAsset('card', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2,
scaleY: 0.6
});
bg.tint = 0xE94560;
notification.addChild(bg);
var text = new Text2('Bu kategoriden en fazla ' + maxPerCategory + ' özellik seçebilirsin!', {
size: 35,
fill: 0xFFFFFF
});
text.anchor.set(0.5, 0.5);
notification.addChild(text);
notification.x = 1024;
notification.y = 600;
notification.alpha = 0;
tween(notification, {
alpha: 1
}, {
duration: 500,
onFinish: function onFinish() {
LK.setTimeout(function () {
tween(notification, {
alpha: 0
}, {
duration: 500,
onFinish: function onFinish() {
notification.destroy();
}
});
}, 2000);
}
});
return;
}
clickedCard.setSelected(true);
selectedFeatures.push(clickedCard.featureData);
selectedFeatureByCategory[cat] = clickedCard.featureData;
LK.getSound('select').play();
}
// Update selected count
selectedFeaturesText.setText('Selected: ' + selectedFeatures.length);
};
featureCategoryMenu.addChild(card);
});
}
function showProjectMenu() {
// Allow project creation if there is at least one developer OR the main character (always present)
if (gameState.developers.length === 0 && !gameState.mainCharacter) {
return;
}
mainMenu.visible = false;
projectMenu.visible = true;
selectedFeatures = [];
// Reset per-category selection
selectedFeatureByCategory.Graphics = null;
selectedFeatureByCategory.Sound = null;
selectedFeatureByCategory.Gameplay = null;
// Clear existing cards
featureCards.forEach(function (card) {
card.destroy();
});
featureCards = [];
// Clear any existing category buttons, but do NOT destroy persistent buttons (priceBtn, platformBtn, gameGenresResearchBtn, startDevelopmentBtn, backFromProjectBtn)
for (var i = projectMenu.children.length - 1; i >= 0; i--) {
var child = projectMenu.children[i];
// Only destroy category feature buttons (those not persistent)
if (child instanceof Button && child !== startDevelopmentBtn && child !== backFromProjectBtn && child !== projectMenu.priceBtn && child !== projectMenu.platformBtn && child !== projectMenu.gameGenresResearchBtn) {
child.destroy();
}
}
// Restore selected genre from gameState if available
if (gameState.selectedGenre) {
projectMenu.selectedGenre = gameState.selectedGenre;
} else {
projectMenu.selectedGenre = null;
gameState.selectedGenre = null;
}
// Update selected genre text
if (projectMenu.genreText) {
projectMenu.genreText.setText('Selected Genre: ' + (projectMenu.selectedGenre ? projectMenu.selectedGenre.name : 'None'));
}
// Persist marketTrends for the duration of a project (until game is released)
// Only generate new trends if there are no trends yet (i.e., at the start of a new project, not just on menu open)
if (!gameState.marketTrends || !Array.isArray(gameState.marketTrends) || gameState.marketTrends.length === 0) {
gameState.marketTrends = [];
var trendTypes = ['Graphics', 'Sound', 'Gameplay'];
var availableGenres = gameGenres.filter(function (genre) {
return !genre.requiresResearch || gameState.researchedFeatures.GameGenres.indexOf(genre.name) !== -1;
});
// Only allow market trends from researched genres
var researchedGenres = gameGenres.filter(function (genre) {
return !genre.requiresResearch || gameState.researchedFeatures.GameGenres.indexOf(genre.name) !== -1;
});
var trend = trendTypes[Math.floor(Math.random() * trendTypes.length)];
gameState.marketTrends.push(trend);
// Only pick genre trends from researched genres
if (researchedGenres.length > 0) {
var genreTrend = researchedGenres[Math.floor(Math.random() * researchedGenres.length)];
gameState.marketTrends.push(genreTrend.name + ' games');
}
}
// --- Ava: Destroy old Market Trends and Total Cost text to prevent duplicates ---
if (projectMenu.trendsText) {
projectMenu.trendsText.destroy();
projectMenu.trendsText = null;
}
if (projectMenu.totalCostText) {
projectMenu.totalCostText.destroy();
projectMenu.totalCostText = null;
}
// Display trends at top
var trendsText = new Text2('Market Trends: ' + gameState.marketTrends.join(' & ') + ' are hot!', {
size: 35,
fill: 0xFF5722
});
trendsText.anchor.set(0.5, 0.5);
trendsText.x = 1024;
trendsText.y = 400;
projectMenu.addChild(trendsText);
projectMenu.trendsText = trendsText;
// --- Ava: Show sales bonus summary for selected features ---
if (projectMenu.featureBonusText) {
projectMenu.featureBonusText.destroy();
}
var featureBonusSummary = '';
(function () {
// Calculate bonuses for selected features
var bonusParts = [];
// Platform bonus
var selectedPlatformName = gameState.selectedPlatform || "PC";
var selectedPlatformObj = null;
for (var i = 0; i < platforms.length; i++) {
if (platforms[i].name === selectedPlatformName) {
selectedPlatformObj = platforms[i];
break;
}
}
if (selectedPlatformObj && selectedPlatformObj.salesBonus) {
bonusParts.push('Platform: +' + Math.round(selectedPlatformObj.salesBonus * 100) + '% satış');
}
// Genre bonus
if (projectMenu.selectedGenre) {
var genreObj = null;
for (var i = 0; i < gameGenres.length; i++) {
if (gameGenres[i].name === projectMenu.selectedGenre.name) {
genreObj = gameGenres[i];
break;
}
}
if (genreObj && genreObj.baseMultiplier && genreObj.baseMultiplier > 1) {
bonusParts.push('Tür: +' + Math.round((genreObj.baseMultiplier - 1) * 100) + '% satış');
}
}
// Feature trend bonus
var trendTypes = [];
if (gameState.marketTrends && Array.isArray(gameState.marketTrends)) {
for (var i = 0; i < gameState.marketTrends.length; i++) {
if (gameState.marketTrends[i] === "Graphics" || gameState.marketTrends[i] === "Sound" || gameState.marketTrends[i] === "Gameplay") {
trendTypes.push(gameState.marketTrends[i]);
}
}
}
var trendBonus = 0;
if (trendTypes.length > 0 && selectedFeatures && selectedFeatures.length > 0) {
for (var i = 0; i < selectedFeatures.length; i++) {
if (trendTypes.indexOf(selectedFeatures[i].type) !== -1) {
trendBonus = 50;
break;
}
}
if (trendBonus > 0) {
bonusParts.push('Trend Özellik: +50% satış');
}
}
// Genre trend bonus
if (projectMenu.selectedGenre && gameState.marketTrends && Array.isArray(gameState.marketTrends)) {
for (var i = 0; i < gameState.marketTrends.length; i++) {
if (typeof gameState.marketTrends[i] === "string" && gameState.marketTrends[i].indexOf(projectMenu.selectedGenre.name) !== -1) {
bonusParts.push('Trend Tür: +30% satış');
break;
}
}
}
// Fan bonus (platform-specific)
var fanBonus = 0;
var selectedPlatformObj = null;
if (gameState.selectedPlatform) {
for (var pi = 0; pi < platforms.length; pi++) {
if (platforms[pi].name === gameState.selectedPlatform) {
selectedPlatformObj = platforms[pi];
break;
}
}
}
if (gameState.fans && gameState.fans > 0) {
fanBonus = gameState.fans / 100000 * 100;
if (fanBonus > 100) fanBonus = 100;
if (fanBonus > 0) {
if (selectedPlatformObj && typeof selectedPlatformObj.salesBonus === "number") {
var platformFanBonus = Math.round(fanBonus * selectedPlatformObj.salesBonus);
bonusParts.push('Fan: +' + platformFanBonus + '% satış (platforma göre)');
} else {
bonusParts.push('Fan: +' + Math.round(fanBonus) + '% satış');
}
}
}
// Compose summary
if (bonusParts.length > 0) {
featureBonusSummary = 'Satış Bonusları: ' + bonusParts.join(', ');
} else {
featureBonusSummary = 'Satış bonusu yok.';
}
})();
// Satış Bonusları: yazısını 2 satır olacak şekilde ayarla ve hizala
var featureBonusLines = [];
if (featureBonusSummary.length > 40) {
// Satış bonusu metni uzunsa, virgülden bölerek iki satıra ayır
var parts = featureBonusSummary.split(':');
if (parts.length > 1) {
var bonuses = parts[1].split(',');
var mid = Math.ceil(bonuses.length / 2);
var firstLine = (parts[0] + ':' + bonuses.slice(0, mid).join(',')).trim();
var secondLine = bonuses.slice(mid).join(',').trim();
featureBonusLines = [firstLine, secondLine];
} else {
featureBonusLines = [featureBonusSummary, ''];
}
} else {
featureBonusLines = [featureBonusSummary, ''];
}
var featureBonusText = new Text2(featureBonusLines[0] + (featureBonusLines[1] ? '\n' + featureBonusLines[1] : ''), {
size: 32,
fill: 0x4CAF50,
align: "center"
});
featureBonusText.anchor.set(0.5, 0.5);
featureBonusText.x = 1024;
featureBonusText.y = 360;
projectMenu.addChild(featureBonusText);
projectMenu.featureBonusText = featureBonusText;
// --- Satış Bonusları kutusunun altındaki butonları aşağı kaydır (hizalama) ---
var buttonY = 650 + 240; // Move all buttons 2 rows (240px) down
if (featureBonusText.height > 40) {
buttonY += 30; // 2 satır ise biraz daha aşağı kaydır
}
var buttonSpacing = 120;
// Feature category buttons
var categories = ['Graphics', 'Sound', 'Gameplay'];
categories.forEach(function (category, index) {
var categoryBtn = new Button();
categoryBtn.setLabel(category + ' Features');
categoryBtn.x = 1024;
categoryBtn.y = buttonY;
categoryBtn.onClick = function () {
showFeatureCategory(category);
};
projectMenu.addChild(categoryBtn);
buttonY += buttonSpacing;
});
// Oyun Fiyatı button (move to next row)
if (projectMenu.priceBtn) {
// If not already present, re-add to projectMenu
if (projectMenu.children.indexOf(projectMenu.priceBtn) === -1) {
projectMenu.addChild(projectMenu.priceBtn);
}
projectMenu.priceBtn.y = buttonY;
buttonY += buttonSpacing;
}
// Game Genres Research button (move to next row)
if (!projectMenu.gameGenresResearchBtn) {
var gameGenresResearchBtn = new Button();
gameGenresResearchBtn.setLabel('Game Genres Research');
gameGenresResearchBtn.x = 1024;
gameGenresResearchBtn.y = buttonY;
gameGenresResearchBtn.onClick = function () {
showProjectGenresResearchMenu();
};
projectMenu.addChild(gameGenresResearchBtn);
projectMenu.gameGenresResearchBtn = gameGenresResearchBtn;
} else {
// If not already present, re-add to projectMenu
if (projectMenu.children.indexOf(projectMenu.gameGenresResearchBtn) === -1) {
projectMenu.addChild(projectMenu.gameGenresResearchBtn);
}
projectMenu.gameGenresResearchBtn.y = buttonY;
}
// Move Platform Seç button to be below the last button
if (projectMenu.platformBtn) {
projectMenu.platformBtn.y = buttonY + buttonSpacing;
buttonY = projectMenu.platformBtn.y;
}
// Add Oyun Adı Seç button below Platform Seç
if (!projectMenu.nameGameBtn) {
var nameGameBtn = new Button();
nameGameBtn.setLabel('Oyun Adı Seç');
nameGameBtn.x = 1024;
nameGameBtn.y = buttonY + buttonSpacing;
nameGameBtn.onClick = function () {
mainMenu.visible = false;
projectMenu.visible = false;
nameGameMenu.visible = true;
currentGameName = '';
gameNameInput.setText('');
};
projectMenu.addChild(nameGameBtn);
projectMenu.nameGameBtn = nameGameBtn;
} else {
// If not already present, re-add to projectMenu
if (projectMenu.children.indexOf(projectMenu.nameGameBtn) === -1) {
projectMenu.addChild(projectMenu.nameGameBtn);
}
projectMenu.nameGameBtn.y = buttonY + buttonSpacing;
}
buttonY = projectMenu.nameGameBtn.y;
// Add info text at the bottom of the platform selection page in Start Project
if (projectMenu.platformInfoText) {
projectMenu.platformInfoText.destroy();
}
var projectPlatformInfoText = new Text2('To use a platform, purchase it from the platform page in the main menu.', {
size: 32,
fill: 0xFFC107
});
projectPlatformInfoText.anchor.set(0.5, 0.5);
projectPlatformInfoText.x = 1024;
projectPlatformInfoText.y = 2500;
projectMenu.addChild(projectPlatformInfoText);
projectMenu.platformInfoText = projectPlatformInfoText;
// Add info note about research and increasing selectable features
if (projectMenu.featureResearchInfoText) {
projectMenu.featureResearchInfoText.destroy();
}
var featureResearchInfoText = new Text2("You can research new features and increase the number of selectable features from the Research section in the main menu.", {
size: 30,
fill: 0x4CAF50,
align: "center"
});
featureResearchInfoText.anchor.set(0.5, 1);
featureResearchInfoText.x = 1024;
featureResearchInfoText.y = 2450;
projectMenu.addChild(featureResearchInfoText);
projectMenu.featureResearchInfoText = featureResearchInfoText;
// --- Genre selection UI removed: genre can only be selected from Game Genres Research page ---
// Show selected genre (if any)
if (!projectMenu.selectedGenre) {
projectMenu.selectedGenre = null;
gameState.selectedGenre = null;
}
if (projectMenu.genreText) {
projectMenu.genreText.destroy();
projectMenu.genreText = null;
}
var genreText = new Text2('Selected Genre: ' + (projectMenu.selectedGenre ? projectMenu.selectedGenre.name : 'None'), {
size: 35,
fill: 0x9C27B0
});
genreText.anchor.set(0.5, 0.5);
genreText.x = 1024;
genreText.y = 480;
projectMenu.addChild(genreText);
projectMenu.genreText = genreText;
// Total cost display
var totalCostText = new Text2('Total Cost: $0', {
size: 35,
fill: 0x4CAF50
});
totalCostText.anchor.set(0.5, 0.5);
totalCostText.x = 1024;
totalCostText.y = 530;
projectMenu.addChild(totalCostText);
// Store totalCostText reference for later updates
projectMenu.totalCostText = totalCostText;
// --- Oyun Fiyatı (Game Price) UI ---
if (!projectMenu.priceText) {
// Default price per copy
if (typeof projectMenu.selectedPrice !== "number") {
projectMenu.selectedPrice = 1; // $1 per copy default
}
var priceText = new Text2('Oyun Fiyatı: $' + projectMenu.selectedPrice, {
size: 35,
fill: 0xFFC107
});
priceText.anchor.set(0.5, 0.5);
priceText.x = 1024;
priceText.y = 580;
projectMenu.addChild(priceText);
projectMenu.priceText = priceText;
// Price select button
var priceBtn = new Button();
priceBtn.setLabel('Oyun Fiyatı Seç');
priceBtn.x = 1024;
priceBtn.y = 630;
priceBtn.onClick = function () {
// Show a simple price selection popup
if (projectMenu.pricePopup) {
projectMenu.pricePopup.destroy();
projectMenu.pricePopup = null;
}
var popup = new Container();
popup.x = 1024;
popup.y = 900;
var bg = LK.getAsset('card', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2,
scaleY: 1
});
bg.tint = 0x16213e;
popup.addChild(bg);
var title = new Text2('Oyun Fiyatı Seçin', {
size: 40,
fill: 0xFFC107
});
title.anchor.set(0.5, 0.5);
title.y = -120;
popup.addChild(title);
// Price options
var prices = [0.5, 1, 2, 3, 5, 10];
prices.forEach(function (p, idx) {
var btn = new Button();
btn.setLabel('$' + p);
btn.x = 0;
btn.y = -40 + idx * 70;
btn.onClick = function () {
projectMenu.selectedPrice = p;
projectMenu.priceText.setText('Oyun Fiyatı: $' + p);
if (projectMenu.pricePopup) {
projectMenu.pricePopup.destroy();
projectMenu.pricePopup = null;
}
LK.getSound('select').play();
};
popup.addChild(btn);
});
// Close button
var closeBtn = new Button();
closeBtn.setLabel('Kapat');
closeBtn.x = 0;
closeBtn.y = 400;
closeBtn.onClick = function () {
if (projectMenu.pricePopup) {
projectMenu.pricePopup.destroy();
projectMenu.pricePopup = null;
}
};
popup.addChild(closeBtn);
projectMenu.pricePopup = popup;
game.addChild(popup);
};
projectMenu.addChild(priceBtn);
projectMenu.priceBtn = priceBtn;
}
// If a game name was set, show it in projectMenu
if (currentGameName && currentGameName.length > 0) {
if (projectMenu.gameNameText) {
projectMenu.gameNameText.destroy();
}
var gameNameText = new Text2('Oyun Adı: ' + currentGameName, {
size: 35,
fill: 0xFFC107
});
gameNameText.anchor.set(0.5, 0.5);
gameNameText.x = 1024;
gameNameText.y = 800;
projectMenu.addChild(gameNameText);
projectMenu.gameNameText = gameNameText;
} else if (projectMenu.gameNameText) {
projectMenu.gameNameText.destroy();
projectMenu.gameNameText = null;
}
if (projectMenu.engineText) {
projectMenu.engineText.destroy();
}
// (Game Engine UI removed)
// --- Platform Selection Button and Text ---
if (projectMenu.platformText) {
projectMenu.platformText.destroy();
projectMenu.platformText = null;
}
var selectedPlatformName = gameState.selectedPlatform || "PC";
var platformText = new Text2('Platform: ' + selectedPlatformName, {
size: 35,
fill: 0xFFC107
});
platformText.anchor.set(0.5, 0.5);
platformText.x = 1024;
platformText.y = 750;
projectMenu.addChild(platformText);
projectMenu.platformText = platformText;
if (!projectMenu.platformBtn) {
var platformBtn = new Button();
platformBtn.setLabel('Platform Seç');
platformBtn.x = 1024;
// We'll set the y position after all other buttons are placed
platformBtn.onClick = function () {
// Show the platformMenu as a page, but in selection mode
mainMenu.visible = false;
projectMenu.visible = false;
platformMenu.visible = true;
platformMenu.y = 0;
// Mark that we are in platform selection mode for projectMenu
platformMenu._selectForProjectMenu = true;
// Remove old platform cards/buttons except title and back
for (var i = platformMenu.children.length - 1; i >= 0; i--) {
var child = platformMenu.children[i];
if (child !== platformTitle && child !== platformBackBtn) {
child.destroy();
}
}
// Show only owned platforms as selectable, others as locked
var yStart = 500;
var xStart = 320;
var xSpacing = 350;
var ySpacing = 220;
var cols = 4;
for (var i = 0; i < platforms.length; i++) {
var plat = platforms[i];
var container = new Container();
var col = i % cols;
var row = Math.floor(i / cols);
container.x = xStart + col * xSpacing;
container.y = yStart + row * ySpacing;
var bg = LK.getAsset('card', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.0,
scaleY: 0.35
});
container.addChild(bg);
var nameText = new Text2(plat.name, {
size: 35,
fill: 0xFFFFFF
});
nameText.anchor.set(0.5, 0.5);
nameText.y = -30;
container.addChild(nameText);
var yearText = new Text2('Çıkış: ' + plat.year, {
size: 28,
fill: 0x4CAF50
});
yearText.anchor.set(0.5, 0.5);
yearText.y = 10;
container.addChild(yearText);
var bonusText = new Text2('Satış Bonus: +' + Math.round(plat.salesBonus * 100) + '%', {
size: 24,
fill: 0x2196F3
});
bonusText.anchor.set(0.5, 0.5);
bonusText.y = 40;
container.addChild(bonusText);
var platState = gameState.platforms && gameState.platforms[plat.name] ? gameState.platforms[plat.name] : {
researched: plat.researched,
owned: plat.owned
};
if (platState && platState.owned) {
// Selectable for projectMenu
var selectBtn = new Button();
selectBtn.setLabel(gameState.selectedPlatform === plat.name ? 'Seçili' : 'Seç');
selectBtn.x = 0;
selectBtn.y = 100;
if (gameState.selectedPlatform === plat.name) {
selectBtn.children[0].tint = 0xe94560;
}
selectBtn.onClick = function (platName) {
return function () {
gameState.selectedPlatform = platName;
if (projectMenu.platformText) {
projectMenu.platformText.setText('Platform: ' + platName);
}
LK.getSound('select').play();
// Return to projectMenu after selection
platformMenu.visible = false;
projectMenu.visible = true;
platformMenu._selectForProjectMenu = false;
// Restore persistent buttons if missing
if (projectMenu.priceBtn && projectMenu.children.indexOf(projectMenu.priceBtn) === -1) {
projectMenu.addChild(projectMenu.priceBtn);
}
if (projectMenu.platformBtn && projectMenu.children.indexOf(projectMenu.platformBtn) === -1) {
projectMenu.addChild(projectMenu.platformBtn);
}
if (projectMenu.gameGenresResearchBtn && projectMenu.children.indexOf(projectMenu.gameGenresResearchBtn) === -1) {
projectMenu.addChild(projectMenu.gameGenresResearchBtn);
}
// --- Ava: Update sales bonus summary instantly when platform is changed ---
if (projectMenu.featureBonusText) {
projectMenu.featureBonusText.destroy();
}
var featureBonusSummary = '';
(function () {
var bonusParts = [];
// Platform bonus
var selectedPlatformName = gameState.selectedPlatform || "PC";
var selectedPlatformObj = null;
for (var i = 0; i < platforms.length; i++) {
if (platforms[i].name === selectedPlatformName) {
selectedPlatformObj = platforms[i];
break;
}
}
if (selectedPlatformObj && selectedPlatformObj.salesBonus) {
bonusParts.push('Platform: +' + Math.round(selectedPlatformObj.salesBonus * 100) + '% satış');
}
// Genre bonus
if (projectMenu.selectedGenre) {
var genreObj = null;
for (var i = 0; i < gameGenres.length; i++) {
if (gameGenres[i].name === projectMenu.selectedGenre.name) {
genreObj = gameGenres[i];
break;
}
}
if (genreObj && genreObj.baseMultiplier && genreObj.baseMultiplier > 1) {
bonusParts.push('Tür: +' + Math.round((genreObj.baseMultiplier - 1) * 100) + '% satış');
}
}
// Feature trend bonus
var trendTypes = [];
if (gameState.marketTrends && Array.isArray(gameState.marketTrends)) {
for (var i = 0; i < gameState.marketTrends.length; i++) {
if (gameState.marketTrends[i] === "Graphics" || gameState.marketTrends[i] === "Sound" || gameState.marketTrends[i] === "Gameplay") {
trendTypes.push(gameState.marketTrends[i]);
}
}
}
var trendBonus = 0;
if (trendTypes.length > 0 && selectedFeatures && selectedFeatures.length > 0) {
for (var i = 0; i < selectedFeatures.length; i++) {
if (trendTypes.indexOf(selectedFeatures[i].type) !== -1) {
trendBonus = 50;
break;
}
}
if (trendBonus > 0) {
bonusParts.push('Trend Özellik: +50% satış');
}
}
// Genre trend bonus
if (projectMenu.selectedGenre && gameState.marketTrends && Array.isArray(gameState.marketTrends)) {
for (var i = 0; i < gameState.marketTrends.length; i++) {
if (typeof gameState.marketTrends[i] === "string" && gameState.marketTrends[i].indexOf(projectMenu.selectedGenre.name) !== -1) {
bonusParts.push('Trend Tür: +30% satış');
break;
}
}
}
// Fan bonus (platform-specific)
var fanBonus = 0;
var selectedPlatformObj = null;
if (gameState.selectedPlatform) {
for (var pi = 0; pi < platforms.length; pi++) {
if (platforms[pi].name === gameState.selectedPlatform) {
selectedPlatformObj = platforms[pi];
break;
}
}
}
if (gameState.fans && gameState.fans > 0) {
fanBonus = Math.floor(gameState.fans / 10) / 10;
if (fanBonus > 100) fanBonus = 100;
if (fanBonus > 0) {
if (selectedPlatformObj && typeof selectedPlatformObj.salesBonus === "number") {
var platformFanBonus = Math.round(fanBonus * selectedPlatformObj.salesBonus);
bonusParts.push('Fan: +' + platformFanBonus + '% satış (platforma göre)');
} else {
bonusParts.push('Fan: +' + fanBonus + '% satış');
}
}
}
if (bonusParts.length > 0) {
featureBonusSummary = 'Satış Bonusları: ' + bonusParts.join(', ');
} else {
featureBonusSummary = 'Satış bonusu yok.';
}
})();
var featureBonusText = new Text2(featureBonusSummary, {
size: 32,
fill: 0x4CAF50
});
featureBonusText.anchor.set(0.5, 0.5);
featureBonusText.x = 1024;
featureBonusText.y = 360;
projectMenu.addChild(featureBonusText);
projectMenu.featureBonusText = featureBonusText;
};
}(plat.name);
container.addChild(selectBtn);
} else {
// Not owned, show as locked
var lockedText = new Text2('Satın Al: $' + plat.price, {
size: 28,
fill: 0x888888
});
lockedText.anchor.set(0.5, 0.5);
lockedText.y = 100;
container.addChild(lockedText);
}
platformMenu.addChild(container);
}
updatePlatformMenuScrollBounds && updatePlatformMenuScrollBounds();
// Patch platformBackBtn to return to projectMenu if in selection mode
platformBackBtn.onClick = function () {
platformMenu.visible = false;
if (platformMenu._selectForProjectMenu) {
projectMenu.visible = true;
platformMenu._selectForProjectMenu = false;
} else {
mainMenu.visible = true;
}
};
updateGlobalBackBtn && updateGlobalBackBtn();
};
projectMenu.addChild(platformBtn);
projectMenu.platformBtn = platformBtn;
} else {
// We'll set the y position after all other buttons are placed
}
// Create all project menu buttons in a single vertical column, one per row
var buttonY = 650 + 240; // Move all buttons 2 rows (240px) down
var buttonSpacing = 120;
// Feature category buttons
var categories = ['Graphics', 'Sound', 'Gameplay'];
categories.forEach(function (category, index) {
var categoryBtn = new Button();
categoryBtn.setLabel(category + ' Features');
categoryBtn.x = 1024;
categoryBtn.y = buttonY;
categoryBtn.onClick = function () {
showFeatureCategory(category);
};
projectMenu.addChild(categoryBtn);
buttonY += buttonSpacing;
});
// Oyun Fiyatı button (move to next row)
if (projectMenu.priceBtn) {
// If not already present, re-add to projectMenu
if (projectMenu.children.indexOf(projectMenu.priceBtn) === -1) {
projectMenu.addChild(projectMenu.priceBtn);
}
projectMenu.priceBtn.y = buttonY;
buttonY += buttonSpacing;
}
// Game Genres Research button (move to next row)
if (!projectMenu.gameGenresResearchBtn) {
var gameGenresResearchBtn = new Button();
gameGenresResearchBtn.setLabel('Game Genres Research');
gameGenresResearchBtn.x = 1024;
gameGenresResearchBtn.y = buttonY;
gameGenresResearchBtn.onClick = function () {
showProjectGenresResearchMenu();
};
projectMenu.addChild(gameGenresResearchBtn);
projectMenu.gameGenresResearchBtn = gameGenresResearchBtn;
} else {
// If not already present, re-add to projectMenu
if (projectMenu.children.indexOf(projectMenu.gameGenresResearchBtn) === -1) {
projectMenu.addChild(projectMenu.gameGenresResearchBtn);
}
projectMenu.gameGenresResearchBtn.y = buttonY;
}
// Move Platform Seç button to be below the last button
if (projectMenu.platformBtn) {
projectMenu.platformBtn.y = buttonY + buttonSpacing;
buttonY = projectMenu.platformBtn.y;
}
// Add Oyun Adı Seç button below Platform Seç
if (!projectMenu.nameGameBtn) {
var nameGameBtn = new Button();
nameGameBtn.setLabel('Oyun Adı Seç');
nameGameBtn.x = 1024;
nameGameBtn.y = buttonY + buttonSpacing;
nameGameBtn.onClick = function () {
mainMenu.visible = false;
projectMenu.visible = false;
nameGameMenu.visible = true;
currentGameName = '';
gameNameInput.setText('');
};
projectMenu.addChild(nameGameBtn);
projectMenu.nameGameBtn = nameGameBtn;
} else {
// If not already present, re-add to projectMenu
if (projectMenu.children.indexOf(projectMenu.nameGameBtn) === -1) {
projectMenu.addChild(projectMenu.nameGameBtn);
}
projectMenu.nameGameBtn.y = buttonY + buttonSpacing;
}
buttonY = projectMenu.nameGameBtn.y;
// Add info text at the bottom of the platform selection page in Start Project
if (projectMenu.platformInfoText) {
projectMenu.platformInfoText.destroy();
}
var projectPlatformInfoText = new Text2('To use a platform, purchase it from the platform page in the main menu.', {
size: 32,
fill: 0xFFC107
});
projectPlatformInfoText.anchor.set(0.5, 0.5);
projectPlatformInfoText.x = 1024;
projectPlatformInfoText.y = 2500;
projectMenu.addChild(projectPlatformInfoText);
projectMenu.platformInfoText = projectPlatformInfoText;
}
function startDevelopment() {
// Must have at least one feature per category
if (!selectedFeatureByCategory.Graphics || !selectedFeatureByCategory.Sound || !selectedFeatureByCategory.Gameplay) {
// Show a notification or feedback
var notification = new Container();
game.addChild(notification);
var bg = LK.getAsset('card', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2,
scaleY: 0.6
});
bg.tint = 0xE94560;
notification.addChild(bg);
var text = new Text2('Her kategoriden en az 1 özellik seçmelisin!', {
size: 35,
fill: 0xFFFFFF
});
text.anchor.set(0.5, 0.5);
notification.addChild(text);
notification.x = 1024;
notification.y = 600;
notification.alpha = 0;
tween(notification, {
alpha: 1
}, {
duration: 500,
onFinish: function onFinish() {
LK.setTimeout(function () {
tween(notification, {
alpha: 0
}, {
duration: 500,
onFinish: function onFinish() {
notification.destroy();
}
});
}, 2000);
}
});
return;
}
// --- Require a researched genre to be selected before starting development ---
var researchedGenres = gameState.researchedFeatures.GameGenres;
// Fix: Check if selectedGenre is not null and its name is in researchedGenres or does not require research
if (!projectMenu.selectedGenre ||
// Find the genre object in gameGenres
function () {
var genreObj = null;
for (var i = 0; i < gameGenres.length; i++) {
if (gameGenres[i].name === projectMenu.selectedGenre.name) {
genreObj = gameGenres[i];
break;
}
}
// If genreObj is not found, treat as not researched
if (!genreObj) return true;
// If genre does not require research, allow
if (!genreObj.requiresResearch) return false;
// If genre requires research, check if it's in researchedGenres
return researchedGenres.indexOf(genreObj.name) === -1;
}()) {
// Show a notification or feedback
var notification = new Container();
game.addChild(notification);
var bg = LK.getAsset('card', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2,
scaleY: 0.6
});
bg.tint = 0xE94560;
notification.addChild(bg);
var text = new Text2('Please select a researched genre before starting!', {
size: 35,
fill: 0xFFFFFF
});
text.anchor.set(0.5, 0.5);
notification.addChild(text);
notification.x = 1024;
notification.y = 600;
notification.alpha = 0;
tween(notification, {
alpha: 1
}, {
duration: 500,
onFinish: function onFinish() {
LK.setTimeout(function () {
tween(notification, {
alpha: 0
}, {
duration: 500,
onFinish: function onFinish() {
notification.destroy();
}
});
}, 2000);
}
});
return;
}
// Calculate total cost
var totalCost = 0;
selectedFeatures.forEach(function (feature) {
totalCost += feature.cost;
});
// Check if player can afford
if (gameState.money < totalCost) {
return;
}
// Deduct costs
gameState.money -= totalCost;
updateUI();
projectMenu.visible = false;
developmentScreen.visible = true;
// (Game Engine UI removed from development screen)
// Display trends
for (var i = trendsContainer.children.length - 1; i > 0; i--) {
trendsContainer.children[i].destroy();
}
gameState.marketTrends.forEach(function (trend, index) {
var trendText = new Text2(trend + ' is trending!', {
size: 30,
fill: 0xFF5722
});
trendText.anchor.set(0.5, 0.5);
trendText.y = 40 + index * 35;
trendsContainer.addChild(trendText);
});
// Calculate target score
var baseTarget = 100;
targetScoreText.setText('Target Score: ' + baseTarget);
// Use selected genre from projectMenu
var selectedGenre = projectMenu.selectedGenre || null;
// Start project
gameState.currentProject = {
features: selectedFeatures,
targetScore: baseTarget,
currentScore: 0,
developmentSpeed: 0,
genre: selectedGenre,
price: typeof projectMenu.selectedPrice === "number" ? projectMenu.selectedPrice : 1
};
// Assign features to developers (main character is always included and can contribute to all features)
var assignedDevelopers = [];
var assignedFeatures = [];
// Always include main character as a developer
var allDevs = [{
name: gameState.mainCharacter.name,
specialty: "All",
skill: gameState.mainCharacter.skill,
featurePoints: Object.assign({}, gameState.mainCharacter.featurePoints)
}].concat(gameState.developers.map(function (dev) {
return {
name: dev.name,
specialty: dev.specialty,
skill: dev.skill,
assignedFeature: null
};
}));
// Assign features: each feature is assigned to a developer, but main character always contributes to all
var devAssignments = [];
selectedFeatures.forEach(function (feature, idx) {
// Assign to next available developer (skip main character for assignment, but main character always contributes)
var devIdx = (idx + 1) % allDevs.length;
if (devIdx === 0 && allDevs.length > 1) devIdx = 1; // avoid assigning all to main character
devAssignments.push({
dev: allDevs[devIdx],
feature: feature
});
allDevs[devIdx].assignedFeature = feature.name;
});
// Calculate development speed
var totalSpeed = 0;
// Main character always contributes to all features
selectedFeatures.forEach(function (feature) {
var fp = gameState.mainCharacter.featurePoints[feature.type] || 1;
totalSpeed += (gameState.mainCharacter.skill + fp) * 0.5;
});
// Other developers contribute to their assigned feature
devAssignments.forEach(function (assignment) {
if (assignment.dev.name !== gameState.mainCharacter.name) {
totalSpeed += assignment.dev.skill * 0.5;
}
});
gameState.currentProject.developmentSpeed = totalSpeed;
gameState.currentProject.devAssignments = devAssignments;
LK.getSound('develop').play();
releaseBtn.visible = false;
progressBarFill.scaleX = 0;
}
function releaseGame() {
var project = gameState.currentProject;
// Calculate final score with bonuses
var finalScore = project.currentScore;
// (Game Engine quality bonus removed)
// Trend bonus
var trendMultiplier = 1;
project.features.forEach(function (feature) {
if (gameState.marketTrends.indexOf(feature.type) !== -1) {
finalScore *= 1.5;
trendMultiplier += 0.3;
}
});
// Genre bonus
if (project.genre) {
finalScore *= project.genre.baseMultiplier;
if (gameState.marketTrends.some(function (trend) {
return trend.indexOf(project.genre.name) !== -1;
})) {
finalScore *= 1.3;
trendMultiplier += 0.4;
}
}
// Calculate initial sales potential
var baseSalesMultiplier = 20;
if (finalScore >= project.targetScore) {
baseSalesMultiplier = 40;
}
// Price effect on sales: higher price = lower sales, lower price = higher sales
var priceSalesMultiplier = 1;
if (project.price) {
if (project.price > 1) {
priceSalesMultiplier = 1 / (0.7 + (project.price - 1) * 0.5); // $2 = ~0.67x, $5 = ~0.29x
if (priceSalesMultiplier < 0.15) priceSalesMultiplier = 0.15;
} else if (project.price < 1) {
priceSalesMultiplier = 1 + (1 - project.price) * 0.7; // $0.5 = 1.35x
}
}
// --- Ava: Reduce sales multiplier if features and review score are low and price is high ---
var featureQuality = 0;
for (var i = 0; i < project.features.length; i++) {
featureQuality += project.features[i].basePoints || 0;
}
var avgFeatureQuality = featureQuality / project.features.length;
var reviewScoreForPenalty = 0;
var scoreRatio = finalScore / project.targetScore;
if (scoreRatio >= 1.5) reviewScoreForPenalty = 95;else if (scoreRatio >= 1.2) reviewScoreForPenalty = 85;else if (scoreRatio >= 1.0) reviewScoreForPenalty = 75;else if (scoreRatio >= 0.8) reviewScoreForPenalty = 60;else reviewScoreForPenalty = 40;
// If price is high, but features and review are low, apply a penalty to sales
var pricePenaltyMultiplier = 1;
if (project.price > 2) {
// If both feature quality and review are low, penalize more
if (avgFeatureQuality < 5 && reviewScoreForPenalty < 70) {
pricePenaltyMultiplier = 0.5 - Math.min((project.price - 2) * 0.1, 0.3); // up to -30% more penalty
} else if (avgFeatureQuality < 6 || reviewScoreForPenalty < 75) {
pricePenaltyMultiplier = 0.7 - Math.min((project.price - 2) * 0.05, 0.2); // up to -20% more penalty
}
// Never less than 0.2x
if (pricePenaltyMultiplier < 0.2) pricePenaltyMultiplier = 0.2;
}
// Find selected platform and apply its salesBonus
var selectedPlatform = null;
for (var i = 0; i < platforms.length; i++) {
if (platforms[i].name === gameState.selectedPlatform) {
selectedPlatform = platforms[i];
break;
}
}
var platformSalesBonus = selectedPlatform && selectedPlatform.salesBonus ? 1 + selectedPlatform.salesBonus : 1;
var initialDailySales = Math.floor(finalScore / project.targetScore * baseSalesMultiplier * trendMultiplier * priceSalesMultiplier * pricePenaltyMultiplier * platformSalesBonus);
var gameName = currentGameName && currentGameName.length > 0 ? currentGameName : 'Game #' + (gameState.completedGames + 1);
// --- Review and score system ---
// Ava: Reviewers are now much more pessimistic!
// Only 5 reviewers, each with unique focus: feature, price, platform, etc.
var reviewCompanies = ["IGN", "GameSpot", "Polygon", "Eurogamer", "Kotaku"];
var reviews = [];
var reviewScore = 0;
var genreTrend = gameState.marketTrends.find(function (trend) {
return project.genre && trend.indexOf(project.genre.name) !== -1;
});
var featureTrend = gameState.marketTrends.indexOf(project.features[0].type) !== -1 || gameState.marketTrends.indexOf(project.features[1].type) !== -1 || gameState.marketTrends.indexOf(project.features[2].type) !== -1 || project.features.length > 3 && gameState.marketTrends.indexOf(project.features[3].type) !== -1 || project.features.length > 4 && gameState.marketTrends.indexOf(project.features[4].type) !== -1;
// Calculate review score (0-100) -- pessimistic version
var scoreRatio = finalScore / project.targetScore;
if (scoreRatio >= 1.5) reviewScore = 80 + Math.floor(Math.random() * 6); // was 95+
else if (scoreRatio >= 1.2) reviewScore = 65 + Math.floor(Math.random() * 10); // was 85+
else if (scoreRatio >= 1.0) reviewScore = 55 + Math.floor(Math.random() * 10); // was 75+
else if (scoreRatio >= 0.8) reviewScore = 40 + Math.floor(Math.random() * 10); // was 60+
else reviewScore = 20 + Math.floor(Math.random() * 20); // was 40+
// If genre matches trend, boost score (less than before)
if (genreTrend) reviewScore += 2;
if (featureTrend) reviewScore += 2;
// --- Price effect on review score ---
if (project.price) {
// $1 is neutral, higher price reduces review, lower price increases (harsher penalty)
if (project.price > 1) {
reviewScore -= Math.floor((project.price - 1) * 7); // -7 puan/extra dollar
} else if (project.price < 1) {
reviewScore += Math.floor((1 - project.price) * 3); // +3 puan/discounted dollar
}
}
if (reviewScore > 100) reviewScore = 100;
if (reviewScore < 0) reviewScore = 0;
// --- 5 unique reviews: each with a different focus ---
// 1. Feature focus
var feature = project.features[0];
var featureScore = reviewScore + Math.floor(Math.random() * 5 - 2);
if (featureScore > 100) featureScore = 100;
if (featureScore < 0) featureScore = 0;
var featureText = "";
if (featureScore >= 80) {
featureText = "The standout feature is '" + feature.name + "'. It really elevates the experience.";
} else if (featureScore >= 60) {
featureText = "'" + feature.name + "' is decent, but could use more polish.";
} else {
featureText = "The '" + feature.name + "' feature is a major letdown.";
}
reviews.push({
company: reviewCompanies[0],
score: featureScore,
text: featureText
});
// 2. Price focus
var priceScore = reviewScore + Math.floor(Math.random() * 5 - 2);
if (priceScore > 100) priceScore = 100;
if (priceScore < 0) priceScore = 0;
var priceText = "";
if (project.price > 3) {
priceText = "At $" + project.price + ", the game feels overpriced for what it offers.";
} else if (project.price < 1) {
priceText = "Great value for money! The low price makes this game more appealing.";
} else {
priceText = "The price is fair for the content provided.";
}
reviews.push({
company: reviewCompanies[1],
score: priceScore,
text: priceText
});
// 3. Platform compatibility focus
var platformName = gameState.selectedPlatform || "PC";
var platformScore = reviewScore + Math.floor(Math.random() * 5 - 2);
if (platformScore > 100) platformScore = 100;
if (platformScore < 0) platformScore = 0;
var platformText = "";
if (platformName === "PC") {
platformText = "Runs smoothly on PC, but we'd love to see more platform options.";
} else {
platformText = "Great to see support for " + platformName + ".";
}
reviews.push({
company: reviewCompanies[2],
score: platformScore,
text: platformText
});
// 4. Trend/genre focus
var trendScore = reviewScore + Math.floor(Math.random() * 5 - 2);
if (trendScore > 100) trendScore = 100;
if (trendScore < 0) trendScore = 0;
var trendText = "";
if (genreTrend) {
trendText = "Smart move to follow the '" + project.genre.name + "' trend. It pays off!";
} else if (featureTrend) {
trendText = "The game tries to follow current feature trends, but doesn't quite hit the mark.";
} else {
trendText = "Misses out on current market trends, making it feel a bit outdated.";
}
reviews.push({
company: reviewCompanies[3],
score: trendScore,
text: trendText
});
// 5. General polish/compatibility focus
var polishScore = reviewScore + Math.floor(Math.random() * 5 - 2);
if (polishScore > 100) polishScore = 100;
if (polishScore < 0) polishScore = 0;
var polishText = "";
if (polishScore >= 80) {
polishText = "A well-polished game with few bugs. Impressive work!";
} else if (polishScore >= 60) {
polishText = "Some rough edges, but overall a stable experience.";
} else {
polishText = "Technical issues and lack of polish hold this game back.";
}
reviews.push({
company: reviewCompanies[4],
score: polishScore,
text: polishText
});
var releasedGame = {
name: gameName,
releaseDay: gameState.currentDay,
score: finalScore,
targetScore: project.targetScore,
initialDailySales: initialDailySales,
currentDailySales: initialDailySales,
totalSales: 0,
features: project.features,
trendBonus: trendMultiplier,
price: project.price || 1,
// Add main character as a developer in the released game
developers: [{
name: gameState.mainCharacter.name,
specialty: "All",
skill: gameState.mainCharacter.skill
}].concat(gameState.developers.slice()),
genre: project.genre,
reviews: reviews,
reviewScore: reviewScore
};
// Reset game name after use
currentGameName = '';
gameNameDisplay.setText('');
// Clear marketTrends so new trends are generated for the next project
gameState.marketTrends = [];
gameState.releasedGames.push(releasedGame);
// Success check
if (finalScore >= project.targetScore) {
gameState.money += Math.floor(finalScore * 0.00025); // 95% less
gameState.completedGames++;
LK.getSound('success').play();
LK.setScore(gameState.completedGames);
if (gameState.completedGames >= 10) {
LK.showYouWin();
}
} else {
gameState.money += Math.floor(finalScore * 0.0000625); // 95% less
}
LK.getSound('release').play();
// Reset
gameState.currentProject = null;
developmentScreen.visible = false;
mainMenu.visible = true;
updateUI();
updateSalesLog();
// --- Rakiplerden biri de oyun çıkarsın (oyuncu oyun çıkardığında) ---
if (gameState.rivals && gameState.rivals.length > 0) {
// Rastgele bir rakip seç
var rivalIndex = Math.floor(Math.random() * gameState.rivals.length);
var rival = gameState.rivals[rivalIndex];
// Oyun ismi ve gelirini üret
var gameNames = ["Super", "Mega", "Ultra", "Epic", "Legend", "Pixel", "Quest", "Saga", "Chronicles", "World"];
var gameSuffix = ["Adventure", "Battle", "Story", "Kingdom", "Odyssey", "Arena", "Tycoon", "Empire", "Run", "Hero"];
var name = gameNames[Math.floor(Math.random() * gameNames.length)] + " " + gameSuffix[Math.floor(Math.random() * gameSuffix.length)];
// Son 3 oyunun ortalamasını bul
var last3 = rival.games && rival.games.length > 0 ? rival.games.slice(-3) : [];
var avg = 40000;
if (last3.length > 0) {
var sum = 0;
for (var i = 0; i < last3.length; i++) sum += last3[i].revenue;
avg = Math.floor(sum / last3.length);
}
// Rakip oyun kazancı, rakip şirket değerinin %1-%20 aralığında kâr veya %1-%20 aralığında zarar olacak şekilde ayarlandı
var percent = (Math.random() < 0.5 ? -1 : 1) * (0.01 + Math.random() * 0.19); // -0.01 ile -0.20 veya +0.01 ile +0.20 arası
var baseValue = rival.value || 100000;
var revenue = Math.floor(baseValue * Math.abs(percent));
var originalRevenue = revenue;
if (percent < 0) {
revenue = -revenue;
}
var originalLoss = 0;
if (revenue < 0) {
originalLoss = -revenue;
revenue = 0;
}
// Oyun objesi
var rivalGame = {
name: name,
releaseDay: gameState.currentDay,
revenue: revenue,
_originalRevenue: percent < 0 ? -originalRevenue : originalRevenue,
_originalLoss: originalLoss
};
rival.games.push(rivalGame);
// Sadece son 3 oyunu tut
if (rival.games.length > 3) rival.games = rival.games.slice(-3);
// Firma değerini anlık olarak kâr/zarara göre değiştir: kâr ise artır, zarar ise azalt
if (revenue > 0) {
rival.value += revenue + Math.floor(revenue * 0.1);
} else if (originalLoss > 0) {
rival.value -= originalLoss;
}
// Firma değeri 0'ın altına düşmesin
if (rival.value < 0) rival.value = 0;
// Son 3 oyunun ortalamasını güncelle
var sum2 = 0;
for (var i = 0; i < rival.games.length; i++) sum2 += rival.games[i].revenue;
rival.avgRevenue = Math.floor(sum2 / rival.games.length);
}
}
// Game update
var dayTimer = 0;
game.update = function () {
// Handle research progress
if (gameState.currentResearch) {
gameState.currentResearch.timeRemaining--;
if (gameState.currentResearch.timeRemaining <= 0) {
// Research complete
var research = gameState.currentResearch;
if (research.category === 'Platforms') {
// Mark platform as researched
if (gameState.platforms && gameState.platforms[research.name]) {
gameState.platforms[research.name].researched = true;
}
} else if (research.category === 'IncreaseLimit_Graphics' || research.category === 'IncreaseLimit_Sound' || research.category === 'IncreaseLimit_Gameplay') {
// Increase the selection limit for the relevant category
var cat = research.category.replace('IncreaseLimit_', '');
if (!gameState.featureSelectionLimit) gameState.featureSelectionLimit = {};
if (typeof gameState.featureSelectionLimit[cat] !== "number") gameState.featureSelectionLimit[cat] = 1;
gameState.featureSelectionLimit[cat]++;
} else {
gameState.researchedFeatures[research.category].push(research.name);
}
gameState.currentResearch = null;
LK.getSound('success').play();
// Show notification
var notification = new Container();
game.addChild(notification);
var bg = LK.getAsset('card', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2,
scaleY: 0.8
});
bg.tint = 0x4CAF50;
notification.addChild(bg);
var text = new Text2('Research Complete: ' + research.name, {
size: 35,
fill: 0xFFFFFF
});
text.anchor.set(0.5, 0.5);
notification.addChild(text);
notification.x = 1024;
notification.y = 600;
notification.alpha = 0;
tween(notification, {
alpha: 1
}, {
duration: 500,
onFinish: function onFinish() {
LK.setTimeout(function () {
tween(notification, {
alpha: 0
}, {
duration: 500,
onFinish: function onFinish() {
notification.destroy();
}
});
}, 2000);
}
});
}
}
// Day progression (every 3 seconds = 1 day)
dayTimer++;
if (dayTimer >= 180) {
// 60 fps * 3 seconds
dayTimer = 0;
gameState.currentDay++;
// --- Bank: Process credit and deposit on day change ---
// Credit: No daily penalty, payment handled at normal interest (see showBankMenu)
// Deposit: If matured, do NOT auto-renew. Wait for user to withdraw. (Faiz zamanı tamamlanınca dursun, çek butonu görüntülensin)
// No action needed here; handled in showBankMenu withdrawBtn
// Kredi vadesi dolunca faiz eklenmesin, borç vadesi dolunca beklesin (hiçbir işlem yapılmaz)
updateUI();
// Fan Store günlük satış sistemi: Her gün başında çalıştır
processFanStoreDailySale();
// Process game sales
for (var i = gameState.releasedGames.length - 1; i >= 0; i--) {
var releasedGame = gameState.releasedGames[i];
var daysSinceRelease = gameState.currentDay - releasedGame.releaseDay;
// Calculate sales decline
var declineRate = 0.75; // Base 25% daily decline
// Better games decline slower
if (releasedGame.score >= releasedGame.targetScore * 1.5) {
declineRate = 0.85;
} else if (releasedGame.score >= releasedGame.targetScore) {
declineRate = 0.80;
}
// Apply trend bonus to decline rate
declineRate += (releasedGame.trendBonus - 1) * 0.03;
declineRate = Math.min(declineRate, 0.90);
// Calculate review score multiplier (0.3x for <60, 1x for 60-74, 1.7x for 75-89, 2.5x for 90+)
// Ava: Review scores now have a much stronger effect on sales!
var reviewMultiplier = 1;
if (releasedGame.reviewScore !== undefined) {
if (releasedGame.reviewScore >= 90) reviewMultiplier = 2.5;else if (releasedGame.reviewScore >= 75) reviewMultiplier = 1.7;else if (releasedGame.reviewScore >= 60) reviewMultiplier = 1;else reviewMultiplier = 0.3;
}
// Calculate fan sales bonus: proportional, e.g. 200 fan = %2, 1000 fan = %10, max 100%
// Platform-specific: always use the selected platform's salesBonus
var fanSalesBonus = 1;
var selectedPlatformObj = null;
if (gameState.selectedPlatform) {
for (var pi = 0; pi < platforms.length; pi++) {
if (platforms[pi].name === gameState.selectedPlatform) {
selectedPlatformObj = platforms[pi];
break;
}
}
}
if (gameState.fans && gameState.fans > 0) {
var bonusPercent = gameState.fans / 100000 * 100; // 100000 fan = %100 bonus
if (bonusPercent > 100) bonusPercent = 100;
// Always use platform's salesBonus if available
if (selectedPlatformObj && typeof selectedPlatformObj.salesBonus === "number") {
fanSalesBonus = 1 + bonusPercent * selectedPlatformObj.salesBonus / 100;
} else {
fanSalesBonus = 1 + bonusPercent / 100;
}
}
// Calculate current day sales
// Ava: +200% general sales boost, then reduce by 25% (multiply by 0.75)
// Satışları %35 artırmak için çarpanı 3.0*0.75 yerine 3.0*0.75*1.35 yapıyoruz
releasedGame.currentDailySales = Math.floor(releasedGame.initialDailySales * Math.pow(declineRate, daysSinceRelease) * reviewMultiplier * fanSalesBonus * 3.0 * 0.75 * 1.35);
// Add to total sales and money
if (releasedGame.currentDailySales > 0) {
releasedGame.totalSales += releasedGame.currentDailySales;
var pricePerCopy = releasedGame.price || 1;
var revenue = Math.floor(releasedGame.currentDailySales * pricePerCopy); // 100% of price per copy to player
gameState.money += revenue;
// --- Fan gain from sales: Her 10 kopya satışta 1-5 arası rastgele fan kazandır ---
if (!releasedGame._fanSalesRemainder) releasedGame._fanSalesRemainder = 0;
var totalSalesForFan = releasedGame.currentDailySales + releasedGame._fanSalesRemainder;
var fansGained = 0;
if (totalSalesForFan >= 10) {
var fanAwardCount = Math.floor(totalSalesForFan / 10);
for (var f = 0; f < fanAwardCount; f++) {
fansGained += 1 + Math.floor(Math.random() * 2); // 1-2 arası rastgele
}
releasedGame._fanSalesRemainder = totalSalesForFan % 10;
} else {
releasedGame._fanSalesRemainder = totalSalesForFan;
}
if (!gameState.fans) gameState.fans = 0;
gameState.fans += fansGained;
// --- Eski random fanGainPercent sistemini kaldır ---
// (Kaldırıldı)
} else {
// Game no longer selling - remove from market
var removedGame = gameState.releasedGames.splice(i, 1)[0];
gameState.gameHistory.push(removedGame);
// Show notification
var notification = new Container();
game.addChild(notification);
var bg = LK.getAsset('card', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2,
scaleY: 1.2
});
bg.tint = 0x0f3460;
notification.addChild(bg);
var titleText = new Text2(removedGame.name + ' removed from market', {
size: 35,
fill: 0xFFFFFF
});
titleText.anchor.set(0.5, 0.5);
titleText.y = -30;
notification.addChild(titleText);
var salesText = new Text2('Total copies sold: ' + removedGame.totalSales, {
size: 30,
fill: 0x4CAF50
});
salesText.anchor.set(0.5, 0.5);
salesText.y = 20;
notification.addChild(salesText);
notification.x = 1024;
notification.y = 1366;
notification.alpha = 0;
// Animate notification
tween(notification, {
alpha: 1,
y: 1000
}, {
duration: 500,
onFinish: function onFinish() {
LK.setTimeout(function () {
tween(notification, {
alpha: 0
}, {
duration: 500,
onFinish: function onFinish() {
notification.destroy();
}
});
}, 2000);
}
});
}
}
updateUI();
updateSalesLog();
}
if (gameState.currentProject && developmentScreen.visible) {
var project = gameState.currentProject;
// Development progress
if (project.currentScore < project.targetScore) {
// --- Ava: Make score gain speed depend on studio level and total developer skill ---
// Calculate base points per tick
var pointsPerTick = project.developmentSpeed / 30;
// Calculate total skill of all developers (including main character)
var totalDevSkill = gameState.mainCharacter.skill;
for (var i = 0; i < gameState.developers.length; i++) {
totalDevSkill += gameState.developers[i].skill;
}
// Studio level bonus: higher level = faster progress
var studioLevelBonus = 1 + (gameState.studioLevel - 1) * 0.15; // +15% per studio level above 1
// Skill bonus: more total skill = faster progress, but with diminishing returns
var skillBonus = 0.5 + Math.log(1 + totalDevSkill) * 0.5; // log curve, min 0.5x
// Feature synergy bonus (as before)
var synergy = 1;
if (gameState.mainCharacter.featurePoints) {
project.features.forEach(function (feature) {
if (gameState.mainCharacter.featurePoints[feature.type] && gameState.mainCharacter.featurePoints[feature.type] > 0) {
synergy += 0.1;
}
});
}
project.features.forEach(function (feature) {
gameState.developers.forEach(function (dev) {
if (dev.specialty === feature.type) {
synergy += 0.1;
}
});
});
// Final points per tick: base * studioLevelBonus * skillBonus * synergy
var finalPointsPerTick = pointsPerTick * studioLevelBonus * skillBonus * synergy;
// Clamp minimum progress to avoid being stuck at 0
if (finalPointsPerTick < 0.01) finalPointsPerTick = 0.01;
project.currentScore += finalPointsPerTick;
// Update UI
currentScoreText.setText('Current Score: ' + Math.floor(project.currentScore));
var progress = Math.min(project.currentScore / project.targetScore, 1);
progressBarFill.scaleX = progress;
// Show release button when ready
if (progress >= 1 && !releaseBtn.visible) {
releaseBtn.visible = true;
tween(releaseBtn, {
scaleX: 1.1,
scaleY: 1.1
}, {
duration: 500,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(releaseBtn, {
scaleX: 1,
scaleY: 1
}, {
duration: 500
});
}
});
}
}
}
// Check game over
if (gameState.money < 100 && gameState.developers.length === 0 && !gameState.currentProject) {
LK.showGameOver();
}
};
// Global Back Button (bottom)
var globalBackBtn = new Button();
globalBackBtn.setLabel('Geri');
// Place at bottom center, matching other menu button size (400x100)
globalBackBtn.x = 1024;
globalBackBtn.y = 2600;
globalBackBtn.visible = false;
LK.gui.bottom.addChild(globalBackBtn);
// --- Reset Game Button (bottom left) ---
var resetGameBtn = new Button();
resetGameBtn.setLabel('Reset Game');
resetGameBtn.x = 220; // 200px from left, avoid top left menu area
resetGameBtn.y = 2600; // bottom, same as globalBackBtn
resetGameBtn.scaleX = 1;
resetGameBtn.scaleY = 1;
resetGameBtn.onClick = function () {
LK.showGameOver(); // This will reset the game state and show the game over popup
};
LK.gui.bottomLeft.addChild(resetGameBtn);
// Global Back Button (top)
var globalBackBtnTop = new Button();
globalBackBtnTop.setLabel('Geri');
globalBackBtnTop.x = 1024;
globalBackBtnTop.y = 100;
globalBackBtnTop.visible = false;
LK.gui.top.addChild(globalBackBtnTop);
// --- Reset Game Button (bottom left) ---
var resetGameBtn = new Button();
resetGameBtn.setLabel('Reset Game');
resetGameBtn.x = 220; // 200px from left, avoid top left menu area
resetGameBtn.y = 2600; // bottom, same as globalBackBtn
resetGameBtn.scaleX = 1;
resetGameBtn.scaleY = 1;
resetGameBtn.onClick = function () {
LK.showGameOver(); // This will reset the game state and show the game over popup
};
LK.gui.bottomLeft.addChild(resetGameBtn);
// Helper to check if any menu except mainMenu is visible
function isAnyMenuOpen() {
return upgradeMenu.visible || researchMenu.visible || researchCategoryMenu.visible || nameGameMenu.visible || allGamesMenu.visible || gameDetailView.visible || hireMenu.visible || projectMenu.visible || featureCategoryMenu.visible || developmentScreen.visible;
}
// Helper to close the topmost open menu and return to mainMenu
function closeCurrentMenu() {
if (upgradeMenu.visible) {
upgradeMenu.visible = false;
mainMenu.visible = true;
} else if (researchCategoryMenu.visible) {
researchCategoryMenu.visible = false;
researchMenu.visible = true;
} else if (researchMenu.visible) {
researchMenu.visible = false;
mainMenu.visible = true;
} else if (nameGameMenu.visible) {
nameGameMenu.visible = false;
mainMenu.visible = true;
gameNameInput.setText('');
currentGameName = '';
} else if (allGamesMenu.visible) {
allGamesMenu.visible = false;
mainMenu.visible = true;
} else if (gameDetailView.visible) {
gameDetailView.visible = false;
allGamesMenu.visible = true;
} else if (hireMenu.visible) {
hireMenu.visible = false;
mainMenu.visible = true;
} else if (featureCategoryMenu.visible) {
featureCategoryMenu.visible = false;
projectMenu.visible = true;
// Update total cost in project menu
var totalCost = 0;
selectedFeatures.forEach(function (f) {
totalCost += f.cost;
});
if (projectMenu.totalCostText) {
projectMenu.totalCostText.setText('Total Cost: $' + totalCost);
}
} else if (projectMenu.visible) {
projectMenu.visible = false;
mainMenu.visible = true;
selectedFeatures = [];
featureCards.forEach(function (card) {
card.setSelected(false);
});
// Restore persistent buttons if missing (for next open)
if (projectMenu.priceBtn && projectMenu.children.indexOf(projectMenu.priceBtn) === -1) {
projectMenu.addChild(projectMenu.priceBtn);
}
if (projectMenu.platformBtn && projectMenu.children.indexOf(projectMenu.platformBtn) === -1) {
projectMenu.addChild(projectMenu.platformBtn);
}
if (projectMenu.gameGenresResearchBtn && projectMenu.children.indexOf(projectMenu.gameGenresResearchBtn) === -1) {
projectMenu.addChild(projectMenu.gameGenresResearchBtn);
}
} else if (developmentScreen.visible) {
developmentScreen.visible = false;
mainMenu.visible = true;
}
}
// Attach handler to global back button
globalBackBtn.onClick = function () {
closeCurrentMenu();
};
globalBackBtnTop.onClick = function () {
closeCurrentMenu();
};
// Show/hide global back button depending on menu state
function updateGlobalBackBtn() {
// Show if any menu except mainMenu is visible
var show = isAnyMenuOpen() && !mainMenu.visible;
globalBackBtn.visible = show;
globalBackBtnTop.visible = show;
}
// Patch all menu show functions to update global back button
var _showUpgradeMenu = showUpgradeMenu;
showUpgradeMenu = function showUpgradeMenu() {
_showUpgradeMenu();
updateGlobalBackBtn();
};
var _showPlatformMenu = showPlatformMenu;
showPlatformMenu = function showPlatformMenu() {
_showPlatformMenu();
updateGlobalBackBtn();
};
var _showResearchMenu = showResearchMenu;
showResearchMenu = function showResearchMenu() {
_showResearchMenu();
updateGlobalBackBtn();
};
var _showAllGamesMenu = showAllGamesMenu;
showAllGamesMenu = function showAllGamesMenu() {
_showAllGamesMenu();
updateGlobalBackBtn();
};
var _showHireMenu = showHireMenu;
showHireMenu = function showHireMenu() {
_showHireMenu();
updateGlobalBackBtn();
};
var _showProjectMenu = showProjectMenu;
showProjectMenu = function showProjectMenu() {
_showProjectMenu();
updateGlobalBackBtn();
};
var _showFeatureCategory = showFeatureCategory;
showFeatureCategory = function showFeatureCategory(category) {
_showFeatureCategory(category);
updateGlobalBackBtn();
};
var _showResearchCategory = showResearchCategory;
showResearchCategory = function showResearchCategory(category) {
_showResearchCategory(category);
updateGlobalBackBtn();
};
var _showNameGameMenu = showNameGameMenu;
showNameGameMenu = function showNameGameMenu() {
_showNameGameMenu();
updateGlobalBackBtn();
};
var _showGameDetail = showGameDetail;
showGameDetail = function showGameDetail(gameData) {
_showGameDetail(gameData);
updateGlobalBackBtn();
};
// Patch all menu back/close buttons to update global back button
function patchBackBtn(btn, closeFn) {
var old = btn.onClick;
btn.onClick = function () {
if (old) old();
updateGlobalBackBtn();
};
}
patchBackBtn(backFromUpgradeBtn);
patchBackBtn(researchBackBtn);
patchBackBtn(categoryBackBtn);
patchBackBtn(backFromNameBtn);
patchBackBtn(backFromAllGamesBtn);
patchBackBtn(detailBackBtn);
patchBackBtn(backFromHireBtn);
patchBackBtn(backFromProjectBtn);
patchBackBtn(categoryBackBtn);
patchBackBtn(researchBackBtn);
patchBackBtn(categoryBackBtn);
// Also update on developmentScreen close (release)
var _releaseGame = releaseGame;
releaseGame = function releaseGame() {
_releaseGame();
updateGlobalBackBtn();
};
// Also update on game update (in case of state changes)
var _updateUI = updateUI;
updateUI = function updateUI() {
_updateUI();
updateGlobalBackBtn();
};
// Initialize
updateUI();
updateGlobalBackBtn(); /****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/****
* Classes
****/
var Button = Container.expand(function () {
var self = Container.call(this);
var bg = self.attachAsset('button', {
anchorX: 0.5,
anchorY: 0.5
});
var label = new Text2('Button', {
size: 40,
fill: 0xFFFFFF
});
label.anchor.set(0.5, 0.5);
self.addChild(label);
self.setLabel = function (text) {
label.setText(text);
};
self.down = function () {
tween(bg, {
scaleX: 0.95,
scaleY: 0.95
}, {
duration: 100
});
LK.getSound('select').play();
};
self.up = function () {
tween(bg, {
scaleX: 1,
scaleY: 1
}, {
duration: 100
});
if (self.onClick) {
self.onClick();
}
};
return self;
});
var DeveloperCard = Container.expand(function () {
var self = Container.call(this);
var bg = self.attachAsset('card', {
anchorX: 0.5,
anchorY: 0.5
});
var icon = self.attachAsset('developerIcon', {
anchorX: 0.5,
anchorY: 0.5,
y: -100
});
var nameText = new Text2('Developer', {
size: 30,
fill: 0xFFFFFF
});
nameText.anchor.set(0.5, 0.5);
nameText.y = -20;
self.addChild(nameText);
var specialtyText = new Text2('Graphics', {
size: 25,
fill: 0xFFC107
});
specialtyText.anchor.set(0.5, 0.5);
specialtyText.y = 20;
self.addChild(specialtyText);
var costText = new Text2('Cost: $100', {
size: 25,
fill: 0x4CAF50
});
costText.anchor.set(0.5, 0.5);
costText.y = 60;
self.addChild(costText);
var skillText = new Text2('Skill: 5', {
size: 25,
fill: 0x2196F3
});
skillText.anchor.set(0.5, 0.5);
skillText.y = 100;
self.addChild(skillText);
self.developerData = null;
self.setDeveloper = function (data) {
self.developerData = data;
nameText.setText(data.name);
specialtyText.setText(data.specialty);
costText.setText('Cost: $' + data.cost);
skillText.setText('Skill: ' + data.skill);
var specialtyColors = {
'Graphics': 0xff5722,
'Sound': 0x9c27b0,
'Gameplay': 0x2196f3
};
icon.tint = specialtyColors[data.specialty] || 0xffc107;
};
self.down = function () {
if (self.onClick) {
self.onClick(self.developerData);
}
};
return self;
});
var FeatureCard = Container.expand(function () {
var self = Container.call(this);
var bg = self.attachAsset('card', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.8,
scaleY: 0.8
});
var icon = self.attachAsset('featureIcon', {
anchorX: 0.5,
anchorY: 0.5,
y: -80
});
var nameText = new Text2('Feature', {
size: 25,
fill: 0xFFFFFF
});
nameText.anchor.set(0.5, 0.5);
nameText.y = -20;
self.addChild(nameText);
var typeText = new Text2('Type', {
size: 20,
fill: 0x2196F3
});
typeText.anchor.set(0.5, 0.5);
typeText.y = 10;
self.addChild(typeText);
var pointsText = new Text2('Points: 0', {
size: 20,
fill: 0x4CAF50
});
pointsText.anchor.set(0.5, 0.5);
pointsText.y = 40;
self.addChild(pointsText);
self.featureData = null;
self.selected = false;
self.setFeature = function (data) {
self.featureData = data;
nameText.setText(data.name);
typeText.setText(data.type);
pointsText.setText('Points: ' + data.basePoints + ' | Cost: $' + data.cost);
var typeColors = {
'Graphics': 0xff5722,
'Sound': 0x9c27b0,
'Gameplay': 0x2196f3
};
icon.tint = typeColors[data.type] || 0xffc107;
};
self.setSelected = function (selected) {
self.selected = selected;
bg.tint = selected ? 0xe94560 : 0xffffff;
};
self.down = function () {
if (self.onClick) {
self.onClick(self);
}
};
return self;
});
var GameHistoryCard = Container.expand(function () {
var self = Container.call(this);
var bg = self.attachAsset('card', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.5,
scaleY: 0.6
});
var nameText = new Text2('Game Name', {
size: 30,
fill: 0xFFFFFF
});
nameText.anchor.set(0.5, 0.5);
nameText.y = -30;
self.addChild(nameText);
var salesText = new Text2('Sales: 0', {
size: 25,
fill: 0x4CAF50
});
salesText.anchor.set(0.5, 0.5);
salesText.y = 10;
self.addChild(salesText);
self.gameData = null;
self.setGameData = function (data) {
self.gameData = data;
nameText.setText(data.name);
var salesInfo = data.currentDailySales > 0 ? 'Sales: ' + data.totalSales + ' (Active)' : 'Sales: ' + data.totalSales + ' (Ended)';
salesText.setText(salesInfo);
bg.tint = data.currentDailySales > 0 ? 0x0f3460 : 0x16213e;
};
self.down = function () {
if (self.onClick) {
self.onClick(self.gameData);
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x1a1a2e
});
/****
* Game Code
****/
// Game state
function _typeof2(o) {
"@babel/helpers - typeof";
return _typeof2 = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) {
return typeof o;
} : function (o) {
return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o;
}, _typeof2(o);
}
function _typeof(o) {
"@babel/helpers - typeof";
return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) {
return typeof o;
} : function (o) {
return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o;
}, _typeof(o);
}
var gameState = {
money: 50000,
developers: [],
currentProject: null,
completedGames: 0,
marketTrends: [],
currentDay: 1,
releasedGames: [],
maxHireableDevelopers: 1,
studioLevel: 1,
studioUpgradeCost: 5000,
fans: 0,
// Toplam fan sayısı
mainCharacter: {
name: "You",
level: 1,
upgradeCost: 2000,
skill: 2,
specialty: "All",
featurePoints: {
Graphics: 1,
Sound: 1,
Gameplay: 1
}
},
gameHistory: [],
researchedFeatures: {
Graphics: [],
Sound: [],
Gameplay: [],
GameGenres: []
},
currentResearch: null,
// --- Feature selection limit per category ---
featureSelectionLimit: {
Graphics: 1,
Sound: 1,
Gameplay: 1
}
};
// Current game name being created
var currentGameName = '';
// Game name display at top
var gameNameDisplay = new Text2('', {
size: 45,
fill: 0xFFFFFF
});
gameNameDisplay.anchor.set(0.5, 0);
gameNameDisplay.y = 10;
LK.gui.top.addChild(gameNameDisplay);
// Available developers pool
var developerPool = [{
name: 'Alex',
specialty: 'Graphics',
skill: 3,
cost: 4000
}, {
name: 'Sam',
specialty: 'Sound',
skill: 4,
cost: 4000
}, {
name: 'Jordan',
specialty: 'Gameplay',
skill: 5,
cost: 4000
}, {
name: 'Morgan',
specialty: 'Graphics',
skill: 6,
cost: 8000
}, {
name: 'Casey',
specialty: 'Sound',
skill: 7,
cost: 8000
}, {
name: 'Drew',
specialty: 'Gameplay',
skill: 8,
cost: 8000
}, {
name: 'Taylor',
specialty: 'Graphics',
skill: 9,
cost: 12000
}, {
name: 'Jamie',
specialty: 'Sound',
skill: 10,
cost: 12000
}, {
name: 'Robin',
specialty: 'Gameplay',
skill: 11,
cost: 12000
}];
// Available features - expanded with research requirements
var featurePool = [{
name: 'Pixel Art',
type: 'Graphics',
basePoints: 3,
cost: 2000,
requiresResearch: false
}, {
name: '3D Models',
type: 'Graphics',
basePoints: 5,
cost: 2000,
requiresResearch: false
}, {
name: 'Particle Effects',
type: 'Graphics',
basePoints: 4,
cost: 2000,
requiresResearch: false
}, {
name: 'Soundtrack',
type: 'Sound',
basePoints: 3,
cost: 2000,
requiresResearch: false
}, {
name: 'Voice Acting',
type: 'Sound',
basePoints: 6,
cost: 2000,
requiresResearch: false
}, {
name: 'Sound Effects',
type: 'Sound',
basePoints: 4,
cost: 2000,
requiresResearch: false
}, {
name: 'RPG Elements',
type: 'Gameplay',
basePoints: 5,
cost: 2000,
requiresResearch: false
}, {
name: 'Multiplayer',
type: 'Gameplay',
basePoints: 7,
cost: 2000,
requiresResearch: false
}, {
name: 'Puzzles',
type: 'Gameplay',
basePoints: 4,
cost: 2000,
requiresResearch: false
}, {
name: 'Open World',
type: 'Gameplay',
basePoints: 8,
cost: 2000,
requiresResearch: false
}, {
name: 'Shaders',
type: 'Graphics',
basePoints: 6,
cost: 4000,
requiresResearch: true
}, {
name: 'Ray Tracing',
type: 'Graphics',
basePoints: 10,
cost: 6000,
requiresResearch: true
}, {
name: 'Motion Capture',
type: 'Graphics',
basePoints: 8,
cost: 4000,
requiresResearch: true
}, {
name: 'Procedural Generation',
type: 'Graphics',
basePoints: 7,
cost: 4000,
requiresResearch: true
}, {
name: 'Dynamic Lighting',
type: 'Graphics',
basePoints: 6,
cost: 4000,
requiresResearch: true
}, {
name: 'Orchestral Score',
type: 'Sound',
basePoints: 8,
cost: 4000,
requiresResearch: true
}, {
name: '3D Audio',
type: 'Sound',
basePoints: 7,
cost: 4000,
requiresResearch: true
}, {
name: 'Dynamic Music',
type: 'Sound',
basePoints: 6,
cost: 4000,
requiresResearch: true
}, {
name: 'Environmental Audio',
type: 'Sound',
basePoints: 5,
cost: 4000,
requiresResearch: true
}, {
name: 'Foley Effects',
type: 'Sound',
basePoints: 6,
cost: 4000,
requiresResearch: true
}, {
name: 'Physics Engine',
type: 'Gameplay',
basePoints: 9,
cost: 6000,
requiresResearch: true
}, {
name: 'AI Systems',
type: 'Gameplay',
basePoints: 10,
cost: 6000,
requiresResearch: true
}, {
name: 'Skill Trees',
type: 'Gameplay',
basePoints: 6,
cost: 4000,
requiresResearch: true
}, {
name: 'Crafting System',
type: 'Gameplay',
basePoints: 7,
cost: 4000,
requiresResearch: true
}, {
name: 'Dialogue System',
type: 'Gameplay',
basePoints: 5,
cost: 4000,
requiresResearch: true
}];
// Game genres that can be researched
var gameGenres = [{
name: 'Action',
baseMultiplier: 1.2,
trendChance: 0.3,
researchCost: 4000,
requiresResearch: false
}, {
name: 'Adventure',
baseMultiplier: 1.1,
trendChance: 0.25,
researchCost: 4000,
requiresResearch: false
}, {
name: 'Puzzle',
baseMultiplier: 1.0,
trendChance: 0.2,
researchCost: 4000,
requiresResearch: false
}, {
name: 'Racing',
baseMultiplier: 1.3,
trendChance: 0.35,
researchCost: 8000,
requiresResearch: true
}, {
name: 'Strategy',
baseMultiplier: 1.4,
trendChance: 0.3,
researchCost: 8000,
requiresResearch: true
}, {
name: 'Simulation',
baseMultiplier: 1.2,
trendChance: 0.25,
researchCost: 8000,
requiresResearch: true
}, {
name: 'RPG',
baseMultiplier: 1.5,
trendChance: 0.4,
researchCost: 12000,
requiresResearch: true
}, {
name: 'FPS',
baseMultiplier: 1.4,
trendChance: 0.35,
researchCost: 12000,
requiresResearch: true
}, {
name: 'Horror',
baseMultiplier: 1.3,
trendChance: 0.25,
researchCost: 12000,
requiresResearch: true
}, {
name: 'Sports',
baseMultiplier: 1.2,
trendChance: 0.3,
researchCost: 12000,
requiresResearch: true
}];
// UI Elements
var moneyText = new Text2('Money: $10000', {
size: 50,
fill: 0x4CAF50
});
moneyText.anchor.set(1, 0);
moneyText.x = 0;
moneyText.y = 0;
LK.gui.topRight.addChild(moneyText);
var developersText = new Text2('Developers: 0', {
size: 40,
fill: 0xFFFFFF
});
developersText.anchor.set(1, 0);
developersText.x = 0;
developersText.y = moneyText.y + moneyText.height + 8;
LK.gui.topRight.addChild(developersText);
var gamesText = new Text2('Games Released: 0', {
size: 40,
fill: 0xFFC107
});
gamesText.anchor.set(1, 0);
gamesText.x = 0;
gamesText.y = developersText.y + developersText.height + 8;
LK.gui.topRight.addChild(gamesText);
// Fan count and bonus UI
var fanText = new Text2('Fan: 0', {
size: 40,
fill: 0x2196F3
});
fanText.anchor.set(1, 0);
fanText.x = 0;
fanText.y = gamesText.y + gamesText.height + 8;
LK.gui.topRight.addChild(fanText);
var fanBonusText = new Text2('Sales Bonus: %0', {
size: 32,
fill: 0x4CAF50
});
fanBonusText.anchor.set(1, 0);
fanBonusText.x = 0;
fanBonusText.y = fanText.y + fanText.height + 8;
LK.gui.topRight.addChild(fanBonusText);
var dayText = new Text2('Day: 1', {
size: 40,
fill: 0x2196F3
});
dayText.anchor.set(1, 0);
dayText.x = 0;
dayText.y = fanBonusText.y + fanBonusText.height + 8;
LK.gui.topRight.addChild(dayText);
// --- Sales & Revenue Log UI ---
var salesLogContainer = new Container();
salesLogContainer.x = 2048 - 40; // right align
salesLogContainer.y = 220; // just below dayText
LK.gui.topRight.addChild(salesLogContainer);
var salesLogEntries = []; // keep references to Text2 objects for updating/removal
function updateSalesLog() {
// Remove old entries
for (var i = 0; i < salesLogEntries.length; i++) {
salesLogEntries[i].destroy();
}
salesLogEntries = [];
// Show up to 5 most recent games (active and ended)
var allGames = gameState.releasedGames.concat(gameState.gameHistory);
var recentGames = allGames.slice(-5).reverse();
var y = 0;
for (var i = 0; i < recentGames.length; i++) {
var g = recentGames[i];
var isActive = g.currentDailySales > 0;
var pricePerCopy = typeof g.price === "number" ? g.price : 1;
var revenue = Math.floor((g.currentDailySales || 0) * pricePerCopy);
var txt = new Text2(g.name + ': +' + (g.currentDailySales || 0) + ' | $' + revenue, {
size: 28,
fill: isActive ? 0x4CAF50 : 0x888888
});
txt.anchor.set(1, 0);
txt.x = 0;
txt.y = y;
salesLogContainer.addChild(txt);
salesLogEntries.push(txt);
y += 36;
}
}
// Main menu container
var mainMenu = new Container();
game.addChild(mainMenu);
// --- How to Play Button and Info Popup ---
var howToPlayBtn = new Button();
howToPlayBtn.setLabel('How to Play?');
howToPlayBtn.x = 1024;
howToPlayBtn.y = 180;
howToPlayBtn.onClick = function () {
// Remove previous popup if any
if (mainMenu.howToPlayPopup) {
mainMenu.howToPlayPopup.destroy();
mainMenu.howToPlayPopup = null;
}
var popup = new Container();
popup.x = 1024;
popup.y = 600;
var bg = LK.getAsset('card', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2.5,
scaleY: 2.2
});
bg.tint = 0x16213e;
popup.addChild(bg);
var infoText = new Text2("Welcome to Game Dev Studio!\n\n" + "• Hire talented developers to join your team.\n" + "• Start new projects and select the best features for your games.\n" + "• Follow market trends and research new technologies to stay ahead.\n" + "• Release your games, earn money, and gain fans.\n" + "• Upgrade your studio to hire more developers and unlock new possibilities.\n" + "• Compete with rival companies and become the top game studio!\n\n" + "Tip: Use the main menu to access hiring, research, platforms, and more.", {
size: 36,
fill: 0xFFFFFF,
align: "center"
});
infoText.anchor.set(0.5, 0.5);
infoText.x = 0;
infoText.y = -40;
popup.addChild(infoText);
var closeBtn = new Button();
closeBtn.setLabel('Close');
closeBtn.x = 0;
closeBtn.y = 320;
closeBtn.onClick = function () {
if (mainMenu.howToPlayPopup) {
mainMenu.howToPlayPopup.destroy();
mainMenu.howToPlayPopup = null;
}
};
popup.addChild(closeBtn);
mainMenu.addChild(popup);
mainMenu.howToPlayPopup = popup;
};
mainMenu.addChild(howToPlayBtn);
var titleText = new Text2('Game Dev Studio', {
size: 80,
fill: 0xFFFFFF
});
titleText.anchor.set(0.5, 0.5);
titleText.x = 1024;
titleText.y = 300;
mainMenu.addChild(titleText);
var hireDeveloperBtn = new Button();
hireDeveloperBtn.setLabel('Hire Developer');
hireDeveloperBtn.x = 1024;
hireDeveloperBtn.y = 750;
hireDeveloperBtn.onClick = showHireMenu;
mainMenu.addChild(hireDeveloperBtn);
var startProjectBtn = new Button();
startProjectBtn.setLabel('Start Project');
startProjectBtn.x = 1024;
startProjectBtn.y = 900;
startProjectBtn.onClick = showProjectMenu;
mainMenu.addChild(startProjectBtn);
var allGamesBtn = new Button();
allGamesBtn.setLabel('All Released Games');
allGamesBtn.x = 1024;
allGamesBtn.y = 1050;
allGamesBtn.onClick = showAllGamesMenu;
mainMenu.addChild(allGamesBtn);
var researchBtn = new Button();
researchBtn.setLabel('Research');
researchBtn.x = 1024;
researchBtn.y = 1200;
researchBtn.onClick = showResearchMenu;
mainMenu.addChild(researchBtn);
// (Game Engine button removed)
// --- Bank Button ---
var bankBtn = new Button();
bankBtn.setLabel('Bank');
bankBtn.x = 1024;
bankBtn.y = 1550;
bankBtn.onClick = showBankMenu;
mainMenu.addChild(bankBtn);
// --- Platform Button ---
var platformBtn = new Button();
platformBtn.setLabel('Platform');
platformBtn.x = 1024;
platformBtn.y = 1650;
platformBtn.onClick = showPlatformMenu;
mainMenu.addChild(platformBtn);
// --- Fan Button ---
var fanBtn = new Button();
fanBtn.setLabel('Fan');
fanBtn.x = 1024;
fanBtn.y = 1800;
fanBtn.onClick = showFanMenu;
mainMenu.addChild(fanBtn);
// --- Fan Store Button ---
var fanStoreBtn = new Button();
fanStoreBtn.setLabel('Fan Store');
fanStoreBtn.x = 1024;
fanStoreBtn.y = 1920;
fanStoreBtn.onClick = showFanStoreMenu;
mainMenu.addChild(fanStoreBtn);
// --- Rivals Button ---
var rivalsBtn = new Button();
rivalsBtn.setLabel('Rivals');
rivalsBtn.x = 1024;
rivalsBtn.y = 2040; // 2 satır altı (120px aralık)
rivalsBtn.onClick = showRivalsMenu;
mainMenu.addChild(rivalsBtn);
// --- Rivals Games Button ---
var rivalsGamesBtn = new Button();
rivalsGamesBtn.setLabel('Rivals Games');
rivalsGamesBtn.x = 1024;
rivalsGamesBtn.y = 2160; // Rivals butonunun hemen altında
rivalsGamesBtn.onClick = showRivalsGamesMenu;
mainMenu.addChild(rivalsGamesBtn);
// --- Bank Menu UI ---
var bankMenu = new Container();
bankMenu.visible = false;
game.addChild(bankMenu);
var bankTitle = new Text2('Bank', {
size: 60,
fill: 0xFFFFFF
});
bankTitle.anchor.set(0.5, 0.5);
bankTitle.x = 1024;
bankTitle.y = 200;
bankMenu.addChild(bankTitle);
// Bilgi yazısı: Banka sistemi hakkında açıklama (Geri tuşunun 3 satır yukarısına)
var bankInfoText = new Text2("Bank System:\n" + "- You must have no outstanding debt to take a new loan.\n" + "- If you pay off a loan early, you pay 10% extra of the original amount.\n" + "- When a loan matures, no extra interest is added; the debt waits until paid.\n" + "- You can deposit up to 50% of your cash as a deposit.\n" + "- When a deposit matures, interest stops. Use the withdraw button to collect your money.", {
size: 32,
fill: 0xFFC107,
align: "center"
});
bankInfoText.anchor.set(0.5, 1);
bankInfoText.x = 1024;
bankInfoText.y = 2400 - 3 * 50; // 3 satır yukarı (her satır ~50px)
bankMenu.addChild(bankInfoText);
var bankBackBtn = new Button();
bankBackBtn.setLabel('Back');
bankBackBtn.x = 1024;
bankBackBtn.y = 2400;
bankBackBtn.onClick = function () {
bankMenu.visible = false;
mainMenu.visible = true;
};
bankMenu.addChild(bankBackBtn);
// --- Bank state ---
if (!gameState.bank) {
gameState.bank = {
credit: 0,
creditDueDay: 0,
deposit: 0,
depositDueDay: 0
};
}
// --- Show Bank Menu function ---
function showBankMenu() {
mainMenu.visible = false;
bankMenu.visible = true;
// Remove old UI except title and back and info text
for (var i = bankMenu.children.length - 1; i >= 0; i--) {
var child = bankMenu.children[i];
if (child !== bankTitle && child !== bankBackBtn && child !== bankInfoText) {
child.destroy();
}
}
// Re-add info text if not present
if (!bankMenu.children.includes(bankInfoText)) {
bankMenu.addChild(bankInfoText);
}
// Info text
var infoText = new Text2('You can take a loan or make a deposit.', {
size: 36,
fill: 0x4CAF50
});
infoText.anchor.set(0.5, 0.5);
infoText.x = 1024;
infoText.y = 350;
bankMenu.addChild(infoText);
// --- Credit Section ---
var creditTitle = new Text2('Take Loan', {
size: 40,
fill: 0xFFC107
});
creditTitle.anchor.set(0.5, 0.5);
creditTitle.x = 1024;
creditTitle.y = 500;
bankMenu.addChild(creditTitle);
var creditAmount = 10000;
var creditInterest = 0.15; // %15 faiz
var creditDuration = 10; // 10 gün vade
var creditBtn = new Button();
creditBtn.setLabel('Take Loan (15% interest, 10 days, Limit: 20% of cash)');
creditBtn.x = 1024;
creditBtn.y = 600;
creditBtn.onClick = function () {
// Prevent new credit if there is any unpaid debt (even if overdue)
if (gameState.bank.credit > 0) {
// Show notification
var notif = new Container();
var bg = LK.getAsset('card', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2,
scaleY: 0.5
});
bg.tint = 0xE94560;
notif.addChild(bg);
var txt = new Text2('You must pay your previous loan first!', {
size: 32,
fill: 0xFFFFFF
});
txt.anchor.set(0.5, 0.5);
notif.addChild(txt);
notif.x = 1024;
notif.y = 800;
notif.alpha = 0;
game.addChild(notif);
tween(notif, {
alpha: 1
}, {
duration: 400,
onFinish: function onFinish() {
LK.setTimeout(function () {
tween(notif, {
alpha: 0
}, {
duration: 400,
onFinish: function onFinish() {
notif.destroy();
}
});
}, 1500);
}
});
return;
}
// Calculate credit limit as 20% of current cash (rounded down to nearest 1000)
var maxCredit = Math.floor(gameState.money * 0.2 / 1000) * 1000;
if (maxCredit < 1000) maxCredit = 1000; // Minimum 1000₺
var creditInterest = 0.15; // %15 faiz
var creditDuration = 10; // 10 gün vade
if (maxCredit <= 0) {
// Show notification for no available credit
var notif = new Container();
var bg = LK.getAsset('card', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2,
scaleY: 0.5
});
bg.tint = 0xE94560;
notif.addChild(bg);
var txt = new Text2('No loan limit! (You have too little cash)', {
size: 32,
fill: 0xFFFFFF
});
txt.anchor.set(0.5, 0.5);
notif.addChild(txt);
notif.x = 1024;
notif.y = 800;
notif.alpha = 0;
game.addChild(notif);
tween(notif, {
alpha: 1
}, {
duration: 400,
onFinish: function onFinish() {
LK.setTimeout(function () {
tween(notif, {
alpha: 0
}, {
duration: 400,
onFinish: function onFinish() {
notif.destroy();
}
});
}, 1500);
}
});
return;
}
// Grant credit
gameState.money += maxCredit;
gameState.bank.credit = maxCredit * (1 + creditInterest);
gameState.bank.creditDueDay = gameState.currentDay + creditDuration;
updateUI();
showBankMenu();
LK.getSound('success').play();
};
bankMenu.addChild(creditBtn);
var creditStatus = '';
if (gameState.bank.credit > 0 && gameState.currentDay < gameState.bank.creditDueDay) {
creditStatus = 'Remaining Debt: ' + Math.round(gameState.bank.credit) + ' | Due Day: ' + gameState.bank.creditDueDay;
} else if (gameState.bank.credit > 0 && gameState.currentDay >= gameState.bank.creditDueDay) {
creditStatus = 'Loan matured! Debt: ' + Math.round(gameState.bank.credit);
} else {
creditStatus = 'No active loan.';
}
var creditStatusText = new Text2(creditStatus, {
size: 30,
fill: 0xFFFFFF
});
creditStatusText.anchor.set(0.5, 0.5);
creditStatusText.x = 1024;
creditStatusText.y = 670;
bankMenu.addChild(creditStatusText);
// --- Deposit Section ---
var depositTitle = new Text2('Make Deposit', {
size: 40,
fill: 0x2196F3
});
depositTitle.anchor.set(0.5, 0.5);
depositTitle.x = 1024;
depositTitle.y = 850;
bankMenu.addChild(depositTitle);
// Ava: Mevduat yatırma oranı, nakit paramızın maksimum %50'sine kadar olmalı
var depositInterest = 0.10; // %10 faiz
var depositDuration = 10; // 10 gün vade
// Hesaplanan maksimum mevduat miktarı (en az 1000₺, 1000'lik katlar)
var maxDeposit = Math.floor(gameState.money * 0.5 / 1000) * 1000;
if (maxDeposit < 1000) maxDeposit = 1000;
var depositAmount = maxDeposit;
var depositBtn = new Button();
depositBtn.setLabel(maxDeposit + ' Deposit (10% interest, 10 days)');
depositBtn.x = 1024;
depositBtn.y = 950;
depositBtn.onClick = function () {
// Only allow one active deposit at a time
if (gameState.bank.deposit > 0 && gameState.currentDay < gameState.bank.depositDueDay) {
// Show notification
var notif = new Container();
var bg = LK.getAsset('card', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2,
scaleY: 0.5
});
bg.tint = 0xE94560;
notif.addChild(bg);
var txt = new Text2('Your previous deposit is still maturing!', {
size: 32,
fill: 0xFFFFFF
});
txt.anchor.set(0.5, 0.5);
notif.addChild(txt);
notif.x = 1024;
notif.y = 1150;
notif.alpha = 0;
game.addChild(notif);
tween(notif, {
alpha: 1
}, {
duration: 400,
onFinish: function onFinish() {
LK.setTimeout(function () {
tween(notif, {
alpha: 0
}, {
duration: 400,
onFinish: function onFinish() {
notif.destroy();
}
});
}, 1500);
}
});
return;
}
if (gameState.money < depositAmount) {
// Show notification
var notif = new Container();
var bg = LK.getAsset('card', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2,
scaleY: 0.5
});
bg.tint = 0xE94560;
notif.addChild(bg);
var txt = new Text2('Not enough money!', {
size: 32,
fill: 0xFFFFFF
});
txt.anchor.set(0.5, 0.5);
notif.addChild(txt);
notif.x = 1024;
notif.y = 1150;
notif.alpha = 0;
game.addChild(notif);
tween(notif, {
alpha: 1
}, {
duration: 400,
onFinish: function onFinish() {
LK.setTimeout(function () {
tween(notif, {
alpha: 0
}, {
duration: 400,
onFinish: function onFinish() {
notif.destroy();
}
});
}, 1500);
}
});
return;
}
gameState.money -= depositAmount;
gameState.bank.deposit = depositAmount * (1 + depositInterest);
gameState.bank.depositDueDay = gameState.currentDay + depositDuration;
updateUI();
showBankMenu();
LK.getSound('success').play();
};
bankMenu.addChild(depositBtn);
var depositStatus = '';
if (gameState.bank.deposit > 0 && gameState.currentDay < gameState.bank.depositDueDay) {
depositStatus = 'Deposit: ' + Math.round(gameState.bank.deposit) + ' | Due Day: ' + gameState.bank.depositDueDay;
} else if (gameState.bank.deposit > 0 && gameState.currentDay >= gameState.bank.depositDueDay) {
depositStatus = 'Deposit matured! Withdrawable: ' + Math.round(gameState.bank.deposit);
} else {
depositStatus = 'No active deposit.';
}
var depositStatusText = new Text2(depositStatus, {
size: 30,
fill: 0xFFFFFF
});
depositStatusText.anchor.set(0.5, 0.5);
depositStatusText.x = 1024;
depositStatusText.y = 1020;
bankMenu.addChild(depositStatusText);
// --- Deposit Withdraw Button (if matured) ---
if (gameState.bank.deposit > 0 && gameState.currentDay >= gameState.bank.depositDueDay) {
var withdrawBtn = new Button();
withdrawBtn.setLabel('Withdraw Deposit (+ ' + Math.round(gameState.bank.deposit) + ')');
withdrawBtn.x = 1024;
withdrawBtn.y = 1100;
withdrawBtn.onClick = function () {
gameState.money += Math.round(gameState.bank.deposit);
gameState.bank.deposit = 0;
gameState.bank.depositDueDay = 0;
updateUI();
showBankMenu();
LK.getSound('success').play();
};
bankMenu.addChild(withdrawBtn);
}
// --- Credit Pay Button (if matured or early) ---
// Early payment: allow if credit > 0 and not overdue
if (gameState.bank.credit > 0 && gameState.currentDay < gameState.bank.creditDueDay) {
var earlyPayBtn = new Button();
// Early payment is original credit + 10% of original credit (not 10% of current debt)
// Calculate original credit amount (principal)
var originalCredit = Math.round(gameState.bank.credit / 1.15); // since credit = principal * 1.15
var earlyPayAmount = Math.round(originalCredit * 1.10); // %10 fazlası
earlyPayBtn.setLabel('Pay Early (-' + earlyPayAmount + ', 10% interest)');
earlyPayBtn.x = 1024;
earlyPayBtn.y = 750;
earlyPayBtn.onClick = function () {
if (gameState.money >= earlyPayAmount) {
gameState.money -= earlyPayAmount;
gameState.bank.credit = 0;
gameState.bank.creditDueDay = 0;
updateUI();
showBankMenu();
LK.getSound('success').play();
} else {
// Show notification
var notif = new Container();
var bg = LK.getAsset('card', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2,
scaleY: 0.5
});
bg.tint = 0xE94560;
notif.addChild(bg);
var txt = new Text2('Not enough money!', {
size: 32,
fill: 0xFFFFFF
});
txt.anchor.set(0.5, 0.5);
notif.addChild(txt);
notif.x = 1024;
notif.y = 900;
notif.alpha = 0;
game.addChild(notif);
tween(notif, {
alpha: 1
}, {
duration: 400,
onFinish: function onFinish() {
LK.setTimeout(function () {
tween(notif, {
alpha: 0
}, {
duration: 400,
onFinish: function onFinish() {
notif.destroy();
}
});
}, 1500);
}
});
}
};
bankMenu.addChild(earlyPayBtn);
}
// Normal payment: if matured or overdue
if (gameState.bank.credit > 0 && gameState.currentDay >= gameState.bank.creditDueDay) {
var payBtn = new Button();
payBtn.setLabel('Pay Loan (-' + Math.round(gameState.bank.credit) + ')');
payBtn.x = 1024;
payBtn.y = 750;
payBtn.onClick = function () {
if (gameState.money >= Math.round(gameState.bank.credit)) {
gameState.money -= Math.round(gameState.bank.credit);
gameState.bank.credit = 0;
gameState.bank.creditDueDay = 0;
updateUI();
showBankMenu();
LK.getSound('success').play();
} else {
// Show notification
var notif = new Container();
var bg = LK.getAsset('card', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2,
scaleY: 0.5
});
bg.tint = 0xE94560;
notif.addChild(bg);
var txt = new Text2('Not enough money!', {
size: 32,
fill: 0xFFFFFF
});
txt.anchor.set(0.5, 0.5);
notif.addChild(txt);
notif.x = 1024;
notif.y = 900;
notif.alpha = 0;
game.addChild(notif);
tween(notif, {
alpha: 1
}, {
duration: 400,
onFinish: function onFinish() {
LK.setTimeout(function () {
tween(notif, {
alpha: 0
}, {
duration: 400,
onFinish: function onFinish() {
notif.destroy();
}
});
}, 1500);
}
});
}
};
bankMenu.addChild(payBtn);
}
}
// --- Rivals Games Menu UI ---
var rivalsGamesMenu = new Container();
rivalsGamesMenu.visible = false;
game.addChild(rivalsGamesMenu);
var rivalsGamesTitle = new Text2('Rivals Games', {
size: 60,
fill: 0xFFFFFF
});
rivalsGamesTitle.anchor.set(0.5, 0.5);
rivalsGamesTitle.x = 1024;
rivalsGamesTitle.y = 200;
rivalsGamesMenu.addChild(rivalsGamesTitle);
var rivalsGamesBackBtn = new Button();
rivalsGamesBackBtn.setLabel('Geri');
rivalsGamesBackBtn.x = 1024;
rivalsGamesBackBtn.y = 2400;
rivalsGamesBackBtn.onClick = function () {
rivalsGamesMenu.visible = false;
mainMenu.visible = true;
};
rivalsGamesMenu.addChild(rivalsGamesBackBtn);
// --- Helper: Show Rivals Games Menu ---
function showRivalsGamesMenu() {
mainMenu.visible = false;
rivalsGamesMenu.visible = true;
// Eski kartları temizle (başlık ve geri hariç)
for (var i = rivalsGamesMenu.children.length - 1; i >= 0; i--) {
var child = rivalsGamesMenu.children[i];
if (child !== rivalsGamesTitle && child !== rivalsGamesBackBtn) {
child.destroy();
}
}
// Tüm rakiplerin çıkardığı oyunları topla
var allRivalGames = [];
for (var i = 0; i < gameState.rivals.length; i++) {
var rival = gameState.rivals[i];
if (rival.games && rival.games.length > 0) {
for (var j = 0; j < rival.games.length; j++) {
var g = rival.games[j];
// Her oyun için rakip adı ekle
allRivalGames.push({
name: g.name,
revenue: g.revenue,
releaseDay: g.releaseDay,
rivalName: rival.name
});
}
}
}
// Oyunları en yeniye göre sırala (büyükten küçüğe)
allRivalGames.sort(function (a, b) {
return b.releaseDay - a.releaseDay;
});
// Hiç oyun yoksa bilgi göster
if (allRivalGames.length === 0) {
var noRivalGamesText = new Text2('No rival has released a game yet', {
size: 40,
fill: 0xFFFFFF
});
noRivalGamesText.anchor.set(0.5, 0.5);
noRivalGamesText.x = 1024;
noRivalGamesText.y = 600;
rivalsGamesMenu.addChild(noRivalGamesText);
return;
}
// 4 sütun, 7 satır grid (28 oyun gösterilecek şekilde)
var cols = 4;
var xStart = 320,
yStart = 440 * 1.1,
xSpacing = 370 * 1.1,
ySpacing = 180 * 1.1;
for (var i = 0; i < allRivalGames.length && i < 28; i++) {
var game = allRivalGames[i];
var col = i % cols,
row = Math.floor(i / cols);
var container = new Container();
container.x = xStart + col * xSpacing;
container.y = yStart + row * ySpacing;
// Kart arka planı
var bg = LK.getAsset('card', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.0,
scaleY: 0.45
});
container.addChild(bg);
// Oyun adı
var nameText = new Text2(game.name, {
size: 28,
fill: 0xFFFFFF
});
nameText.anchor.set(0.5, 0.5);
nameText.y = -30;
container.addChild(nameText);
// Rakip firma adı
var rivalText = new Text2('Company: ' + game.rivalName, {
size: 24,
fill: 0x2196F3
});
rivalText.anchor.set(0.5, 0.5);
rivalText.y = 10;
container.addChild(rivalText);
// Gelir veya Zarar
var revenueLabel = 'Gelir: $' + game.revenue;
var revenueColor = 0x4CAF50;
if (typeof game.revenue === "number" && game.revenue === 0) {
// Zarar varsa, revenue 0 olarak tutuluyor, ama aslında zarar vardı.
// Oyun objesinde orijinal zarar bilgisini bulmak için rakip firmanın oyunlarını arayalım.
var actualLoss = 0;
for (var ri = 0; ri < gameState.rivals.length; ri++) {
var rival = gameState.rivals[ri];
if (rival.name === game.rivalName && rival.games && rival.games.length > 0) {
for (var gj = 0; gj < rival.games.length; gj++) {
var g2 = rival.games[gj];
if (g2.name === game.name && g2.releaseDay === game.releaseDay) {
// Orijinal revenue negatifse, onu göster
if (typeof g2._originalLoss === "number" && g2._originalLoss > 0) {
actualLoss = g2._originalLoss;
} else if (typeof g2._originalRevenue === "number" && g2._originalRevenue < 0) {
actualLoss = -g2._originalRevenue;
}
}
}
}
}
revenueLabel = 'Loss: $' + (actualLoss > 0 ? actualLoss : 0);
revenueColor = 0xE94560;
}
var revenueText = new Text2(revenueLabel, {
size: 24,
fill: revenueColor
});
revenueText.anchor.set(0.5, 0.5);
revenueText.y = 40;
container.addChild(revenueText);
// Çıkış günü
var dayText = new Text2('Day: ' + game.releaseDay, {
size: 22,
fill: 0xFFC107
});
dayText.anchor.set(0.5, 0.5);
dayText.y = 70;
container.addChild(dayText);
rivalsGamesMenu.addChild(container);
}
}
// --- Rivals Menu UI ---
var rivalsMenu = new Container();
rivalsMenu.visible = false;
game.addChild(rivalsMenu);
var rivalsTitle = new Text2('Rival Companies', {
size: 60,
fill: 0xFFFFFF
});
rivalsTitle.anchor.set(0.5, 0.5);
rivalsTitle.x = 1024;
rivalsTitle.y = 200;
rivalsMenu.addChild(rivalsTitle);
var rivalsBackBtn = new Button();
rivalsBackBtn.setLabel('Back');
rivalsBackBtn.x = 1024;
rivalsBackBtn.y = 2400;
rivalsBackBtn.onClick = function () {
rivalsMenu.visible = false;
mainMenu.visible = true;
};
rivalsMenu.addChild(rivalsBackBtn);
// --- Rivals Data ---
if (!gameState.rivals) {
// 28 popüler firma, her biri 20-30 günde bir oyun çıkarır
var rivalNames = ["PixelForge", "BitMasters", "RetroSoft", "NextGen Games", "Funbyte", "DreamPixel", "CodeCrafters", "GameNest", "Playverse", "IndieGiant", "ArcadiaWorks", "QuantumPlay", "StudioNova", "BlueBox", "RedShift", "MegaFun", "GameWave", "Starbyte", "EpicPlay", "VirtuaDev",
// 8 yeni firma
"NeonPixel", "TurboPlay", "GameSmiths", "HyperNova", "PlayMakers", "PixelPioneers", "FunLab", "InfinityGames"];
gameState.rivals = [];
for (var i = 0; i < rivalNames.length; i++) {
var baseValue = 100000 + Math.floor(Math.random() * 100000); // 100k-200k arası başlangıç değeri
var rival = {
name: rivalNames[i],
value: baseValue,
ownedPercent: 0,
// Oyuncunun sahip olduğu yüzde
games: [],
lastReleaseDay: 1 + Math.floor(Math.random() * 10),
// İlk oyun çıkış günü
releaseInterval: 20 + Math.floor(Math.random() * 11),
// 20-30 gün arası
avgRevenue: 0 // Son 3 oyunun ortalaması
};
gameState.rivals.push(rival);
}
// Oyuncunun şirket değeri başlangıçta: anlık nakit paramın %20'si + sahip olunan şirketlerin değerleri toplamı
var cash = gameState.money || 0;
var cashPart = cash * 0.20;
var ownedValueSum = 0;
if (gameState.rivals && gameState.rivals.length > 0) {
for (var i = 0; i < gameState.rivals.length; i++) {
var rival = gameState.rivals[i];
if (rival.ownedPercent && rival.ownedPercent > 0) {
ownedValueSum += Math.floor((rival.value || 0) * (rival.ownedPercent / 100));
}
}
}
gameState.companyValue = Math.floor(cashPart + ownedValueSum);
}
// --- Helper: Rival yeni oyun çıkarır ---
function rivalReleaseGame(rival, day) {
// Oyun ismi ve gelirini üret
var gameNames = ["Super", "Mega", "Ultra", "Epic", "Legend", "Pixel", "Quest", "Saga", "Chronicles", "World"];
var gameSuffix = ["Adventure", "Battle", "Story", "Kingdom", "Odyssey", "Arena", "Tycoon", "Empire", "Run", "Hero"];
var name = gameNames[Math.floor(Math.random() * gameNames.length)] + " " + gameSuffix[Math.floor(Math.random() * gameSuffix.length)];
// Rakip oyun kazancı, rakip şirket değerinin %1-%20 aralığında kâr veya %1-%20 aralığında zarar olacak şekilde ayarlandı
var percent = (Math.random() < 0.5 ? -1 : 1) * (0.01 + Math.random() * 0.19); // -0.01 ile -0.20 veya +0.01 ile +0.20 arası
var baseValue = rival.value || 100000;
var revenue = Math.floor(baseValue * Math.abs(percent));
var originalRevenue = revenue;
if (percent < 0) {
revenue = -revenue;
}
var originalLoss = 0;
if (revenue < 0) {
originalLoss = -revenue;
revenue = 0;
}
var game = {
name: name,
releaseDay: day,
revenue: revenue,
_originalRevenue: percent < 0 ? -originalRevenue : originalRevenue,
_originalLoss: originalLoss
};
rival.games.push(game);
// Sadece son 3 oyunun ortalamasını tut
if (rival.games.length > 3) rival.games = rival.games.slice(-3);
// Firma değerini anlık olarak kâr/zarara göre değiştir: kâr ise artır, zarar ise azalt
if (revenue > 0) {
rival.value += revenue + Math.floor(revenue * 0.1);
} else if (originalLoss > 0) {
rival.value -= originalLoss;
}
if (rival.value < 0) rival.value = 0;
// Son 3 oyunun ortalamasını güncelle
var sum = 0;
for (var i = 0; i < rival.games.length; i++) sum += rival.games[i].revenue;
rival.avgRevenue = Math.floor(sum / rival.games.length);
}
// --- Helper: Oyuncu rakipten hisse satın alır ---
function buyRivalShare(rival, percent) {
var price = Math.floor(rival.value * percent / 100);
if (gameState.money >= price && rival.ownedPercent + percent <= 100) {
gameState.money -= price;
rival.ownedPercent += percent;
// --- Ava: Satın alınan %10'luk hisse için alış fiyatını kaydet ---
if (!rival.sharePurchaseHistory) rival.sharePurchaseHistory = [];
for (var i = 0; i < percent / 10; i++) {
rival.sharePurchaseHistory.push(price);
}
// Ava: Increase player's company value by the purchased share percent of the rival's value
if (!gameState.companyValue) gameState.companyValue = 0;
gameState.companyValue += Math.floor(rival.value * (percent / 100));
updateUI();
LK.getSound('success').play();
showRivalsMenu();
}
}
// --- Helper: Rakiplerden oyuncuya gelir aktarımı ---
function processRivalIncome() {
for (var i = 0; i < gameState.rivals.length; i++) {
var rival = gameState.rivals[i];
if (rival.ownedPercent > 0 && rival.avgRevenue > 0) {
var income = Math.floor(rival.avgRevenue * (rival.ownedPercent / 100));
gameState.money += income;
}
}
}
// --- Rivals Menu Show ---
function showRivalsMenu() {
mainMenu.visible = false;
rivalsMenu.visible = true;
// Eski kartları temizle
for (var i = rivalsMenu.children.length - 1; i >= 0; i--) {
var child = rivalsMenu.children[i];
if (child !== rivalsTitle && child !== rivalsBackBtn) {
child.destroy();
}
}
// 4 sütunlu grid, 7 satır (ekrana sığacak şekilde 28 firma için)
// YENİ: yStart bir satır aşağı (ör: +40px), fontlar 30, hizalama güncellendi
var cols = 4;
var xStart = 320,
yStart = 440 * 1.1,
// 1 satır aşağı
xSpacing = 370 * 1.1,
ySpacing = 260 * 1.1;
for (var i = 0; i < gameState.rivals.length; i++) {
var rival = gameState.rivals[i];
var col = i % cols,
row = Math.floor(i / cols);
var container = new Container();
container.x = xStart + col * xSpacing;
container.y = yStart + row * ySpacing;
// Kart arka planı
var bg = LK.getAsset('card', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.0,
scaleY: 0.55
});
container.addChild(bg);
// Firma adı
var nameText = new Text2(rival.name, {
size: 30,
fill: 0xFFFFFF
});
nameText.anchor.set(0.5, 0.5);
nameText.y = -50;
container.addChild(nameText);
// Değer
var valueText = new Text2('Value: $' + rival.value, {
size: 30,
fill: 0x4CAF50
});
valueText.anchor.set(0.5, 0.5);
valueText.y = -10;
container.addChild(valueText);
// Sahip olunan yüzde
var ownedText = new Text2('Ownership: %' + rival.ownedPercent, {
size: 30,
fill: rival.ownedPercent >= 100 ? 0xFFC107 : 0x2196F3
});
ownedText.anchor.set(0.5, 0.5);
ownedText.y = 30;
container.addChild(ownedText);
// Son oyun(lar)
var lastGame = rival.games.length > 0 ? rival.games[rival.games.length - 1] : null;
var lastGameText = "";
if (lastGame) {
if (typeof lastGame.revenue === "number" && lastGame.revenue === 0) {
// Zarar miktarını göster
var actualLoss = 0;
if (typeof lastGame._originalLoss === "number" && lastGame._originalLoss > 0) {
actualLoss = lastGame._originalLoss;
} else if (typeof lastGame._originalRevenue === "number" && lastGame._originalRevenue < 0) {
actualLoss = -lastGame._originalRevenue;
}
lastGameText = "Last Game: " + lastGame.name + " (Loss: $" + (actualLoss > 0 ? actualLoss : 0) + ")";
} else {
lastGameText = "Last Game: " + lastGame.name + " ($" + lastGame.revenue + ")";
}
} else {
lastGameText = "No games yet";
}
var gameText = new Text2(lastGameText, {
size: 30,
fill: 0xFFFFFF
});
gameText.anchor.set(0.5, 0.5);
gameText.y = 70;
container.addChild(gameText);
// Sadece 1 tane %10'luk buton göster, %100 olana kadar
if (rival.ownedPercent < 100) {
var percent = 10;
var price = Math.floor(rival.value * percent / 100);
var buyBtn = new Button();
buyBtn.setLabel('Buy 10% ($' + price + ')');
buyBtn.x = -90;
buyBtn.y = 120;
buyBtn.scaleX = 0.7;
buyBtn.scaleY = 0.7;
buyBtn.onClick = function (rival, percent) {
return function () {
buyRivalShare(rival, percent);
};
}(rival, percent);
container.addChild(buyBtn);
// --- %10 Sat butonu ---
if (rival.ownedPercent >= 10) {
// --- Ava: Satış fiyatı, ilk alış fiyatına göre hesaplanmalı! ---
// Satın alınan her %10'luk hisse için alış fiyatını kaydet
if (!rival.sharePurchaseHistory) rival.sharePurchaseHistory = [];
// Eğer sharePurchaseHistory eksikse, eski kayıtlara göre doldur (eski kayıtsız oyunlar için)
var ownedShares = Math.floor(rival.ownedPercent / 10);
while (rival.sharePurchaseHistory.length < ownedShares) {
// Eski oyunlarda, ilk alış fiyatı olarak o anki değeri kaydet
rival.sharePurchaseHistory.push(Math.floor(rival.value * 0.1));
}
// Satılacak ilk %10'luk hissenin alış fiyatı
var sellPrice = rival.sharePurchaseHistory.length > 0 ? rival.sharePurchaseHistory[0] : price;
var sellBtn = new Button();
sellBtn.setLabel('Sell 10% (+$' + sellPrice + ')');
sellBtn.x = 90;
sellBtn.y = 120;
sellBtn.scaleX = 0.7;
sellBtn.scaleY = 0.7;
sellBtn.onClick = function (rival, percent) {
return function () {
// Satış işlemi: %10 hisseyi sat, para al, şirket değerini azalt
if (rival.ownedPercent >= percent && rival.sharePurchaseHistory && rival.sharePurchaseHistory.length > 0) {
rival.ownedPercent -= percent;
var soldPrice = rival.sharePurchaseHistory.shift();
gameState.money += soldPrice;
// Ava: Satınca şirket değerini de orantılı azalt
if (!gameState.companyValue) gameState.companyValue = 0;
gameState.companyValue -= Math.floor(rival.value * (percent / 100));
if (gameState.companyValue < 0) gameState.companyValue = 0;
updateUI();
LK.getSound('success').play();
showRivalsMenu();
}
};
}(rival, percent);
container.addChild(sellBtn);
}
} else {
// %100 ise, gelirinin tamamı oyuncuya geçer
var fullText = new Text2('All income is yours!', {
size: 30,
fill: 0xFFC107
});
fullText.anchor.set(0.5, 0.5);
fullText.y = 120;
container.addChild(fullText);
}
rivalsMenu.addChild(container);
}
// Rivals sayfasına girince şirket değerini anlık olarak güncelle
var cash = gameState.money || 0;
var cashPart = cash * 0.20;
var ownedValueSum = 0;
if (gameState.rivals && gameState.rivals.length > 0) {
for (var i = 0; i < gameState.rivals.length; i++) {
var rival = gameState.rivals[i];
if (rival.ownedPercent && rival.ownedPercent > 0) {
ownedValueSum += Math.floor((rival.value || 0) * (rival.ownedPercent / 100));
}
}
}
gameState.companyValue = Math.floor(cashPart + ownedValueSum);
// Oyuncu şirket değeri göster
if (rivalsMenu.companyValueText) rivalsMenu.companyValueText.destroy();
var companyValueText = new Text2('Your Company Value: $' + (gameState.companyValue || 0), {
size: 38,
fill: 0xE94560
});
companyValueText.anchor.set(0.5, 0.5);
companyValueText.x = 1024;
companyValueText.y = 350;
rivalsMenu.addChild(companyValueText);
rivalsMenu.companyValueText = companyValueText;
}
// --- Her gün başında rakipler yeni oyun çıkarır ve gelirler işlenir ---
if (!gameState._rivalLastDay) gameState._rivalLastDay = gameState.currentDay;
var _oldGameUpdate = game.update;
game.update = function () {
// Her gün başında
if (gameState.currentDay !== gameState._rivalLastDay) {
for (var i = 0; i < gameState.rivals.length; i++) {
var rival = gameState.rivals[i];
if (!rival.lastReleaseDay) rival.lastReleaseDay = 1;
if (!rival.releaseInterval) rival.releaseInterval = 25;
if (gameState.currentDay - rival.lastReleaseDay >= rival.releaseInterval) {
rivalReleaseGame(rival, gameState.currentDay);
rival.lastReleaseDay = gameState.currentDay;
}
}
// Oyuncuya rakiplerden gelir aktar
processRivalIncome();
// Oyuncu şirket değeri: Son 3 oyunun ortalamasının 5 katı + 50k
var myAvg = 0;
if (gameState.releasedGames && gameState.releasedGames.length > 0) {
var sum = 0,
count = 0;
for (var i = gameState.releasedGames.length - 1; i >= 0 && count < 3; i--, count++) {
var g = gameState.releasedGames[i];
var pricePerCopy = typeof g.price === "number" ? g.price : 1;
sum += (g.totalSales || 0) * pricePerCopy;
}
if (count > 0) myAvg = Math.floor(sum / count);
}
// --- Ava: Şirket değeri, anlık nakit paramın %20'si + aldığım şirketlerin değerleri toplamı olarak hesaplanır ---
var cash = gameState.money || 0;
var cashPart = cash * 0.20;
var ownedValueSum = 0;
if (gameState.rivals && gameState.rivals.length > 0) {
for (var i = 0; i < gameState.rivals.length; i++) {
var rival = gameState.rivals[i];
if (rival.ownedPercent && rival.ownedPercent > 0) {
ownedValueSum += Math.floor((rival.value || 0) * (rival.ownedPercent / 100));
}
}
}
gameState.companyValue = Math.floor(cashPart + ownedValueSum);
gameState._rivalLastDay = gameState.currentDay;
}
if (_oldGameUpdate) _oldGameUpdate();
};
// --- Fan Menu UI ---
var fanMenu = new Container();
fanMenu.visible = false;
game.addChild(fanMenu);
var fanTitle = new Text2('Fan Shop', {
size: 60,
fill: 0xFFFFFF
});
fanTitle.anchor.set(0.5, 0.5);
fanTitle.x = 1024;
fanTitle.y = 200;
fanMenu.addChild(fanTitle);
var fanBackBtn = new Button();
fanBackBtn.setLabel('Back');
fanBackBtn.x = 1024;
fanBackBtn.y = 2400;
fanBackBtn.onClick = function () {
fanMenu.visible = false;
mainMenu.visible = true;
};
fanMenu.addChild(fanBackBtn);
// Fan products (each gives fans)
var fanProducts = [{
name: "T-shirt",
price: 400,
fans: 40,
desc: "Studio t-shirt, gives 40 fans."
}, {
name: "Poster",
price: 800,
fans: 100,
desc: "Game poster, gives 100 fans."
}, {
name: "Mug",
price: 1500,
fans: 200,
desc: "Studio mug, gives 200 fans."
}, {
name: "Keychain",
price: 2500,
fans: 350,
desc: "Studio keychain, gives 350 fans."
}, {
name: "Mousepad",
price: 3500,
fans: 500,
desc: "Studio mousepad, gives 500 fans."
}, {
name: "Figure",
price: 6000,
fans: 900,
desc: "Collector's figure, gives 900 fans."
}, {
name: "Collector's Pack",
price: 12000,
fans: 2000,
desc: "Special collector's pack, gives 2000 fans."
}, {
name: "Hoodie",
price: 20000,
fans: 3500,
desc: "Studio hoodie, gives 3500 fans."
}, {
name: "Limited Edition Art",
price: 35000,
fans: 6000,
desc: "Limited edition art, gives 6000 fans."
}, {
name: "VIP Fan Club Membership",
price: 50000,
fans: 10000,
desc: "VIP fan club membership, gives 10000 fans."
}];
// --- Fan Store Products (20 items, computers and game-related) ---
var fanStoreProducts = [{
name: "Retro PC",
price: 2000,
desc: "Classic 80s computer.",
type: "hardware"
}, {
name: "Game Console",
price: 3000,
desc: "Legendary game console.",
type: "hardware"
}, {
name: "Joystick",
price: 500,
desc: "Retro joystick.",
type: "accessory"
}, {
name: "Gaming Mouse",
price: 800,
desc: "Precision gaming mouse.",
type: "accessory"
}, {
name: "Keyboard",
price: 700,
desc: "Mechanical keyboard.",
type: "accessory"
}, {
name: "Gaming Headset",
price: 1200,
desc: "Surround sound headset.",
type: "accessory"
}, {
name: "Game Magazine",
price: 300,
desc: "Collector's magazine.",
type: "magazine"
}, {
name: "Game Cartridge",
price: 600,
desc: "Rare game cartridge.",
type: "game"
}, {
name: "Collector's Edition",
price: 5000,
desc: "Special collector's box.",
type: "game"
}, {
name: "Game Poster",
price: 400,
desc: "Classic game poster.",
type: "poster"
}, {
name: "Desktop PC",
price: 4000,
desc: "Powerful desktop PC.",
type: "hardware"
}, {
name: "Laptop",
price: 3500,
desc: "Portable gaming laptop.",
type: "hardware"
}, {
name: "Gaming Mousepad",
price: 350,
desc: "Large mousepad.",
type: "accessory"
}, {
name: "Game Figure",
price: 900,
desc: "Collector's figure.",
type: "figure"
}, {
name: "Game Keychain",
price: 200,
desc: "Game-themed keychain.",
type: "accessory"
}, {
name: "Game T-shirt",
price: 250,
desc: "Game logo t-shirt.",
type: "clothing"
}, {
name: "Game Hoodie",
price: 600,
desc: "Warm hoodie.",
type: "clothing"
}, {
name: "Game Art",
price: 1500,
desc: "Artistic game painting.",
type: "poster"
}, {
name: "Mouse Wristband",
price: 150,
desc: "Comfortable wristband.",
type: "accessory"
}, {
name: "Sticker Pack",
price: 100,
desc: "Pack of 10 stickers.",
type: "accessory"
},
// --- 5 new products added ---
{
name: "RGB LED Strip",
price: 450,
desc: "Colorful LED strip for your game room.",
type: "accessory"
}, {
name: "Mouse Stand",
price: 300,
desc: "Stylish mouse stand.",
type: "accessory"
}, {
name: "Game Notebook",
price: 200,
desc: "Game-themed notebook for taking notes.",
type: "stationery"
}, {
name: "Game Pen Set",
price: 120,
desc: "Set of 5 game-themed pens.",
type: "stationery"
}, {
name: "Game Puzzle",
price: 600,
desc: "500-piece game-themed puzzle.",
type: "game"
}];
// --- Fan Store Menu UI ---
var fanStoreMenu = new Container();
fanStoreMenu.visible = false;
game.addChild(fanStoreMenu);
var fanStoreTitle = new Text2('Fan Store', {
size: 60,
fill: 0xFFFFFF
});
fanStoreTitle.anchor.set(0.5, 0.5);
fanStoreTitle.x = 1024;
fanStoreTitle.y = 200;
fanStoreMenu.addChild(fanStoreTitle);
var fanStoreBackBtn = new Button();
fanStoreBackBtn.setLabel('Back');
fanStoreBackBtn.x = 1024;
fanStoreBackBtn.y = 2400;
fanStoreBackBtn.onClick = function () {
fanStoreMenu.visible = false;
mainMenu.visible = true;
};
fanStoreMenu.addChild(fanStoreBackBtn);
// Helper for showing the fan menu
function showFanMenu() {
mainMenu.visible = false;
fanMenu.visible = true;
// Remove old product cards/buttons
for (var i = fanMenu.children.length - 1; i >= 0; i--) {
var child = fanMenu.children[i];
if (child !== fanTitle && child !== fanBackBtn) {
child.destroy();
}
}
// Show all products in a grid: 2 columns per row
var yStart = 500;
var xStart = 700;
var xSpacing = 600;
var ySpacing = 300;
var cols = 2;
for (var i = 0; i < fanProducts.length; i++) {
var prod = fanProducts[i];
var container = new Container();
var col = i % cols;
var row = Math.floor(i / cols);
container.x = xStart + col * xSpacing;
container.y = yStart + row * ySpacing;
// Card background
var bg = LK.getAsset('card', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.2,
scaleY: 0.7
});
container.addChild(bg);
// Product name
var nameText = new Text2(prod.name, {
size: 40,
fill: 0xFFFFFF
});
nameText.anchor.set(0.5, 0.5);
nameText.y = -60;
container.addChild(nameText);
// Description
var descText = new Text2(prod.desc, {
size: 28,
fill: 0xFFC107
});
descText.anchor.set(0.5, 0.5);
descText.y = 0;
container.addChild(descText);
// Price
var priceText = new Text2('Price: $' + prod.price, {
size: 30,
fill: 0x4CAF50
});
priceText.anchor.set(0.5, 0.5);
priceText.y = 50;
container.addChild(priceText);
// Buy button
var buyBtn = new Button();
buyBtn.setLabel('Buy (+ ' + prod.fans + ' fan)');
buyBtn.x = 0;
buyBtn.y = 120;
buyBtn.onClick = function (prod) {
return function () {
if (gameState.money >= prod.price) {
gameState.money -= prod.price;
if (!gameState.fans) gameState.fans = 0;
gameState.fans += prod.fans;
updateUI();
LK.getSound('success').play();
showFanMenu();
}
};
}(prod);
container.addChild(buyBtn);
fanMenu.addChild(container);
}
// Show current fan count at top
if (fanMenu.fanCountText) fanMenu.fanCountText.destroy();
var fanCountText = new Text2('Total Fans: ' + (gameState.fans || 0), {
size: 45,
fill: 0x2196F3
});
fanCountText.anchor.set(0.5, 0.5);
fanCountText.x = 1024;
fanCountText.y = 400;
fanMenu.addChild(fanCountText);
fanMenu.fanCountText = fanCountText;
}
// Helper for showing the fan store menu
function showFanStoreMenu() {
mainMenu.visible = false;
fanStoreMenu.visible = true;
// Remove old product cards/buttons
for (var i = fanStoreMenu.children.length - 1; i >= 0; i--) {
var child = fanStoreMenu.children[i];
if (child !== fanStoreTitle && child !== fanStoreBackBtn) {
child.destroy();
}
}
// Show all products in a grid: 5 columns per row, 4 rows (ekrana sığacak şekilde %20 büyütülmüş ve hizalanmış)
// 20 ürün için 5x4 grid
var yStart = 550;
var xStart = 180;
var xSpacing = 385; // %20 büyütülmüş kartlar için aralık artırıldı
var ySpacing = 310; // %20 büyütülmüş kartlar için aralık artırıldı
var cols = 5;
for (var i = 0; i < fanStoreProducts.length; i++) {
var prod = fanStoreProducts[i];
var container = new Container();
var col = i % cols;
var row = Math.floor(i / cols);
container.x = xStart + col * xSpacing;
container.y = yStart + row * ySpacing;
// Card background
var bg = LK.getAsset('card', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.84,
// 0.7 * 1.2 = 0.84, %20 büyütme
scaleY: 0.6 // 0.5 * 1.2 = 0.6, %20 büyütme
});
container.addChild(bg);
// Product name
var nameText = new Text2(prod.name, {
size: 34,
fill: 0xFFFFFF
});
nameText.anchor.set(0.5, 0.5);
nameText.y = -45;
container.addChild(nameText);
// Description
var descText = new Text2(prod.desc, {
size: 22,
fill: 0xFFC107
});
descText.anchor.set(0.5, 0.5);
descText.y = 0;
container.addChild(descText);
// Price (Satış fiyatı: alış fiyatı + %10 kâr)
var salePrice = Math.round(prod.price * 1.1);
var priceText = new Text2('Sale Price: $' + salePrice + ' (Cost: $' + prod.price + ')', {
size: 24,
fill: 0x4CAF50
});
priceText.anchor.set(0.5, 0.5);
priceText.y = 38;
container.addChild(priceText);
// Buy button for Fan Store products
var buyBtn = new Button();
buyBtn.setLabel('Buy (for Fans)');
// Scale down by 30%
buyBtn.scaleX = 0.7;
buyBtn.scaleY = 0.7;
// Move button lower to visually separate from price
buyBtn.x = 0;
buyBtn.y = 120;
buyBtn.onClick = function (prod) {
return function () {
// Only allow if player has enough money AND at least 50 fans
if (gameState.money >= prod.price && (gameState.fans || 0) >= 50) {
gameState.money -= prod.price;
// Track owned count for each product
if (!prod.owned) prod.owned = 0;
prod.owned += 1;
// Deduct 50 fans per purchase
gameState.fans -= 50;
updateUI();
LK.getSound('success').play();
showFanStoreMenu();
}
};
}(prod);
container.addChild(buyBtn);
// Show owned count if any
if (prod.owned && prod.owned > 0) {
var ownedText = new Text2('Owned: ' + prod.owned, {
size: 22,
fill: 0x2196F3
});
ownedText.anchor.set(0.5, 0.5);
ownedText.y = 65;
container.addChild(ownedText);
}
fanStoreMenu.addChild(container);
}
// Show current fan count at top
if (fanStoreMenu.fanCountText) fanStoreMenu.fanCountText.destroy();
var fanCountText = new Text2('Total Fans: ' + (gameState.fans || 0), {
size: 45,
fill: 0x2196F3
});
fanCountText.anchor.set(0.5, 0.5);
fanCountText.x = 1024;
fanCountText.y = 400;
fanStoreMenu.addChild(fanCountText);
fanStoreMenu.fanCountText = fanCountText;
// --- Ava: Weekly Sales, Weekly Revenue, Total Products Sold ---
// Find last week's sales log
var lastLog = null;
if (gameState.fanStoreAutoSaleLog && gameState.fanStoreAutoSaleLog.length > 0) {
lastLog = gameState.fanStoreAutoSaleLog[gameState.fanStoreAutoSaleLog.length - 1];
}
var weeklySalesCount = 0;
var weeklyRevenue = 0;
var weeklyProductCount = 0;
if (lastLog) {
for (var i = 0; i < lastLog.sales.length; i++) {
weeklySalesCount += lastLog.sales[i].qty;
weeklyProductCount += 1;
}
weeklyRevenue = lastLog.totalRevenue;
}
// Info text about profit margin
if (fanStoreMenu.profitInfoText) fanStoreMenu.profitInfoText.destroy();
var profitInfoText = new Text2("Fan products are sold at 10% above purchase price (e.g. $500 product is sold for $550).", {
size: 30,
fill: 0x4CAF50,
align: "center"
});
profitInfoText.anchor.set(0.5, 1);
profitInfoText.x = 1024;
// Move 2 lines higher (assume 2x line height, ~64px per line for size 30)
profitInfoText.y = fanStoreBackBtn.y - 120 - 64 * 2;
fanStoreMenu.addChild(profitInfoText);
fanStoreMenu.profitInfoText = profitInfoText;
// Ava: Each product purchase costs 50 Fans.
if (fanStoreMenu.fanCostInfoText) fanStoreMenu.fanCostInfoText.destroy();
var fanCostInfoText = new Text2("Each product purchase costs 50 Fans.", {
size: 28,
fill: 0x4CAF50,
align: "center"
});
fanCostInfoText.anchor.set(0.5, 1);
fanCostInfoText.x = 1024;
fanCostInfoText.y = profitInfoText.y + 40;
fanStoreMenu.addChild(fanCostInfoText);
fanStoreMenu.fanCostInfoText = fanCostInfoText;
// Ava: Each product sale costs 100 Fans.
if (fanStoreMenu.fanSaleCostInfoText) fanStoreMenu.fanSaleCostInfoText.destroy();
var fanSaleCostInfoText = new Text2("Each product sale costs 100 Fans.", {
size: 28,
fill: 0x4CAF50,
align: "center"
});
fanSaleCostInfoText.anchor.set(0.5, 1);
fanSaleCostInfoText.x = 1024;
fanSaleCostInfoText.y = fanCostInfoText.y + 40;
fanStoreMenu.addChild(fanSaleCostInfoText);
fanStoreMenu.fanSaleCostInfoText = fanSaleCostInfoText;
// Calculate total number of products sold since the beginning
var totalProductSold = 0;
if (gameState.fanStoreAutoSaleLog && gameState.fanStoreAutoSaleLog.length > 0) {
for (var i = 0; i < gameState.fanStoreAutoSaleLog.length; i++) {
var log = gameState.fanStoreAutoSaleLog[i];
if (log && log.sales && log.sales.length > 0) {
for (var j = 0; j < log.sales.length; j++) {
totalProductSold += log.sales[j].qty;
}
}
}
}
// Compose info text
var weeklyInfoText = "Weekly Sales: " + weeklySalesCount + "\nWeekly Revenue: $" + weeklyRevenue + "\nTotal Products Sold: " + totalProductSold;
if (fanStoreMenu.weeklyInfoText) fanStoreMenu.weeklyInfoText.destroy();
var infoText = new Text2(weeklyInfoText, {
size: 32,
fill: 0xFFC107,
align: "center"
});
infoText.anchor.set(0.5, 1);
infoText.x = 1024;
infoText.y = fanStoreBackBtn.y - 60;
fanStoreMenu.addChild(infoText);
fanStoreMenu.weeklyInfoText = infoText;
}
// --- Fan Store: Günlük orantılı satış sistemi ---
// Her gün başında, mevcut fan sayısına orantılı olarak sahip olunan Store ürünlerinden satış yapılır
if (typeof gameState.fanStoreAutoSaleLog === "undefined") {
gameState.fanStoreAutoSaleLog = [];
}
// Yardımcı: Rastgele tamsayı [min, max]
function getRandomIntFanStore(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}
// Günlük fan store satış fonksiyonu
function processFanStoreDailySale() {
var totalFans = gameState.fans || 0;
if (totalFans < 1) return; // En az 1 fan olmalı
// Satış yapılacak toplam ürün adedi: her 100 fan için 1 satış, ancak 100'den az fan varsa da 1 satış yapılır
var saleCount = Math.floor(totalFans / 100);
if (saleCount < 1 && totalFans > 0) saleCount = 1;
// Satış için yeterli fan yoksa, satış yapılmaz
if (gameState.fans < 100) return;
// Satılabilir ürünler: sadece owned > 0 olanlar
var ownedProducts = fanStoreProducts.filter(function (prod) {
return prod.owned && prod.owned > 0;
});
if (ownedProducts.length === 0) return; // Satılacak ürün yoksa çık
// Satışları orantılı dağıt: fan sayısına göre, sahip olunan ürünlerden rastgele seçerek
var sales = [];
var totalRevenue = 0;
var fansBefore = gameState.fans;
var fansToLose = 0;
// Her ürün için, sahip olunan adede ve toplam fan sayısına göre satış miktarı belirle
// Her ürün için: (ürün owned / toplam owned) * saleCount kadar satış
var totalOwned = 0;
for (var i = 0; i < ownedProducts.length; i++) {
totalOwned += ownedProducts[i].owned;
}
// Her ürün için satış miktarını hesapla
var remainingSaleCount = saleCount;
for (var i = 0; i < ownedProducts.length; i++) {
var prod = ownedProducts[i];
// Oranla dağıt, en az 1 satılabilir
var prodSale = Math.floor(prod.owned / totalOwned * saleCount);
if (prodSale < 1 && remainingSaleCount > 0) prodSale = 1;
if (prodSale > prod.owned) prodSale = prod.owned;
if (prodSale > remainingSaleCount) prodSale = remainingSaleCount;
if (prodSale > 0) {
sales.push({
name: prod.name,
price: prod.price,
qty: prodSale
});
// Owned azalt
prod.owned -= prodSale;
// Kâr ekle (Satış fiyatı: alış fiyatı + %10 kâr)
// Satış fiyatı = alış fiyatı * 1.1, kâr = alış fiyatı * 0.1
var salePrice = Math.round(prod.price * 1.1);
totalRevenue += salePrice * prodSale;
// Fan kaybı: her satışta 100 fan kaybı, ancak toplu olarak gün sonunda uygula
fansToLose += prodSale * 100; // Her ürün satışı 100 fan maliyetindedir
remainingSaleCount -= prodSale;
}
if (remainingSaleCount <= 0) break;
}
// Eğer yeterli fan yoksa, satış miktarını azalt
if (fansToLose > gameState.fans) {
// Kaç ürün satılabilir?
var maxSales = Math.floor(gameState.fans / 100);
// Satışları yeniden dağıt
var totalReduced = 0;
for (var i = 0; i < sales.length; i++) {
if (totalReduced + sales[i].qty > maxSales) {
sales[i].qty = Math.max(0, maxSales - totalReduced);
}
totalReduced += sales[i].qty;
}
// Owned'ları tekrar güncelle (fazla azaltılmışsa geri ekle)
for (var i = 0; i < ownedProducts.length; i++) {
var prod = ownedProducts[i];
var sale = sales.find(function (s) {
return s.name === prod.name;
});
if (sale) {
var sold = sale.qty;
var originallyReduced = prod.owned + sold;
prod.owned += originallyReduced - sold;
}
}
// fansToLose'u güncelle
fansToLose = maxSales * 100;
// totalRevenue'u güncelle
totalRevenue = 0;
for (var i = 0; i < sales.length; i++) {
var salePrice = Math.round(sales[i].price * 1.1);
totalRevenue += salePrice * sales[i].qty;
}
}
// Para ekle
gameState.money += totalRevenue;
// Fan sayısını azalt: toplamda 100 fan/ürün, ancak en fazla mevcut fan kadar
var fansAfter = gameState.fans;
if (fansToLose > 0) {
if (fansToLose > gameState.fans) fansToLose = gameState.fans;
gameState.fans -= fansToLose;
fansAfter = gameState.fans;
}
// Satış kaydını logla
var logEntry = {
day: gameState.currentDay,
sales: sales,
totalRevenue: totalRevenue,
fansBefore: fansBefore,
fansAfter: fansAfter
};
gameState.fanStoreAutoSaleLog.push(logEntry);
// Bildirim gösterme (popup kaldırıldı)
updateUI();
}
// --- Her gün başında fan store satışını tetikle ---
// Günlük ilerleme kodunda çağrılacak, game.update içinde dayTimer >= 180 kısmında
// --- Platform Menu UI ---
var platformMenu = new Container();
platformMenu.visible = false;
game.addChild(platformMenu);
var platformTitle = new Text2('Platforms', {
size: 60,
fill: 0xFFFFFF
});
platformTitle.anchor.set(0.5, 0.5);
platformTitle.x = 1024;
platformTitle.y = 200;
platformMenu.addChild(platformTitle);
var platformBackBtn = new Button();
platformBackBtn.setLabel('Back');
platformBackBtn.x = 1024;
platformBackBtn.y = 2400;
platformBackBtn.onClick = function () {
platformMenu.visible = false;
mainMenu.visible = true;
};
platformMenu.addChild(platformBackBtn);
// --- Drag-to-scroll for platformMenu ---
var platformMenuDrag = {
dragging: false,
lastY: 0,
startY: 0,
startMenuY: 0,
minY: 0,
maxY: 0
};
// Calculate scroll bounds after platforms are rendered
function updatePlatformMenuScrollBounds() {
// Find min/max y for scrolling (platformMenu children)
var minY = 0,
maxY = 0;
for (var i = 0; i < platformMenu.children.length; i++) {
var child = platformMenu.children[i];
if (child !== platformTitle && child !== platformBackBtn) {
if (minY === 0 || child.y < minY) minY = child.y;
if (child.y > maxY) maxY = child.y;
}
}
// Allow scrolling so that last row is visible, but not too far up
platformMenuDrag.minY = Math.min(0, 800 - maxY);
platformMenuDrag.maxY = 0;
}
platformMenu.interactive = true;
platformMenu.down = function (x, y, obj) {
platformMenuDrag.dragging = true;
platformMenuDrag.lastY = y;
platformMenuDrag.startY = y;
platformMenuDrag.startMenuY = platformMenu.y || 0;
updatePlatformMenuScrollBounds();
};
platformMenu.move = function (x, y, obj) {
if (!platformMenuDrag.dragging) return;
var dy = y - platformMenuDrag.lastY;
var newY = (platformMenu.y || 0) + dy;
// Clamp scroll
if (newY < platformMenuDrag.minY) newY = platformMenuDrag.minY;
if (newY > platformMenuDrag.maxY) newY = platformMenuDrag.maxY;
platformMenu.y = newY;
platformMenuDrag.lastY = y;
};
platformMenu.up = function (x, y, obj) {
platformMenuDrag.dragging = false;
};
// --- Platform data (moved up to fix ReferenceError) ---
// Each platform gets a salesBonus: 0.02 * (index+1) for 2% more per platform
var platforms = [{
name: "PC",
year: 1981,
researched: true,
owned: true,
researchCost: 0,
price: 0
}, {
name: "Commodore 64",
year: 1982,
researched: false,
owned: false,
researchCost: 4000,
price: 4000
}, {
name: "NES",
year: 1983,
researched: false,
owned: false,
researchCost: 4000,
price: 4000
}, {
name: "Sega Master System",
year: 1985,
researched: false,
owned: false,
researchCost: 4000,
price: 4000
}, {
name: "Game Boy",
year: 1989,
researched: false,
owned: false,
researchCost: 4000,
price: 4000
}, {
name: "Super Nintendo",
year: 1990,
researched: false,
owned: false,
researchCost: 4000,
price: 4000
}, {
name: "Sega Genesis",
year: 1990,
researched: false,
owned: false,
researchCost: 4000,
price: 4000
}, {
name: "PlayStation",
year: 1994,
researched: true,
owned: true,
researchCost: 0,
price: 0
}, {
name: "Sega Saturn",
year: 1994,
researched: false,
owned: false,
researchCost: 4000,
price: 4000
}, {
name: "Nintendo 64",
year: 1996,
researched: false,
owned: false,
researchCost: 4000,
price: 4000
}, {
name: "Dreamcast",
year: 1998,
researched: false,
owned: false,
researchCost: 4000,
price: 4000
}, {
name: "PlayStation 2",
year: 2000,
researched: false,
owned: false,
researchCost: 4000,
price: 8000
}, {
name: "GameCube",
year: 2001,
researched: false,
owned: false,
researchCost: 8000,
price: 8000
}, {
name: "Xbox",
year: 2001,
researched: false,
owned: false,
researchCost: 8000,
price: 8000
}, {
name: "Game Boy Advance",
year: 2001,
researched: false,
owned: false,
researchCost: 8000,
price: 8000
}, {
name: "PlayStation Portable",
year: 2004,
researched: false,
owned: false,
researchCost: 8000,
price: 8000
}, {
name: "Nintendo DS",
year: 2004,
researched: false,
owned: false,
researchCost: 8000,
price: 8000
}, {
name: "Xbox 360",
year: 2005,
researched: false,
owned: false,
researchCost: 8000,
price: 8000
}, {
name: "Wii",
year: 2006,
researched: false,
owned: false,
researchCost: 8000,
price: 8000
}, {
name: "PlayStation 3",
year: 2006,
researched: false,
owned: false,
researchCost: 8000,
price: 8000
}, {
name: "PlayStation Vita",
year: 2011,
researched: false,
owned: false,
researchCost: 12000,
price: 12000
}, {
name: "Nintendo 3DS",
year: 2011,
researched: false,
owned: false,
researchCost: 12000,
price: 12000
}, {
name: "Wii U",
year: 2012,
researched: false,
owned: false,
researchCost: 12000,
price: 12000
}, {
name: "PlayStation 4",
year: 2013,
researched: false,
owned: false,
researchCost: 12000,
price: 12000
}, {
name: "Xbox One",
year: 2013,
researched: false,
owned: false,
researchCost: 12000,
price: 12000
}, {
name: "Nintendo Switch",
year: 2017,
researched: false,
owned: false,
researchCost: 16000,
price: 16000
}, {
name: "PlayStation 5",
year: 2020,
researched: false,
owned: false,
researchCost: 16000,
price: 16000
}, {
name: "Xbox Series X",
year: 2020,
researched: false,
owned: false,
researchCost: 16000,
price: 16000
}, {
name: "Steam Deck",
year: 2022,
researched: false,
owned: false,
researchCost: 16000,
price: 16000
}, {
name: "Mobile",
year: 2007,
researched: false,
owned: false,
researchCost: 8000,
price: 8000
}, {
name: "Ouya",
year: 2013,
researched: false,
owned: false,
researchCost: 4000,
price: 4000
}];
// Add salesBonus to each platform (2% per platform, starting from 2%)
for (var i = 0; i < platforms.length; i++) {
platforms[i].salesBonus = 0.02 * (i + 1);
}
// Sort platforms by year ascending
platforms.sort(function (a, b) {
return a.year - b.year;
});
// Helper for showing the platform menu
function showPlatformMenu() {
mainMenu.visible = false;
platformMenu.visible = true;
platformMenu.y = 0; // Reset scroll position on open
// Remove old platform cards/buttons
for (var i = platformMenu.children.length - 1; i >= 0; i--) {
var child = platformMenu.children[i];
if (child !== platformTitle && child !== platformBackBtn) {
child.destroy();
}
}
// Platform data
// Use the global, sorted platforms array
// Store platform state in gameState if not already
if (!gameState.platforms) {
gameState.platforms = {};
for (var i = 0; i < platforms.length; i++) {
var plat = platforms[i];
gameState.platforms[plat.name] = {
researched: plat.researched,
owned: plat.owned
};
}
gameState.selectedPlatform = "PC";
}
// Defensive: ensure all platforms in the list have an entry in gameState.platforms
for (var i = 0; i < platforms.length; i++) {
var plat = platforms[i];
if (!gameState.platforms[plat.name]) {
gameState.platforms[plat.name] = {
researched: plat.researched,
owned: plat.owned
};
}
}
// Show all platforms in a grid: 4 columns per row, 7 rows (ekrana sığacak şekilde 28 platform için)
var yStart = 500;
var xStart = 220; // leftmost card center (for 4 columns, more margin for 7 rows)
var xSpacing = 420; // horizontal distance between columns (wider for 4 columns)
var ySpacing = 220; // vertical spacing (keep as is)
var cols = 4;
for (var i = 0; i < platforms.length; i++) {
var plat = platforms[i];
var container = new Container();
var col = i % cols;
var row = Math.floor(i / cols);
container.x = xStart + col * xSpacing;
container.y = yStart + row * ySpacing;
// Card background
var bg = LK.getAsset('card', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.0,
scaleY: 0.35
});
container.addChild(bg);
// Platform name
var nameText = new Text2(plat.name, {
size: 35,
fill: 0xFFFFFF
});
nameText.anchor.set(0.5, 0.5);
nameText.y = -30;
container.addChild(nameText);
// Year
var yearText = new Text2('Year: ' + plat.year, {
size: 28,
fill: 0x4CAF50
});
yearText.anchor.set(0.5, 0.5);
yearText.y = 10;
container.addChild(yearText);
// Sales bonus
var bonusText = new Text2('Sales Bonus: +' + Math.round(plat.salesBonus * 100) + '%', {
size: 24,
fill: 0x2196F3
});
bonusText.anchor.set(0.5, 0.5);
bonusText.y = 40;
container.addChild(bonusText);
// Research or Buy button
var platState;
if (gameState.platforms && _typeof2(gameState.platforms) === "object") {
if (!gameState.platforms[plat.name]) {
gameState.platforms[plat.name] = {
researched: plat.researched,
owned: plat.owned
};
}
platState = gameState.platforms[plat.name];
} else {
platState = {
researched: plat.researched,
owned: plat.owned
};
}
if (!platState.owned) {
var buyBtn = new Button();
buyBtn.setLabel('Buy ($' + plat.price + ')');
buyBtn.x = 0;
buyBtn.y = 100;
buyBtn.onClick = function (plat, platState) {
return function () {
if (gameState.money >= plat.price) {
gameState.money -= plat.price;
// Find the correct platState again (by name) to avoid closure bug
if (gameState.platforms && gameState.platforms[plat.name]) {
gameState.platforms[plat.name].owned = true;
gameState.platforms[plat.name].researched = true; // Mark as researched on purchase
}
updateUI();
LK.getSound('success').play();
showPlatformMenu();
}
};
}(plat, platState);
container.addChild(buyBtn);
} else {
var ownedText = new Text2('Available', {
size: 28,
fill: 0xFFC107
});
ownedText.anchor.set(0.5, 0.5);
ownedText.y = 100;
container.addChild(ownedText);
// No select button for owned platforms
}
platformMenu.addChild(container);
}
// Update scroll bounds after all cards are added
updatePlatformMenuScrollBounds && updatePlatformMenuScrollBounds();
// Add info text at the bottom of the platformMenu
if (platformMenu.platformInfoText) {
platformMenu.platformInfoText.destroy();
}
var platformInfoText = new Text2('To use a platform, purchase it from the platform page in the main menu.', {
size: 32,
fill: 0xFFC107
});
platformInfoText.anchor.set(0.5, 0.5);
platformInfoText.x = 1024;
platformInfoText.y = 2500;
platformMenu.addChild(platformInfoText);
platformMenu.platformInfoText = platformInfoText;
}
// (Game Engine menu and related UI removed)
// --- Upgrade Button and Menu ---
var upgradeBtn = new Button();
upgradeBtn.setLabel('Yükselt');
upgradeBtn.x = 1024;
upgradeBtn.y = 1350;
upgradeBtn.onClick = showUpgradeMenu;
mainMenu.addChild(upgradeBtn);
var upgradeMenu = new Container();
upgradeMenu.visible = false;
game.addChild(upgradeMenu);
var upgradeTitle = new Text2('Studio Upgrades', {
size: 60,
fill: 0xFFFFFF
});
upgradeTitle.anchor.set(0.5, 0.5);
upgradeTitle.x = 1024;
upgradeTitle.y = 200;
upgradeMenu.addChild(upgradeTitle);
var studioLevelText = new Text2('', {
size: 40,
fill: 0xFFC107
});
studioLevelText.anchor.set(0.5, 0.5);
studioLevelText.x = 1024;
studioLevelText.y = 350;
upgradeMenu.addChild(studioLevelText);
var studioUpgradeCostText = new Text2('', {
size: 35,
fill: 0x4CAF50
});
studioUpgradeCostText.anchor.set(0.5, 0.5);
studioUpgradeCostText.x = 1024;
studioUpgradeCostText.y = 420;
upgradeMenu.addChild(studioUpgradeCostText);
var studioUpgradeBtn = new Button();
studioUpgradeBtn.setLabel('Stüdyo Seviyesini Yükselt');
studioUpgradeBtn.x = 1024;
studioUpgradeBtn.y = 500;
studioUpgradeBtn.onClick = function () {
if (gameState.money >= gameState.studioUpgradeCost) {
gameState.money -= gameState.studioUpgradeCost;
gameState.studioLevel += 1;
gameState.maxHireableDevelopers += 1;
gameState.studioUpgradeCost = Math.floor(gameState.studioUpgradeCost * 1.7);
updateUI();
showUpgradeMenu();
LK.getSound('success').play();
}
};
upgradeMenu.addChild(studioUpgradeBtn);
// --- Main Character Section ---
var mainCharTitle = new Text2('Main Character', {
size: 40,
fill: 0xFFFFFF
});
mainCharTitle.anchor.set(0.5, 0.5);
mainCharTitle.x = 1024;
mainCharTitle.y = 700;
upgradeMenu.addChild(mainCharTitle);
var mainCharLevelText = new Text2('', {
size: 35,
fill: 0xFFC107
});
mainCharLevelText.anchor.set(0.5, 0.5);
mainCharLevelText.x = 1024;
mainCharLevelText.y = 770;
upgradeMenu.addChild(mainCharLevelText);
var mainCharSkillText = new Text2('', {
size: 30,
fill: 0x2196F3
});
mainCharSkillText.anchor.set(0.5, 0.5);
mainCharSkillText.x = 1024;
mainCharSkillText.y = 820;
upgradeMenu.addChild(mainCharSkillText);
var mainCharUpgradeCostText = new Text2('', {
size: 30,
fill: 0x4CAF50
});
mainCharUpgradeCostText.anchor.set(0.5, 0.5);
mainCharUpgradeCostText.x = 1024;
mainCharUpgradeCostText.y = 870;
upgradeMenu.addChild(mainCharUpgradeCostText);
var mainCharUpgradeBtn = new Button();
mainCharUpgradeBtn.setLabel('Upgrade Main Character');
mainCharUpgradeBtn.x = 1024;
mainCharUpgradeBtn.y = 950;
mainCharUpgradeBtn.onClick = function () {
if (gameState.money >= gameState.mainCharacter.upgradeCost) {
gameState.money -= gameState.mainCharacter.upgradeCost;
gameState.mainCharacter.level += 1;
gameState.mainCharacter.skill += 1;
// Each level, increase all feature points by 1
gameState.mainCharacter.featurePoints.Graphics += 1;
gameState.mainCharacter.featurePoints.Sound += 1;
gameState.mainCharacter.featurePoints.Gameplay += 1;
gameState.mainCharacter.upgradeCost = Math.floor(gameState.mainCharacter.upgradeCost * 1.8);
updateUI();
showUpgradeMenu();
LK.getSound('success').play();
}
};
upgradeMenu.addChild(mainCharUpgradeBtn);
var backFromUpgradeBtn = new Button();
backFromUpgradeBtn.setLabel('Back');
backFromUpgradeBtn.x = 1024;
backFromUpgradeBtn.y = 2400;
backFromUpgradeBtn.onClick = function () {
upgradeMenu.visible = false;
mainMenu.visible = true;
};
upgradeMenu.addChild(backFromUpgradeBtn);
function showUpgradeMenu() {
mainMenu.visible = false;
upgradeMenu.visible = true;
studioLevelText.setText('Studio Level: ' + gameState.studioLevel);
studioUpgradeCostText.setText('Upgrade Cost: $' + gameState.studioUpgradeCost);
mainCharLevelText.setText('Main Character Level: ' + gameState.mainCharacter.level);
mainCharSkillText.setText('Each Feature Point: ' + 'Graphics: ' + gameState.mainCharacter.featurePoints.Graphics + ', Sound: ' + gameState.mainCharacter.featurePoints.Sound + ', Gameplay: ' + gameState.mainCharacter.featurePoints.Gameplay);
mainCharUpgradeCostText.setText('Upgrade Cost: $' + gameState.mainCharacter.upgradeCost);
}
// Research menu container
var researchMenu = new Container();
researchMenu.visible = false;
game.addChild(researchMenu);
var researchTitle = new Text2('Research Lab', {
size: 60,
fill: 0xFFFFFF
});
researchTitle.anchor.set(0.5, 0.5);
researchTitle.x = 1024;
researchTitle.y = 200;
researchMenu.addChild(researchTitle);
var researchBackBtn = new Button();
researchBackBtn.setLabel('Back');
researchBackBtn.x = 1024;
researchBackBtn.y = 2400;
researchBackBtn.onClick = function () {
researchMenu.visible = false;
mainMenu.visible = true;
};
researchMenu.addChild(researchBackBtn);
// Research category menu
var researchCategoryMenu = new Container();
researchCategoryMenu.visible = false;
game.addChild(researchCategoryMenu);
var categoryTitle = new Text2('', {
size: 60,
fill: 0xFFFFFF
});
categoryTitle.anchor.set(0.5, 0.5);
categoryTitle.x = 1024;
categoryTitle.y = 200;
researchCategoryMenu.addChild(categoryTitle);
var categoryBackBtn = new Button();
categoryBackBtn.setLabel('Back');
categoryBackBtn.x = 1024;
categoryBackBtn.y = 2400;
categoryBackBtn.onClick = function () {
researchCategoryMenu.visible = false;
researchMenu.visible = true;
};
researchCategoryMenu.addChild(categoryBackBtn);
// Name game menu container
var nameGameMenu = new Container();
nameGameMenu.visible = false;
game.addChild(nameGameMenu);
var nameGameTitle = new Text2('Name Your Game', {
size: 60,
fill: 0xFFFFFF
});
nameGameTitle.anchor.set(0.5, 0.5);
nameGameTitle.x = 1024;
nameGameTitle.y = 200;
nameGameMenu.addChild(nameGameTitle);
// --- Ava: Add a text input area for entering a custom game name ---
var gameNameInput = new Text2('', {
size: 50,
fill: 0x4CAF50
});
gameNameInput.anchor.set(0.5, 0.5);
gameNameInput.x = 1024;
gameNameInput.y = 400;
nameGameMenu.addChild(gameNameInput);
// Add a background for the input area
var inputBg = LK.getAsset('button', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2.2,
scaleY: 1.1
});
inputBg.x = 1024;
inputBg.y = 400;
inputBg.alpha = 0.25;
nameGameMenu.addChildAt(inputBg, nameGameMenu.children.indexOf(gameNameInput));
// --- Ava: Add a blinking cursor to indicate input ---
var cursor = new Text2('|', {
size: 50,
fill: 0x4CAF50
});
cursor.anchor.set(0, 0.5);
cursor.x = 0;
cursor.y = 0;
cursor.visible = false;
nameGameMenu.addChild(cursor);
// --- Ava: Show prompt below input area ---
var inputPrompt = new Text2('Tap the input area to enter a game name', {
size: 30,
fill: 0xFFFFFF
});
inputPrompt.anchor.set(0.5, 0.5);
inputPrompt.x = 1024;
inputPrompt.y = 500;
nameGameMenu.addChild(inputPrompt);
// --- Ava: Simple tap-to-edit for mobile/desktop ---
// Track input state
var isEditingGameName = false;
var inputBlinkTimer = 0;
// Helper to update the cursor position
function updateGameNameCursor() {
if (!isEditingGameName) {
cursor.visible = false;
return;
}
// Place cursor at end of text
var textWidth = gameNameInput.width || 0;
cursor.x = gameNameInput.x + textWidth / 2 + 8;
cursor.y = gameNameInput.y;
cursor.visible = true;
}
// Helper to start editing
function startEditingGameName() {
isEditingGameName = true;
inputPrompt.setText('Type your game name (max 24 chars)');
updateGameNameCursor();
cursor.visible = true;
inputBlinkTimer = 0;
}
// Helper to stop editing
function stopEditingGameName() {
isEditingGameName = false;
inputPrompt.setText('Tap the input area to enter a game name');
cursor.visible = false;
}
// --- Ava: Input area tap handler ---
inputBg.interactive = true;
inputBg.down = function () {
startEditingGameName();
LK.getSound('select').play();
};
// --- Ava: Simulate text input for mobile/desktop ---
// Listen for text input events using LK's input event system (cross-platform, sandbox-safe)
if (!game._avaGameNameInputListener) {
game._avaGameNameInputListener = function (e) {
if (!isEditingGameName) return;
var key = e && (e.key || e.data || '');
if (key === 'Enter' || key === 'Done') {
stopEditingGameName();
return;
}
if (key === 'Backspace') {
if (currentGameName.length > 0) {
currentGameName = currentGameName.slice(0, -1);
gameNameInput.setText(currentGameName);
updateGameNameCursor();
}
return;
}
// Only allow visible ASCII, max 24 chars
if (typeof key === 'string' && key.length === 1 && currentGameName.length < 24 && /^[\w\s\-!?.']$/.test(key)) {
currentGameName += key;
gameNameInput.setText(currentGameName);
updateGameNameCursor();
}
};
// Use LK's event system for input (works for both desktop and mobile)
LK.on('input', game._avaGameNameInputListener);
LK.on('keydown', game._avaGameNameInputListener);
}
// --- Ava: Blinking cursor animation in game.update ---
var _oldGameUpdateForInput = game.update;
game.update = function () {
if (_oldGameUpdateForInput) _oldGameUpdateForInput();
if (isEditingGameName) {
inputBlinkTimer++;
if (inputBlinkTimer % 60 < 30) {
cursor.visible = true;
} else {
cursor.visible = false;
}
updateGameNameCursor();
} else {
cursor.visible = false;
}
};
var randomNameBtn = new Button();
randomNameBtn.setLabel('Random Name');
randomNameBtn.x = 1024;
randomNameBtn.y = 700;
randomNameBtn.onClick = generateRandomName;
nameGameMenu.addChild(randomNameBtn);
var confirmNameBtn = new Button();
confirmNameBtn.setLabel('Confirm Name');
confirmNameBtn.x = 1024;
confirmNameBtn.y = 850;
confirmNameBtn.onClick = confirmGameName;
nameGameMenu.addChild(confirmNameBtn);
var backFromNameBtn = new Button();
backFromNameBtn.setLabel('Back');
backFromNameBtn.x = 1024;
backFromNameBtn.y = 1000;
backFromNameBtn.onClick = function () {
nameGameMenu.visible = false;
mainMenu.visible = true;
gameNameInput.setText('');
currentGameName = '';
};
nameGameMenu.addChild(backFromNameBtn);
// Simple tap-to-edit name input
var nameInputBg = LK.getAsset('button', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2,
scaleY: 1
});
nameInputBg.x = 1024;
nameInputBg.y = 400;
nameInputBg.alpha = 0.3;
nameGameMenu.addChild(nameInputBg);
nameInputBg.interactive = true;
nameInputBg.down = function () {
// Simulate simple text input with preset options
var names = ['Game Studio Pro', 'Developer Tycoon', 'Code Master', 'Pixel Dreams', 'Game Maker Plus'];
var randomIndex = Math.floor(Math.random() * names.length);
currentGameName = names[randomIndex];
gameNameInput.setText(currentGameName);
LK.getSound('select').play();
};
// Move gameNameInput to be on top
nameGameMenu.removeChild(gameNameInput);
nameGameMenu.addChild(gameNameInput);
// All games menu container
var allGamesMenu = new Container();
allGamesMenu.visible = false;
game.addChild(allGamesMenu);
var allGamesTitle = new Text2('All Released Games', {
size: 60,
fill: 0xFFFFFF
});
allGamesTitle.anchor.set(0.5, 0.5);
allGamesTitle.x = 1024;
allGamesTitle.y = 200;
allGamesMenu.addChild(allGamesTitle);
var noGamesText = new Text2('No games released yet', {
size: 40,
fill: 0xFFFFFF
});
noGamesText.anchor.set(0.5, 0.5);
noGamesText.x = 1024;
noGamesText.y = 600;
noGamesText.visible = false;
allGamesMenu.addChild(noGamesText);
var backFromAllGamesBtn = new Button();
backFromAllGamesBtn.setLabel('Back');
backFromAllGamesBtn.x = 1024;
backFromAllGamesBtn.y = 2400;
backFromAllGamesBtn.onClick = function () {
allGamesMenu.visible = false;
mainMenu.visible = true;
};
allGamesMenu.addChild(backFromAllGamesBtn);
// Game detail view container
var gameDetailView = new Container();
gameDetailView.visible = false;
game.addChild(gameDetailView);
var detailBackBtn = new Button();
detailBackBtn.setLabel('Back to Games List');
detailBackBtn.x = 1024;
detailBackBtn.y = 2400;
detailBackBtn.onClick = function () {
gameDetailView.visible = false;
allGamesMenu.visible = true;
};
gameDetailView.addChild(detailBackBtn);
// Hire menu container
var hireMenu = new Container();
hireMenu.visible = false;
game.addChild(hireMenu);
var hireTitle = new Text2('Hire Developer', {
size: 60,
fill: 0xFFFFFF
});
hireTitle.anchor.set(0.5, 0.5);
hireTitle.x = 1024;
hireTitle.y = 200;
hireMenu.addChild(hireTitle);
var backFromHireBtn = new Button();
backFromHireBtn.setLabel('Back');
backFromHireBtn.x = 1024;
backFromHireBtn.y = 2400;
backFromHireBtn.onClick = function () {
hireMenu.visible = false;
mainMenu.visible = true;
};
hireMenu.addChild(backFromHireBtn);
// Project menu container
var projectMenu = new Container();
projectMenu.visible = false;
game.addChild(projectMenu);
var projectTitle = new Text2('New Project', {
size: 60,
fill: 0xFFFFFF
});
projectTitle.anchor.set(0.5, 0.5);
projectTitle.x = 1024;
projectTitle.y = 200;
projectMenu.addChild(projectTitle);
var selectFeaturesText = new Text2('Özellikleri Seç:', {
size: 40,
fill: 0xFFFFFF
});
selectFeaturesText.anchor.set(0.5, 0.5);
selectFeaturesText.x = 1024;
selectFeaturesText.y = 300;
projectMenu.addChild(selectFeaturesText);
var startDevelopmentBtn = new Button();
startDevelopmentBtn.setLabel('Start Development');
startDevelopmentBtn.x = 1024;
startDevelopmentBtn.y = 2200;
startDevelopmentBtn.onClick = startDevelopment;
projectMenu.addChild(startDevelopmentBtn);
// Add Back button to New Project page
var backFromProjectBtn = new Button();
backFromProjectBtn.setLabel('Back');
backFromProjectBtn.x = 1024;
backFromProjectBtn.y = 2350;
backFromProjectBtn.onClick = function () {
projectMenu.visible = false;
mainMenu.visible = true;
selectedFeatures = [];
featureCards.forEach(function (card) {
card.setSelected(false);
});
selectedFeatureByCategory.Graphics = null;
selectedFeatureByCategory.Sound = null;
selectedFeatureByCategory.Gameplay = null;
projectMenu.selectedGenre = null;
// Restore persistent buttons if missing (for next open)
if (projectMenu.priceBtn && projectMenu.children.indexOf(projectMenu.priceBtn) === -1) {
projectMenu.addChild(projectMenu.priceBtn);
}
if (projectMenu.platformBtn && projectMenu.children.indexOf(projectMenu.platformBtn) === -1) {
projectMenu.addChild(projectMenu.platformBtn);
}
if (projectMenu.gameGenresResearchBtn && projectMenu.children.indexOf(projectMenu.gameGenresResearchBtn) === -1) {
projectMenu.addChild(projectMenu.gameGenresResearchBtn);
}
};
projectMenu.addChild(backFromProjectBtn);
// Feature category menu
var featureCategoryMenu = new Container();
featureCategoryMenu.visible = false;
game.addChild(featureCategoryMenu);
var categoryMenuTitle = new Text2('', {
size: 60,
fill: 0xFFFFFF
});
categoryMenuTitle.anchor.set(0.5, 0.5);
categoryMenuTitle.x = 1024;
categoryMenuTitle.y = 200;
featureCategoryMenu.addChild(categoryMenuTitle);
var selectedFeaturesText = new Text2('Selected: 0/5', {
size: 40,
fill: 0xFFFFFF
});
selectedFeaturesText.anchor.set(0.5, 0.5);
selectedFeaturesText.x = 1024;
selectedFeaturesText.y = 300;
featureCategoryMenu.addChild(selectedFeaturesText);
var categoryBackBtn = new Button();
categoryBackBtn.setLabel('Back to Categories');
categoryBackBtn.x = 1024;
categoryBackBtn.y = 2350;
categoryBackBtn.onClick = function () {
featureCategoryMenu.visible = false;
projectMenu.visible = true;
// Restore persistent buttons if missing
if (projectMenu.priceBtn && projectMenu.children.indexOf(projectMenu.priceBtn) === -1) {
projectMenu.addChild(projectMenu.priceBtn);
}
if (projectMenu.platformBtn && projectMenu.children.indexOf(projectMenu.platformBtn) === -1) {
projectMenu.addChild(projectMenu.platformBtn);
}
if (projectMenu.gameGenresResearchBtn && projectMenu.children.indexOf(projectMenu.gameGenresResearchBtn) === -1) {
projectMenu.addChild(projectMenu.gameGenresResearchBtn);
}
// Update total cost in project menu
var totalCost = 0;
selectedFeatures.forEach(function (f) {
totalCost += f.cost;
});
if (projectMenu.totalCostText) {
projectMenu.totalCostText.setText('Total Cost: $' + totalCost);
}
// Update selectedFeatureByCategory to first selected per category, but do not remove extra selections
['Graphics', 'Sound', 'Gameplay'].forEach(function (cat) {
var found = false;
for (var i = 0; i < selectedFeatures.length; i++) {
if (selectedFeatures[i].type === cat) {
if (!found) {
selectedFeatureByCategory[cat] = selectedFeatures[i];
found = true;
}
}
}
if (!found) selectedFeatureByCategory[cat] = null;
});
};
featureCategoryMenu.addChild(categoryBackBtn);
// --- Game Genres Research menu for projectMenu ---
var projectGenresResearchMenu = new Container();
projectGenresResearchMenu.visible = false;
game.addChild(projectGenresResearchMenu);
var projectGenresResearchTitle = new Text2('Game Genres Research', {
size: 60,
fill: 0xFFFFFF
});
projectGenresResearchTitle.anchor.set(0.5, 0.5);
projectGenresResearchTitle.x = 1024;
projectGenresResearchTitle.y = 200;
projectGenresResearchMenu.addChild(projectGenresResearchTitle);
var projectGenresResearchBackBtn = new Button();
projectGenresResearchBackBtn.setLabel('Back');
projectGenresResearchBackBtn.x = 1024;
projectGenresResearchBackBtn.y = 2400;
projectGenresResearchBackBtn.onClick = function () {
projectGenresResearchMenu.visible = false;
projectMenu.visible = true;
// Restore persistent buttons if missing
if (projectMenu.priceBtn && projectMenu.children.indexOf(projectMenu.priceBtn) === -1) {
projectMenu.addChild(projectMenu.priceBtn);
}
if (projectMenu.platformBtn && projectMenu.children.indexOf(projectMenu.platformBtn) === -1) {
projectMenu.addChild(projectMenu.platformBtn);
}
if (projectMenu.gameGenresResearchBtn && projectMenu.children.indexOf(projectMenu.gameGenresResearchBtn) === -1) {
projectMenu.addChild(projectMenu.gameGenresResearchBtn);
}
};
projectGenresResearchMenu.addChild(projectGenresResearchBackBtn);
function showProjectGenresResearchMenu() {
projectMenu.visible = false;
projectGenresResearchMenu.visible = true;
// Remove old genre buttons
for (var i = projectGenresResearchMenu.children.length - 1; i >= 0; i--) {
var child = projectGenresResearchMenu.children[i];
if (child !== projectGenresResearchTitle && child !== projectGenresResearchBackBtn) {
child.destroy();
}
}
// Show researched genres as selectable, and unresearched as buttons
var yStart = 400;
var researched = gameState.researchedFeatures.GameGenres;
gameGenres.forEach(function (genre, idx) {
if (!genre.requiresResearch || researched.indexOf(genre.name) !== -1) {
// Make researched genres selectable (only one can be selected)
var isSelected = projectMenu.selectedGenre && projectMenu.selectedGenre.name === genre.name;
var genreBtn = new Button();
genreBtn.setLabel(genre.name + (isSelected ? ' (Selected)' : ' (Researched)'));
genreBtn.x = 1024;
genreBtn.y = yStart + idx * 120;
if (isSelected) {
// Highlight selected genre
genreBtn.children[0].tint = 0xe94560;
}
genreBtn.onClick = function (g) {
return function () {
projectMenu.selectedGenre = g;
// Sync selected genre to gameState for persistence
gameState.selectedGenre = g;
LK.getSound('select').play();
if (projectMenu.genreText) {
projectMenu.genreText.setText('Selected Genre: ' + (projectMenu.selectedGenre ? projectMenu.selectedGenre.name : 'None'));
}
showProjectGenresResearchMenu();
};
}(genre);
projectGenresResearchMenu.addChild(genreBtn);
} else {
var btn = new Button();
btn.setLabel(genre.name + ' ($' + genre.researchCost + ')');
btn.x = 1024;
btn.y = yStart + idx * 120;
btn.onClick = function (g) {
return function () {
if (gameState.money >= g.researchCost && !gameState.currentResearch) {
gameState.money -= g.researchCost;
gameState.currentResearch = {
name: g.name,
category: 'GameGenres',
timeRemaining: 180
};
updateUI();
LK.getSound('select').play();
showProjectGenresResearchMenu();
}
};
}(genre);
projectGenresResearchMenu.addChild(btn);
}
});
}
// Development screen
var developmentScreen = new Container();
developmentScreen.visible = false;
game.addChild(developmentScreen);
var devTitle = new Text2('Developing Game', {
size: 60,
fill: 0xFFFFFF
});
devTitle.anchor.set(0.5, 0.5);
devTitle.x = 1024;
devTitle.y = 200;
developmentScreen.addChild(devTitle);
var targetScoreText = new Text2('Target Score: 100', {
size: 40,
fill: 0xFFFFFF
});
targetScoreText.anchor.set(0.5, 0.5);
targetScoreText.x = 1024;
targetScoreText.y = 400;
developmentScreen.addChild(targetScoreText);
var currentScoreText = new Text2('Current Score: 0', {
size: 40,
fill: 0x4CAF50
});
currentScoreText.anchor.set(0.5, 0.5);
currentScoreText.x = 1024;
currentScoreText.y = 500;
developmentScreen.addChild(currentScoreText);
var progressBarBg = LK.getAsset('progressBar', {
anchorX: 0.5,
anchorY: 0.5
});
progressBarBg.x = 1024;
progressBarBg.y = 700;
developmentScreen.addChild(progressBarBg);
var progressBarFill = LK.getAsset('progressFill', {
anchorX: 0,
anchorY: 0.5
});
progressBarFill.x = 624;
progressBarFill.y = 700;
progressBarFill.scaleX = 0;
developmentScreen.addChild(progressBarFill);
var releaseBtn = new Button();
releaseBtn.setLabel('Release Game!');
releaseBtn.x = 1024;
releaseBtn.y = 900;
releaseBtn.visible = false;
releaseBtn.onClick = releaseGame;
developmentScreen.addChild(releaseBtn);
// Market trends display
var trendsContainer = new Container();
trendsContainer.x = 1024;
trendsContainer.y = 1200;
developmentScreen.addChild(trendsContainer);
var trendsTitle = new Text2('Market Trends:', {
size: 35,
fill: 0xFF5722
});
trendsTitle.anchor.set(0.5, 0.5);
trendsContainer.addChild(trendsTitle);
// Arrays for UI elements
var developerCards = [];
var featureCards = [];
var selectedFeatures = [];
// Track selected feature per category for new project
var selectedFeatureByCategory = {
Graphics: null,
Sound: null,
Gameplay: null
};
// Functions
function updateUI() {
moneyText.setText('Money: $' + gameState.money);
developersText.setText('Developers: ' + gameState.developers.length);
gamesText.setText('Games Released: ' + gameState.completedGames);
// Sync gameState.currentDay with the dayText UI (top right Day ilerlemesi)
var dayFromUI = 1;
if (typeof dayText.text === "string") {
var match = dayText.text.match(/Day:\s*(\d+)/);
if (match && match[1]) {
dayFromUI = parseInt(match[1], 10);
if (!isNaN(dayFromUI)) {
gameState.currentDay = dayFromUI;
}
}
}
dayText.setText('Day: ' + gameState.currentDay);
// Fan UI
fanText.setText('Fan: ' + (gameState.fans || 0));
// Calculate fan bonus: 100000 fans = %100 bonus, scale linearly up to that point, max 100%
// Platform-specific: always use the selected platform's salesBonus
var fanBonus = 0;
var selectedPlatformObj = null;
if (gameState.selectedPlatform) {
for (var pi = 0; pi < platforms.length; pi++) {
if (platforms[pi].name === gameState.selectedPlatform) {
selectedPlatformObj = platforms[pi];
break;
}
}
}
if (gameState.fans && gameState.fans > 0) {
fanBonus = gameState.fans / 100000 * 100; // 100000 fan = %100 bonus
if (fanBonus > 100) fanBonus = 100;
}
var displayFanBonus = 0;
if (selectedPlatformObj && typeof selectedPlatformObj.salesBonus === "number") {
displayFanBonus = Math.round(fanBonus * selectedPlatformObj.salesBonus); // platforma göre çarp
} else {
displayFanBonus = Math.round(fanBonus);
}
fanBonusText.setText('Satış Bonusu: %' + displayFanBonus);
}
function showResearchMenu() {
mainMenu.visible = false;
researchMenu.visible = true;
// Clear existing buttons
for (var i = researchMenu.children.length - 1; i >= 0; i--) {
if (researchMenu.children[i] instanceof Button && researchMenu.children[i] !== researchBackBtn) {
researchMenu.children[i].destroy();
}
}
// Create category buttons
var categories = ['Graphics', 'Sound', 'Gameplay', 'GameGenres'];
categories.forEach(function (category, index) {
var btn = new Button();
var displayName = category === 'GameGenres' ? 'Game Genres' : category;
btn.setLabel(displayName + ' Research');
btn.x = 1024;
btn.y = 400 + index * 150;
btn.onClick = function () {
showResearchCategory(category);
};
researchMenu.addChild(btn);
});
}
function showResearchCategory(category) {
researchMenu.visible = false;
researchCategoryMenu.visible = true;
var displayName = category === 'GameGenres' ? 'Game Genres' : category;
categoryTitle.setText(displayName + ' Research');
// Clear existing items
for (var i = researchCategoryMenu.children.length - 1; i >= 0; i--) {
var child = researchCategoryMenu.children[i];
if (child !== categoryTitle && child !== categoryBackBtn) {
child.destroy();
}
}
// Get researchable items for this category
var items = [];
if (category === 'GameGenres') {
items = gameGenres.filter(function (genre) {
return genre.requiresResearch && gameState.researchedFeatures.GameGenres.indexOf(genre.name) === -1;
});
} else {
items = featurePool.filter(function (feature) {
return feature.type === category && feature.requiresResearch && gameState.researchedFeatures[category].indexOf(feature.name) === -1;
});
}
// Display research items
items.forEach(function (item, index) {
var container = new Container();
container.x = 1024;
container.y = 400 + index * 120;
var bg = LK.getAsset('card', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2,
scaleY: 0.4
});
container.addChild(bg);
var nameText = new Text2(item.name, {
size: 30,
fill: 0xFFFFFF
});
nameText.anchor.set(0.5, 0.5);
nameText.y = -20;
container.addChild(nameText);
var cost = category === 'GameGenres' ? item.researchCost : item.cost * 3;
var costText = new Text2('Research Cost: $' + cost, {
size: 25,
fill: 0x4CAF50
});
costText.anchor.set(0.5, 0.5);
costText.y = 20;
container.addChild(costText);
container.interactive = true;
container.down = function () {
if (gameState.money >= cost && !gameState.currentResearch) {
gameState.money -= cost;
gameState.currentResearch = {
name: item.name,
category: category,
timeRemaining: 180 // 3 seconds
};
updateUI();
LK.getSound('select').play();
showResearchCategory(category);
}
};
researchCategoryMenu.addChild(container);
});
// Add research option to increase selection limit for this category (if not already maxed)
if (category === 'Graphics' || category === 'Sound' || category === 'Gameplay') {
var maxLimit = 5;
var currentLimit = 1;
if (gameState.featureSelectionLimit && typeof gameState.featureSelectionLimit[category] === "number") {
currentLimit = gameState.featureSelectionLimit[category];
}
if (currentLimit < maxLimit) {
var y = 400 + items.length * 120 + 60;
var limitContainer = new Container();
limitContainer.x = 1024;
limitContainer.y = y;
var bg2 = LK.getAsset('card', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2,
scaleY: 0.4
});
limitContainer.addChild(bg2);
var limitText = new Text2('Seçim Limiti Artır: ' + category + ' (' + currentLimit + ' → ' + (currentLimit + 1) + ')', {
size: 30,
fill: 0xFFC107
});
limitText.anchor.set(0.5, 0.5);
limitText.y = -20;
limitContainer.addChild(limitText);
var limitCost = 8000 * currentLimit;
var limitCostText = new Text2('Araştırma Maliyeti: $' + limitCost, {
size: 25,
fill: 0x4CAF50
});
limitCostText.anchor.set(0.5, 0.5);
limitCostText.y = 20;
limitContainer.addChild(limitCostText);
limitContainer.interactive = true;
limitContainer.down = function () {
if (gameState.money >= limitCost && !gameState.currentResearch) {
gameState.money -= limitCost;
gameState.currentResearch = {
name: 'IncreaseLimit_' + category,
category: 'IncreaseLimit_' + category,
timeRemaining: 180
};
updateUI();
LK.getSound('select').play();
showResearchCategory(category);
}
};
researchCategoryMenu.addChild(limitContainer);
}
}
// Add a Back button specifically for Game Genres, Gameplay, Graphics, and Sound Research page
if (category === 'GameGenres' || category === 'Gameplay' || category === 'Graphics' || category === 'Sound') {
// Remove previous genre/gameplay/graphics/sound back button if any
if (researchCategoryMenu.genreBackBtn) {
researchCategoryMenu.removeChild(researchCategoryMenu.genreBackBtn);
researchCategoryMenu.genreBackBtn.destroy();
researchCategoryMenu.genreBackBtn = null;
}
var genreBackBtn = new Button();
genreBackBtn.setLabel('Back');
genreBackBtn.x = 1024;
genreBackBtn.y = 2400;
genreBackBtn.onClick = function () {
researchCategoryMenu.visible = false;
researchMenu.visible = true;
updateGlobalBackBtn && updateGlobalBackBtn();
};
researchCategoryMenu.addChild(genreBackBtn);
researchCategoryMenu.genreBackBtn = genreBackBtn;
}
// Show current research if any
if (gameState.currentResearch) {
var researchInfo = new Text2('Currently researching: ' + gameState.currentResearch.name, {
size: 35,
fill: 0xFFC107
});
researchInfo.anchor.set(0.5, 0.5);
researchInfo.x = 1024;
researchInfo.y = 300;
researchCategoryMenu.addChild(researchInfo);
}
}
function showNameGameMenu() {
mainMenu.visible = false;
nameGameMenu.visible = true;
currentGameName = '';
gameNameInput.setText('');
}
function generateRandomName() {
var prefixes = ['Super', 'Mega', 'Ultra', 'Epic', 'Legendary', 'Amazing', 'Incredible', 'Fantastic'];
var genres = ['Adventure', 'Quest', 'Battle', 'World', 'Kingdom', 'Legend', 'Saga', 'Chronicles'];
var suffixes = ['2000', 'X', 'Plus', 'HD', 'Remastered', 'Ultimate', 'Deluxe', 'Pro'];
var name = prefixes[Math.floor(Math.random() * prefixes.length)] + ' ' + genres[Math.floor(Math.random() * genres.length)] + ' ' + suffixes[Math.floor(Math.random() * suffixes.length)];
currentGameName = name;
gameNameInput.setText(name);
LK.getSound('select').play();
}
function confirmGameName() {
if (currentGameName && currentGameName.length > 0) {
// Store the game name for later use
nameGameMenu.visible = false;
// If projectMenu is hidden, show it again (for project flow)
if (!mainMenu.visible && projectMenu) {
projectMenu.visible = true;
} else {
mainMenu.visible = true;
}
LK.getSound('success').play();
// Update game name display
gameNameDisplay.setText('Next Game: ' + currentGameName);
// Show confirmation message
var confirmText = new Text2('Next game will be: ' + currentGameName, {
size: 30,
fill: 0x4CAF50
});
confirmText.anchor.set(0.5, 0.5);
confirmText.x = 1024;
confirmText.y = 1050;
confirmText.alpha = 0;
mainMenu.addChild(confirmText);
tween(confirmText, {
alpha: 1
}, {
duration: 500,
onFinish: function onFinish() {
LK.setTimeout(function () {
tween(confirmText, {
alpha: 0
}, {
duration: 500,
onFinish: function onFinish() {
confirmText.destroy();
}
});
}, 2000);
}
});
}
}
function showAllGamesMenu() {
mainMenu.visible = false;
allGamesMenu.visible = true;
// Clear existing game cards
var cardsToRemove = [];
allGamesMenu.children.forEach(function (child) {
if (child instanceof GameHistoryCard) {
cardsToRemove.push(child);
}
});
cardsToRemove.forEach(function (card) {
card.destroy();
});
// Show all games (both active and completed)
var allGames = gameState.releasedGames.concat(gameState.gameHistory);
if (allGames.length === 0) {
noGamesText.visible = true;
} else {
noGamesText.visible = false;
allGames.forEach(function (game, index) {
var card = new GameHistoryCard();
card.setGameData(game);
card.x = 1024;
card.y = 400 + index * 150;
card.onClick = showGameDetail;
allGamesMenu.addChild(card);
});
}
}
function showGameDetail(gameData) {
allGamesMenu.visible = false;
gameDetailView.visible = true;
// Clear previous content
for (var i = gameDetailView.children.length - 1; i >= 0; i--) {
if (gameDetailView.children[i] !== detailBackBtn) {
gameDetailView.children[i].destroy();
}
}
// Game title
var titleText = new Text2(gameData.name, {
size: 60,
fill: 0xFFFFFF
});
titleText.anchor.set(0.5, 0.5);
titleText.x = 1024;
titleText.y = 200;
gameDetailView.addChild(titleText);
// Release info
var releaseText = new Text2('Released on Day ' + gameData.releaseDay, {
size: 35,
fill: 0x2196F3
});
releaseText.anchor.set(0.5, 0.5);
releaseText.x = 1024;
releaseText.y = 300;
gameDetailView.addChild(releaseText);
// Sales info
var salesStatus = gameData.currentDailySales > 0 ? 'Active' : 'Ended';
var salesText = new Text2('Total Sales: ' + gameData.totalSales + ' copies (' + salesStatus + ')', {
size: 35,
fill: 0x4CAF50
});
salesText.anchor.set(0.5, 0.5);
salesText.x = 1024;
salesText.y = 380;
gameDetailView.addChild(salesText);
// Show total earned money (use actual price and revenue formula)
var pricePerCopy = typeof gameData.price === "number" ? gameData.price : 1;
var totalMoneyEarned = Math.floor((gameData.totalSales || 0) * pricePerCopy);
var moneyText = new Text2('Total Money Earned: $' + totalMoneyEarned, {
size: 32,
fill: 0xFFC107
});
moneyText.anchor.set(0.5, 0.5);
moneyText.x = 1024;
moneyText.y = 420;
gameDetailView.addChild(moneyText);
// Score info
var scoreText = new Text2('Score: ' + Math.floor(gameData.score) + ' / ' + gameData.targetScore, {
size: 35,
fill: 0xFFC107
});
scoreText.anchor.set(0.5, 0.5);
scoreText.x = 1024;
scoreText.y = 460;
gameDetailView.addChild(scoreText);
// Show price per copy
if (typeof gameData.price === "number") {
var priceText = new Text2('Oyun Fiyatı: $' + gameData.price, {
size: 32,
fill: 0xFFC107
});
priceText.anchor.set(0.5, 0.5);
priceText.x = 1024;
priceText.y = 500;
gameDetailView.addChild(priceText);
}
// Genre info
if (gameData.genre) {
var genreText = new Text2('Genre: ' + gameData.genre.name, {
size: 35,
fill: 0x9C27B0
});
genreText.anchor.set(0.5, 0.5);
genreText.x = 1024;
genreText.y = 540;
gameDetailView.addChild(genreText);
}
// Features title
var featuresTitle = new Text2('Features Used:', {
size: 40,
fill: 0xFFFFFF
});
featuresTitle.anchor.set(0.5, 0.5);
featuresTitle.x = 1024;
featuresTitle.y = 600;
gameDetailView.addChild(featuresTitle);
// Display features
gameData.features.forEach(function (feature, index) {
var featureText = new Text2('• ' + feature.name + ' (' + feature.type + ')', {
size: 30,
fill: 0x2196F3
});
featureText.anchor.set(0.5, 0.5);
featureText.x = 1024;
featureText.y = 680 + index * 40;
gameDetailView.addChild(featureText);
});
// Developers title
var devsTitle = new Text2('Developed by:', {
size: 40,
fill: 0xFFFFFF
});
devsTitle.anchor.set(0.5, 0.5);
devsTitle.x = 1024;
devsTitle.y = 1000;
gameDetailView.addChild(devsTitle);
// Display developers if stored
if (gameData.developers) {
gameData.developers.forEach(function (dev, index) {
var devText = new Text2('• ' + dev.name + ' (' + dev.specialty + ', Skill: ' + dev.skill + ')', {
size: 30,
fill: 0xFFC107
});
devText.anchor.set(0.5, 0.5);
devText.x = 1024;
devText.y = 1080 + index * 40;
gameDetailView.addChild(devText);
});
}
// Show reviews if present
if (gameData.reviews && gameData.reviews.length > 0) {
var reviewsTitle = new Text2('Reviews:', {
size: 40,
fill: 0xFFFFFF
});
reviewsTitle.anchor.set(0.5, 0.5);
reviewsTitle.x = 1024;
reviewsTitle.y = 1400;
gameDetailView.addChild(reviewsTitle);
// Show average review score
var avgScore = 0;
for (var i = 0; i < gameData.reviews.length; i++) {
avgScore += gameData.reviews[i].score;
}
avgScore = Math.round(avgScore / gameData.reviews.length);
var avgScoreText = new Text2('Average Score: ' + avgScore + '/100', {
size: 35,
fill: avgScore >= 80 ? 0x4CAF50 : avgScore >= 60 ? 0xFFC107 : 0xE94560
});
avgScoreText.anchor.set(0.5, 0.5);
avgScoreText.x = 1024;
avgScoreText.y = 1460;
gameDetailView.addChild(avgScoreText);
// Show up to 10 reviews
gameData.reviews.forEach(function (review, idx) {
var reviewText = new Text2(review.company + ": " + review.score + "/100 - " + review.text, {
size: 28,
fill: 0xFFFFFF
});
reviewText.anchor.set(0.5, 0.5);
reviewText.x = 1024;
reviewText.y = 1540 + idx * 60;
gameDetailView.addChild(reviewText);
});
}
}
function showHireMenu() {
mainMenu.visible = false;
hireMenu.visible = true;
// Clear existing cards
developerCards.forEach(function (card) {
card.destroy();
});
developerCards = [];
// Show available developers info
var infoText = new Text2('Available Developers: ' + gameState.maxHireableDevelopers, {
size: 35,
fill: 0xFFC107
});
infoText.anchor.set(0.5, 0.5);
infoText.x = 1024;
infoText.y = 350;
hireMenu.addChild(infoText);
// Show main character as always hired
var mainCharCard = new DeveloperCard();
mainCharCard.setDeveloper({
name: gameState.mainCharacter.name,
specialty: "All",
skill: gameState.mainCharacter.skill,
cost: 0
});
mainCharCard.x = 1024;
mainCharCard.y = 600;
mainCharCard.developerData = {
name: gameState.mainCharacter.name,
specialty: "All",
skill: gameState.mainCharacter.skill,
cost: 0
};
mainCharCard.down = function () {};
hireMenu.addChild(mainCharCard);
developerCards.push(mainCharCard);
// Create developer cards as a grid, restrict hiring to studio level
var availableDevelopers = developerPool.filter(function (dev) {
return !gameState.developers.some(function (hired) {
return hired.name === dev.name;
});
});
// Only allow hiring up to maxHireableDevelopers (studioLevel+1, including main character)
var canHireCount = gameState.maxHireableDevelopers - gameState.developers.length;
if (canHireCount < 0) canHireCount = 0;
// Arrange developer cards in a grid (3 per row)
var cardsPerRow = 3;
var cardSpacingX = 400;
var cardSpacingY = 500;
var startX = 1024 - cardSpacingX;
var startY = 1000;
availableDevelopers.forEach(function (dev, index) {
var card = new DeveloperCard();
card.setDeveloper(dev);
var col = index % cardsPerRow;
var row = Math.floor(index / cardsPerRow);
card.x = startX + col * cardSpacingX;
card.y = startY + row * cardSpacingY;
// If we can't hire more, gray out the card and disable click
if (index >= canHireCount) {
card.alpha = 0.4;
card.down = function () {
// Optionally show a message or play a sound
LK.getSound('select').play();
};
// Show a message overlay
var lockText = new Text2('Stüdyo seviyesini yükseltmelisin', {
size: 28,
fill: 0xE94560
});
lockText.anchor.set(0.5, 0.5);
lockText.y = 160;
card.addChild(lockText);
} else {
card.onClick = function (developer) {
if (gameState.money >= developer.cost) {
gameState.money -= developer.cost;
gameState.developers.push({
name: developer.name,
specialty: developer.specialty,
skill: developer.skill,
cost: developer.cost,
assignedFeature: null // Only 1 feature can be assigned
});
updateUI();
LK.getSound('hire').play();
showHireMenu(); // Refresh menu
}
};
}
hireMenu.addChild(card);
developerCards.push(card);
});
}
function showFeatureCategory(category) {
projectMenu.visible = false;
featureCategoryMenu.visible = true;
categoryMenuTitle.setText(category + ' Features');
selectedFeaturesText.setText('Selected: ' + selectedFeatures.length);
// Clear existing feature cards
for (var i = featureCategoryMenu.children.length - 1; i >= 0; i--) {
var child = featureCategoryMenu.children[i];
if (child instanceof FeatureCard) {
child.destroy();
}
}
// Get available features for this category
var availableFeatures = featurePool.filter(function (feature) {
return feature.type === category && (!feature.requiresResearch || gameState.researchedFeatures[feature.type].indexOf(feature.name) !== -1);
});
// Create feature cards
availableFeatures.forEach(function (feature, index) {
var card = new FeatureCard();
card.setFeature(feature);
card.x = 400 + index % 4 * 250;
card.y = 500 + Math.floor(index / 4) * 350;
// Set selected state if already selected
var isSelected = selectedFeatures.some(function (f) {
return f.name === feature.name;
});
card.setSelected(isSelected);
// Highlight trending features
if (gameState.marketTrends.indexOf(feature.type) !== -1) {
var trendIcon = LK.getAsset('trendIcon', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.3,
scaleY: 0.3
});
trendIcon.x = 100;
trendIcon.y = -100;
card.addChild(trendIcon);
}
card.onClick = function (clickedCard) {
var cat = category;
// Determine max selection for this category
var maxPerCategory = 1;
if (gameState.featureSelectionLimit && typeof gameState.featureSelectionLimit[cat] === "number") {
maxPerCategory = gameState.featureSelectionLimit[cat];
}
// Count how many are already selected in this category
var selectedInCategory = selectedFeatures.filter(function (f) {
return f.type === cat;
}).length;
// If already selected, deselect
if (clickedCard.selected) {
clickedCard.setSelected(false);
selectedFeatures = selectedFeatures.filter(function (f) {
return f !== clickedCard.featureData;
});
// If this was the only selected in category, clear selectedFeatureByCategory
if (selectedFeatureByCategory[cat] && selectedFeatureByCategory[cat].name === clickedCard.featureData.name) {
selectedFeatureByCategory[cat] = null;
}
} else {
// Only allow up to maxPerCategory selections per category
if (selectedInCategory >= maxPerCategory) {
// Show notification
var notification = new Container();
game.addChild(notification);
var bg = LK.getAsset('card', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2,
scaleY: 0.6
});
bg.tint = 0xE94560;
notification.addChild(bg);
var text = new Text2('Bu kategoriden en fazla ' + maxPerCategory + ' özellik seçebilirsin!', {
size: 35,
fill: 0xFFFFFF
});
text.anchor.set(0.5, 0.5);
notification.addChild(text);
notification.x = 1024;
notification.y = 600;
notification.alpha = 0;
tween(notification, {
alpha: 1
}, {
duration: 500,
onFinish: function onFinish() {
LK.setTimeout(function () {
tween(notification, {
alpha: 0
}, {
duration: 500,
onFinish: function onFinish() {
notification.destroy();
}
});
}, 2000);
}
});
return;
}
clickedCard.setSelected(true);
selectedFeatures.push(clickedCard.featureData);
selectedFeatureByCategory[cat] = clickedCard.featureData;
LK.getSound('select').play();
}
// Update selected count
selectedFeaturesText.setText('Selected: ' + selectedFeatures.length);
};
featureCategoryMenu.addChild(card);
});
}
function showProjectMenu() {
// Allow project creation if there is at least one developer OR the main character (always present)
if (gameState.developers.length === 0 && !gameState.mainCharacter) {
return;
}
mainMenu.visible = false;
projectMenu.visible = true;
selectedFeatures = [];
// Reset per-category selection
selectedFeatureByCategory.Graphics = null;
selectedFeatureByCategory.Sound = null;
selectedFeatureByCategory.Gameplay = null;
// Clear existing cards
featureCards.forEach(function (card) {
card.destroy();
});
featureCards = [];
// Clear any existing category buttons, but do NOT destroy persistent buttons (priceBtn, platformBtn, gameGenresResearchBtn, startDevelopmentBtn, backFromProjectBtn)
for (var i = projectMenu.children.length - 1; i >= 0; i--) {
var child = projectMenu.children[i];
// Only destroy category feature buttons (those not persistent)
if (child instanceof Button && child !== startDevelopmentBtn && child !== backFromProjectBtn && child !== projectMenu.priceBtn && child !== projectMenu.platformBtn && child !== projectMenu.gameGenresResearchBtn) {
child.destroy();
}
}
// Restore selected genre from gameState if available
if (gameState.selectedGenre) {
projectMenu.selectedGenre = gameState.selectedGenre;
} else {
projectMenu.selectedGenre = null;
gameState.selectedGenre = null;
}
// Update selected genre text
if (projectMenu.genreText) {
projectMenu.genreText.setText('Selected Genre: ' + (projectMenu.selectedGenre ? projectMenu.selectedGenre.name : 'None'));
}
// Persist marketTrends for the duration of a project (until game is released)
// Only generate new trends if there are no trends yet (i.e., at the start of a new project, not just on menu open)
if (!gameState.marketTrends || !Array.isArray(gameState.marketTrends) || gameState.marketTrends.length === 0) {
gameState.marketTrends = [];
var trendTypes = ['Graphics', 'Sound', 'Gameplay'];
var availableGenres = gameGenres.filter(function (genre) {
return !genre.requiresResearch || gameState.researchedFeatures.GameGenres.indexOf(genre.name) !== -1;
});
// Only allow market trends from researched genres
var researchedGenres = gameGenres.filter(function (genre) {
return !genre.requiresResearch || gameState.researchedFeatures.GameGenres.indexOf(genre.name) !== -1;
});
var trend = trendTypes[Math.floor(Math.random() * trendTypes.length)];
gameState.marketTrends.push(trend);
// Only pick genre trends from researched genres
if (researchedGenres.length > 0) {
var genreTrend = researchedGenres[Math.floor(Math.random() * researchedGenres.length)];
gameState.marketTrends.push(genreTrend.name + ' games');
}
}
// --- Ava: Destroy old Market Trends and Total Cost text to prevent duplicates ---
if (projectMenu.trendsText) {
projectMenu.trendsText.destroy();
projectMenu.trendsText = null;
}
if (projectMenu.totalCostText) {
projectMenu.totalCostText.destroy();
projectMenu.totalCostText = null;
}
// Display trends at top
var trendsText = new Text2('Market Trends: ' + gameState.marketTrends.join(' & ') + ' are hot!', {
size: 35,
fill: 0xFF5722
});
trendsText.anchor.set(0.5, 0.5);
trendsText.x = 1024;
trendsText.y = 400;
projectMenu.addChild(trendsText);
projectMenu.trendsText = trendsText;
// --- Ava: Show sales bonus summary for selected features ---
if (projectMenu.featureBonusText) {
projectMenu.featureBonusText.destroy();
}
var featureBonusSummary = '';
(function () {
// Calculate bonuses for selected features
var bonusParts = [];
// Platform bonus
var selectedPlatformName = gameState.selectedPlatform || "PC";
var selectedPlatformObj = null;
for (var i = 0; i < platforms.length; i++) {
if (platforms[i].name === selectedPlatformName) {
selectedPlatformObj = platforms[i];
break;
}
}
if (selectedPlatformObj && selectedPlatformObj.salesBonus) {
bonusParts.push('Platform: +' + Math.round(selectedPlatformObj.salesBonus * 100) + '% satış');
}
// Genre bonus
if (projectMenu.selectedGenre) {
var genreObj = null;
for (var i = 0; i < gameGenres.length; i++) {
if (gameGenres[i].name === projectMenu.selectedGenre.name) {
genreObj = gameGenres[i];
break;
}
}
if (genreObj && genreObj.baseMultiplier && genreObj.baseMultiplier > 1) {
bonusParts.push('Tür: +' + Math.round((genreObj.baseMultiplier - 1) * 100) + '% satış');
}
}
// Feature trend bonus
var trendTypes = [];
if (gameState.marketTrends && Array.isArray(gameState.marketTrends)) {
for (var i = 0; i < gameState.marketTrends.length; i++) {
if (gameState.marketTrends[i] === "Graphics" || gameState.marketTrends[i] === "Sound" || gameState.marketTrends[i] === "Gameplay") {
trendTypes.push(gameState.marketTrends[i]);
}
}
}
var trendBonus = 0;
if (trendTypes.length > 0 && selectedFeatures && selectedFeatures.length > 0) {
for (var i = 0; i < selectedFeatures.length; i++) {
if (trendTypes.indexOf(selectedFeatures[i].type) !== -1) {
trendBonus = 50;
break;
}
}
if (trendBonus > 0) {
bonusParts.push('Trend Özellik: +50% satış');
}
}
// Genre trend bonus
if (projectMenu.selectedGenre && gameState.marketTrends && Array.isArray(gameState.marketTrends)) {
for (var i = 0; i < gameState.marketTrends.length; i++) {
if (typeof gameState.marketTrends[i] === "string" && gameState.marketTrends[i].indexOf(projectMenu.selectedGenre.name) !== -1) {
bonusParts.push('Trend Tür: +30% satış');
break;
}
}
}
// Fan bonus (platform-specific)
var fanBonus = 0;
var selectedPlatformObj = null;
if (gameState.selectedPlatform) {
for (var pi = 0; pi < platforms.length; pi++) {
if (platforms[pi].name === gameState.selectedPlatform) {
selectedPlatformObj = platforms[pi];
break;
}
}
}
if (gameState.fans && gameState.fans > 0) {
fanBonus = gameState.fans / 100000 * 100;
if (fanBonus > 100) fanBonus = 100;
if (fanBonus > 0) {
if (selectedPlatformObj && typeof selectedPlatformObj.salesBonus === "number") {
var platformFanBonus = Math.round(fanBonus * selectedPlatformObj.salesBonus);
bonusParts.push('Fan: +' + platformFanBonus + '% satış (platforma göre)');
} else {
bonusParts.push('Fan: +' + Math.round(fanBonus) + '% satış');
}
}
}
// Compose summary
if (bonusParts.length > 0) {
featureBonusSummary = 'Satış Bonusları: ' + bonusParts.join(', ');
} else {
featureBonusSummary = 'Satış bonusu yok.';
}
})();
// Satış Bonusları: yazısını 2 satır olacak şekilde ayarla ve hizala
var featureBonusLines = [];
if (featureBonusSummary.length > 40) {
// Satış bonusu metni uzunsa, virgülden bölerek iki satıra ayır
var parts = featureBonusSummary.split(':');
if (parts.length > 1) {
var bonuses = parts[1].split(',');
var mid = Math.ceil(bonuses.length / 2);
var firstLine = (parts[0] + ':' + bonuses.slice(0, mid).join(',')).trim();
var secondLine = bonuses.slice(mid).join(',').trim();
featureBonusLines = [firstLine, secondLine];
} else {
featureBonusLines = [featureBonusSummary, ''];
}
} else {
featureBonusLines = [featureBonusSummary, ''];
}
var featureBonusText = new Text2(featureBonusLines[0] + (featureBonusLines[1] ? '\n' + featureBonusLines[1] : ''), {
size: 32,
fill: 0x4CAF50,
align: "center"
});
featureBonusText.anchor.set(0.5, 0.5);
featureBonusText.x = 1024;
featureBonusText.y = 360;
projectMenu.addChild(featureBonusText);
projectMenu.featureBonusText = featureBonusText;
// --- Satış Bonusları kutusunun altındaki butonları aşağı kaydır (hizalama) ---
var buttonY = 650 + 240; // Move all buttons 2 rows (240px) down
if (featureBonusText.height > 40) {
buttonY += 30; // 2 satır ise biraz daha aşağı kaydır
}
var buttonSpacing = 120;
// Feature category buttons
var categories = ['Graphics', 'Sound', 'Gameplay'];
categories.forEach(function (category, index) {
var categoryBtn = new Button();
categoryBtn.setLabel(category + ' Features');
categoryBtn.x = 1024;
categoryBtn.y = buttonY;
categoryBtn.onClick = function () {
showFeatureCategory(category);
};
projectMenu.addChild(categoryBtn);
buttonY += buttonSpacing;
});
// Oyun Fiyatı button (move to next row)
if (projectMenu.priceBtn) {
// If not already present, re-add to projectMenu
if (projectMenu.children.indexOf(projectMenu.priceBtn) === -1) {
projectMenu.addChild(projectMenu.priceBtn);
}
projectMenu.priceBtn.y = buttonY;
buttonY += buttonSpacing;
}
// Game Genres Research button (move to next row)
if (!projectMenu.gameGenresResearchBtn) {
var gameGenresResearchBtn = new Button();
gameGenresResearchBtn.setLabel('Game Genres Research');
gameGenresResearchBtn.x = 1024;
gameGenresResearchBtn.y = buttonY;
gameGenresResearchBtn.onClick = function () {
showProjectGenresResearchMenu();
};
projectMenu.addChild(gameGenresResearchBtn);
projectMenu.gameGenresResearchBtn = gameGenresResearchBtn;
} else {
// If not already present, re-add to projectMenu
if (projectMenu.children.indexOf(projectMenu.gameGenresResearchBtn) === -1) {
projectMenu.addChild(projectMenu.gameGenresResearchBtn);
}
projectMenu.gameGenresResearchBtn.y = buttonY;
}
// Move Platform Seç button to be below the last button
if (projectMenu.platformBtn) {
projectMenu.platformBtn.y = buttonY + buttonSpacing;
buttonY = projectMenu.platformBtn.y;
}
// Add Oyun Adı Seç button below Platform Seç
if (!projectMenu.nameGameBtn) {
var nameGameBtn = new Button();
nameGameBtn.setLabel('Oyun Adı Seç');
nameGameBtn.x = 1024;
nameGameBtn.y = buttonY + buttonSpacing;
nameGameBtn.onClick = function () {
mainMenu.visible = false;
projectMenu.visible = false;
nameGameMenu.visible = true;
currentGameName = '';
gameNameInput.setText('');
};
projectMenu.addChild(nameGameBtn);
projectMenu.nameGameBtn = nameGameBtn;
} else {
// If not already present, re-add to projectMenu
if (projectMenu.children.indexOf(projectMenu.nameGameBtn) === -1) {
projectMenu.addChild(projectMenu.nameGameBtn);
}
projectMenu.nameGameBtn.y = buttonY + buttonSpacing;
}
buttonY = projectMenu.nameGameBtn.y;
// Add info text at the bottom of the platform selection page in Start Project
if (projectMenu.platformInfoText) {
projectMenu.platformInfoText.destroy();
}
var projectPlatformInfoText = new Text2('To use a platform, purchase it from the platform page in the main menu.', {
size: 32,
fill: 0xFFC107
});
projectPlatformInfoText.anchor.set(0.5, 0.5);
projectPlatformInfoText.x = 1024;
projectPlatformInfoText.y = 2500;
projectMenu.addChild(projectPlatformInfoText);
projectMenu.platformInfoText = projectPlatformInfoText;
// Add info note about research and increasing selectable features
if (projectMenu.featureResearchInfoText) {
projectMenu.featureResearchInfoText.destroy();
}
var featureResearchInfoText = new Text2("You can research new features and increase the number of selectable features from the Research section in the main menu.", {
size: 30,
fill: 0x4CAF50,
align: "center"
});
featureResearchInfoText.anchor.set(0.5, 1);
featureResearchInfoText.x = 1024;
featureResearchInfoText.y = 2450;
projectMenu.addChild(featureResearchInfoText);
projectMenu.featureResearchInfoText = featureResearchInfoText;
// --- Genre selection UI removed: genre can only be selected from Game Genres Research page ---
// Show selected genre (if any)
if (!projectMenu.selectedGenre) {
projectMenu.selectedGenre = null;
gameState.selectedGenre = null;
}
if (projectMenu.genreText) {
projectMenu.genreText.destroy();
projectMenu.genreText = null;
}
var genreText = new Text2('Selected Genre: ' + (projectMenu.selectedGenre ? projectMenu.selectedGenre.name : 'None'), {
size: 35,
fill: 0x9C27B0
});
genreText.anchor.set(0.5, 0.5);
genreText.x = 1024;
genreText.y = 480;
projectMenu.addChild(genreText);
projectMenu.genreText = genreText;
// Total cost display
var totalCostText = new Text2('Total Cost: $0', {
size: 35,
fill: 0x4CAF50
});
totalCostText.anchor.set(0.5, 0.5);
totalCostText.x = 1024;
totalCostText.y = 530;
projectMenu.addChild(totalCostText);
// Store totalCostText reference for later updates
projectMenu.totalCostText = totalCostText;
// --- Oyun Fiyatı (Game Price) UI ---
if (!projectMenu.priceText) {
// Default price per copy
if (typeof projectMenu.selectedPrice !== "number") {
projectMenu.selectedPrice = 1; // $1 per copy default
}
var priceText = new Text2('Oyun Fiyatı: $' + projectMenu.selectedPrice, {
size: 35,
fill: 0xFFC107
});
priceText.anchor.set(0.5, 0.5);
priceText.x = 1024;
priceText.y = 580;
projectMenu.addChild(priceText);
projectMenu.priceText = priceText;
// Price select button
var priceBtn = new Button();
priceBtn.setLabel('Oyun Fiyatı Seç');
priceBtn.x = 1024;
priceBtn.y = 630;
priceBtn.onClick = function () {
// Show a simple price selection popup
if (projectMenu.pricePopup) {
projectMenu.pricePopup.destroy();
projectMenu.pricePopup = null;
}
var popup = new Container();
popup.x = 1024;
popup.y = 900;
var bg = LK.getAsset('card', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2,
scaleY: 1
});
bg.tint = 0x16213e;
popup.addChild(bg);
var title = new Text2('Oyun Fiyatı Seçin', {
size: 40,
fill: 0xFFC107
});
title.anchor.set(0.5, 0.5);
title.y = -120;
popup.addChild(title);
// Price options
var prices = [0.5, 1, 2, 3, 5, 10];
prices.forEach(function (p, idx) {
var btn = new Button();
btn.setLabel('$' + p);
btn.x = 0;
btn.y = -40 + idx * 70;
btn.onClick = function () {
projectMenu.selectedPrice = p;
projectMenu.priceText.setText('Oyun Fiyatı: $' + p);
if (projectMenu.pricePopup) {
projectMenu.pricePopup.destroy();
projectMenu.pricePopup = null;
}
LK.getSound('select').play();
};
popup.addChild(btn);
});
// Close button
var closeBtn = new Button();
closeBtn.setLabel('Kapat');
closeBtn.x = 0;
closeBtn.y = 400;
closeBtn.onClick = function () {
if (projectMenu.pricePopup) {
projectMenu.pricePopup.destroy();
projectMenu.pricePopup = null;
}
};
popup.addChild(closeBtn);
projectMenu.pricePopup = popup;
game.addChild(popup);
};
projectMenu.addChild(priceBtn);
projectMenu.priceBtn = priceBtn;
}
// If a game name was set, show it in projectMenu
if (currentGameName && currentGameName.length > 0) {
if (projectMenu.gameNameText) {
projectMenu.gameNameText.destroy();
}
var gameNameText = new Text2('Oyun Adı: ' + currentGameName, {
size: 35,
fill: 0xFFC107
});
gameNameText.anchor.set(0.5, 0.5);
gameNameText.x = 1024;
gameNameText.y = 800;
projectMenu.addChild(gameNameText);
projectMenu.gameNameText = gameNameText;
} else if (projectMenu.gameNameText) {
projectMenu.gameNameText.destroy();
projectMenu.gameNameText = null;
}
if (projectMenu.engineText) {
projectMenu.engineText.destroy();
}
// (Game Engine UI removed)
// --- Platform Selection Button and Text ---
if (projectMenu.platformText) {
projectMenu.platformText.destroy();
projectMenu.platformText = null;
}
var selectedPlatformName = gameState.selectedPlatform || "PC";
var platformText = new Text2('Platform: ' + selectedPlatformName, {
size: 35,
fill: 0xFFC107
});
platformText.anchor.set(0.5, 0.5);
platformText.x = 1024;
platformText.y = 750;
projectMenu.addChild(platformText);
projectMenu.platformText = platformText;
if (!projectMenu.platformBtn) {
var platformBtn = new Button();
platformBtn.setLabel('Platform Seç');
platformBtn.x = 1024;
// We'll set the y position after all other buttons are placed
platformBtn.onClick = function () {
// Show the platformMenu as a page, but in selection mode
mainMenu.visible = false;
projectMenu.visible = false;
platformMenu.visible = true;
platformMenu.y = 0;
// Mark that we are in platform selection mode for projectMenu
platformMenu._selectForProjectMenu = true;
// Remove old platform cards/buttons except title and back
for (var i = platformMenu.children.length - 1; i >= 0; i--) {
var child = platformMenu.children[i];
if (child !== platformTitle && child !== platformBackBtn) {
child.destroy();
}
}
// Show only owned platforms as selectable, others as locked
var yStart = 500;
var xStart = 320;
var xSpacing = 350;
var ySpacing = 220;
var cols = 4;
for (var i = 0; i < platforms.length; i++) {
var plat = platforms[i];
var container = new Container();
var col = i % cols;
var row = Math.floor(i / cols);
container.x = xStart + col * xSpacing;
container.y = yStart + row * ySpacing;
var bg = LK.getAsset('card', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.0,
scaleY: 0.35
});
container.addChild(bg);
var nameText = new Text2(plat.name, {
size: 35,
fill: 0xFFFFFF
});
nameText.anchor.set(0.5, 0.5);
nameText.y = -30;
container.addChild(nameText);
var yearText = new Text2('Çıkış: ' + plat.year, {
size: 28,
fill: 0x4CAF50
});
yearText.anchor.set(0.5, 0.5);
yearText.y = 10;
container.addChild(yearText);
var bonusText = new Text2('Satış Bonus: +' + Math.round(plat.salesBonus * 100) + '%', {
size: 24,
fill: 0x2196F3
});
bonusText.anchor.set(0.5, 0.5);
bonusText.y = 40;
container.addChild(bonusText);
var platState = gameState.platforms && gameState.platforms[plat.name] ? gameState.platforms[plat.name] : {
researched: plat.researched,
owned: plat.owned
};
if (platState && platState.owned) {
// Selectable for projectMenu
var selectBtn = new Button();
selectBtn.setLabel(gameState.selectedPlatform === plat.name ? 'Seçili' : 'Seç');
selectBtn.x = 0;
selectBtn.y = 100;
if (gameState.selectedPlatform === plat.name) {
selectBtn.children[0].tint = 0xe94560;
}
selectBtn.onClick = function (platName) {
return function () {
gameState.selectedPlatform = platName;
if (projectMenu.platformText) {
projectMenu.platformText.setText('Platform: ' + platName);
}
LK.getSound('select').play();
// Return to projectMenu after selection
platformMenu.visible = false;
projectMenu.visible = true;
platformMenu._selectForProjectMenu = false;
// Restore persistent buttons if missing
if (projectMenu.priceBtn && projectMenu.children.indexOf(projectMenu.priceBtn) === -1) {
projectMenu.addChild(projectMenu.priceBtn);
}
if (projectMenu.platformBtn && projectMenu.children.indexOf(projectMenu.platformBtn) === -1) {
projectMenu.addChild(projectMenu.platformBtn);
}
if (projectMenu.gameGenresResearchBtn && projectMenu.children.indexOf(projectMenu.gameGenresResearchBtn) === -1) {
projectMenu.addChild(projectMenu.gameGenresResearchBtn);
}
// --- Ava: Update sales bonus summary instantly when platform is changed ---
if (projectMenu.featureBonusText) {
projectMenu.featureBonusText.destroy();
}
var featureBonusSummary = '';
(function () {
var bonusParts = [];
// Platform bonus
var selectedPlatformName = gameState.selectedPlatform || "PC";
var selectedPlatformObj = null;
for (var i = 0; i < platforms.length; i++) {
if (platforms[i].name === selectedPlatformName) {
selectedPlatformObj = platforms[i];
break;
}
}
if (selectedPlatformObj && selectedPlatformObj.salesBonus) {
bonusParts.push('Platform: +' + Math.round(selectedPlatformObj.salesBonus * 100) + '% satış');
}
// Genre bonus
if (projectMenu.selectedGenre) {
var genreObj = null;
for (var i = 0; i < gameGenres.length; i++) {
if (gameGenres[i].name === projectMenu.selectedGenre.name) {
genreObj = gameGenres[i];
break;
}
}
if (genreObj && genreObj.baseMultiplier && genreObj.baseMultiplier > 1) {
bonusParts.push('Tür: +' + Math.round((genreObj.baseMultiplier - 1) * 100) + '% satış');
}
}
// Feature trend bonus
var trendTypes = [];
if (gameState.marketTrends && Array.isArray(gameState.marketTrends)) {
for (var i = 0; i < gameState.marketTrends.length; i++) {
if (gameState.marketTrends[i] === "Graphics" || gameState.marketTrends[i] === "Sound" || gameState.marketTrends[i] === "Gameplay") {
trendTypes.push(gameState.marketTrends[i]);
}
}
}
var trendBonus = 0;
if (trendTypes.length > 0 && selectedFeatures && selectedFeatures.length > 0) {
for (var i = 0; i < selectedFeatures.length; i++) {
if (trendTypes.indexOf(selectedFeatures[i].type) !== -1) {
trendBonus = 50;
break;
}
}
if (trendBonus > 0) {
bonusParts.push('Trend Özellik: +50% satış');
}
}
// Genre trend bonus
if (projectMenu.selectedGenre && gameState.marketTrends && Array.isArray(gameState.marketTrends)) {
for (var i = 0; i < gameState.marketTrends.length; i++) {
if (typeof gameState.marketTrends[i] === "string" && gameState.marketTrends[i].indexOf(projectMenu.selectedGenre.name) !== -1) {
bonusParts.push('Trend Tür: +30% satış');
break;
}
}
}
// Fan bonus (platform-specific)
var fanBonus = 0;
var selectedPlatformObj = null;
if (gameState.selectedPlatform) {
for (var pi = 0; pi < platforms.length; pi++) {
if (platforms[pi].name === gameState.selectedPlatform) {
selectedPlatformObj = platforms[pi];
break;
}
}
}
if (gameState.fans && gameState.fans > 0) {
fanBonus = Math.floor(gameState.fans / 10) / 10;
if (fanBonus > 100) fanBonus = 100;
if (fanBonus > 0) {
if (selectedPlatformObj && typeof selectedPlatformObj.salesBonus === "number") {
var platformFanBonus = Math.round(fanBonus * selectedPlatformObj.salesBonus);
bonusParts.push('Fan: +' + platformFanBonus + '% satış (platforma göre)');
} else {
bonusParts.push('Fan: +' + fanBonus + '% satış');
}
}
}
if (bonusParts.length > 0) {
featureBonusSummary = 'Satış Bonusları: ' + bonusParts.join(', ');
} else {
featureBonusSummary = 'Satış bonusu yok.';
}
})();
var featureBonusText = new Text2(featureBonusSummary, {
size: 32,
fill: 0x4CAF50
});
featureBonusText.anchor.set(0.5, 0.5);
featureBonusText.x = 1024;
featureBonusText.y = 360;
projectMenu.addChild(featureBonusText);
projectMenu.featureBonusText = featureBonusText;
};
}(plat.name);
container.addChild(selectBtn);
} else {
// Not owned, show as locked
var lockedText = new Text2('Satın Al: $' + plat.price, {
size: 28,
fill: 0x888888
});
lockedText.anchor.set(0.5, 0.5);
lockedText.y = 100;
container.addChild(lockedText);
}
platformMenu.addChild(container);
}
updatePlatformMenuScrollBounds && updatePlatformMenuScrollBounds();
// Patch platformBackBtn to return to projectMenu if in selection mode
platformBackBtn.onClick = function () {
platformMenu.visible = false;
if (platformMenu._selectForProjectMenu) {
projectMenu.visible = true;
platformMenu._selectForProjectMenu = false;
} else {
mainMenu.visible = true;
}
};
updateGlobalBackBtn && updateGlobalBackBtn();
};
projectMenu.addChild(platformBtn);
projectMenu.platformBtn = platformBtn;
} else {
// We'll set the y position after all other buttons are placed
}
// Create all project menu buttons in a single vertical column, one per row
var buttonY = 650 + 240; // Move all buttons 2 rows (240px) down
var buttonSpacing = 120;
// Feature category buttons
var categories = ['Graphics', 'Sound', 'Gameplay'];
categories.forEach(function (category, index) {
var categoryBtn = new Button();
categoryBtn.setLabel(category + ' Features');
categoryBtn.x = 1024;
categoryBtn.y = buttonY;
categoryBtn.onClick = function () {
showFeatureCategory(category);
};
projectMenu.addChild(categoryBtn);
buttonY += buttonSpacing;
});
// Oyun Fiyatı button (move to next row)
if (projectMenu.priceBtn) {
// If not already present, re-add to projectMenu
if (projectMenu.children.indexOf(projectMenu.priceBtn) === -1) {
projectMenu.addChild(projectMenu.priceBtn);
}
projectMenu.priceBtn.y = buttonY;
buttonY += buttonSpacing;
}
// Game Genres Research button (move to next row)
if (!projectMenu.gameGenresResearchBtn) {
var gameGenresResearchBtn = new Button();
gameGenresResearchBtn.setLabel('Game Genres Research');
gameGenresResearchBtn.x = 1024;
gameGenresResearchBtn.y = buttonY;
gameGenresResearchBtn.onClick = function () {
showProjectGenresResearchMenu();
};
projectMenu.addChild(gameGenresResearchBtn);
projectMenu.gameGenresResearchBtn = gameGenresResearchBtn;
} else {
// If not already present, re-add to projectMenu
if (projectMenu.children.indexOf(projectMenu.gameGenresResearchBtn) === -1) {
projectMenu.addChild(projectMenu.gameGenresResearchBtn);
}
projectMenu.gameGenresResearchBtn.y = buttonY;
}
// Move Platform Seç button to be below the last button
if (projectMenu.platformBtn) {
projectMenu.platformBtn.y = buttonY + buttonSpacing;
buttonY = projectMenu.platformBtn.y;
}
// Add Oyun Adı Seç button below Platform Seç
if (!projectMenu.nameGameBtn) {
var nameGameBtn = new Button();
nameGameBtn.setLabel('Oyun Adı Seç');
nameGameBtn.x = 1024;
nameGameBtn.y = buttonY + buttonSpacing;
nameGameBtn.onClick = function () {
mainMenu.visible = false;
projectMenu.visible = false;
nameGameMenu.visible = true;
currentGameName = '';
gameNameInput.setText('');
};
projectMenu.addChild(nameGameBtn);
projectMenu.nameGameBtn = nameGameBtn;
} else {
// If not already present, re-add to projectMenu
if (projectMenu.children.indexOf(projectMenu.nameGameBtn) === -1) {
projectMenu.addChild(projectMenu.nameGameBtn);
}
projectMenu.nameGameBtn.y = buttonY + buttonSpacing;
}
buttonY = projectMenu.nameGameBtn.y;
// Add info text at the bottom of the platform selection page in Start Project
if (projectMenu.platformInfoText) {
projectMenu.platformInfoText.destroy();
}
var projectPlatformInfoText = new Text2('To use a platform, purchase it from the platform page in the main menu.', {
size: 32,
fill: 0xFFC107
});
projectPlatformInfoText.anchor.set(0.5, 0.5);
projectPlatformInfoText.x = 1024;
projectPlatformInfoText.y = 2500;
projectMenu.addChild(projectPlatformInfoText);
projectMenu.platformInfoText = projectPlatformInfoText;
}
function startDevelopment() {
// Must have at least one feature per category
if (!selectedFeatureByCategory.Graphics || !selectedFeatureByCategory.Sound || !selectedFeatureByCategory.Gameplay) {
// Show a notification or feedback
var notification = new Container();
game.addChild(notification);
var bg = LK.getAsset('card', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2,
scaleY: 0.6
});
bg.tint = 0xE94560;
notification.addChild(bg);
var text = new Text2('Her kategoriden en az 1 özellik seçmelisin!', {
size: 35,
fill: 0xFFFFFF
});
text.anchor.set(0.5, 0.5);
notification.addChild(text);
notification.x = 1024;
notification.y = 600;
notification.alpha = 0;
tween(notification, {
alpha: 1
}, {
duration: 500,
onFinish: function onFinish() {
LK.setTimeout(function () {
tween(notification, {
alpha: 0
}, {
duration: 500,
onFinish: function onFinish() {
notification.destroy();
}
});
}, 2000);
}
});
return;
}
// --- Require a researched genre to be selected before starting development ---
var researchedGenres = gameState.researchedFeatures.GameGenres;
// Fix: Check if selectedGenre is not null and its name is in researchedGenres or does not require research
if (!projectMenu.selectedGenre ||
// Find the genre object in gameGenres
function () {
var genreObj = null;
for (var i = 0; i < gameGenres.length; i++) {
if (gameGenres[i].name === projectMenu.selectedGenre.name) {
genreObj = gameGenres[i];
break;
}
}
// If genreObj is not found, treat as not researched
if (!genreObj) return true;
// If genre does not require research, allow
if (!genreObj.requiresResearch) return false;
// If genre requires research, check if it's in researchedGenres
return researchedGenres.indexOf(genreObj.name) === -1;
}()) {
// Show a notification or feedback
var notification = new Container();
game.addChild(notification);
var bg = LK.getAsset('card', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2,
scaleY: 0.6
});
bg.tint = 0xE94560;
notification.addChild(bg);
var text = new Text2('Please select a researched genre before starting!', {
size: 35,
fill: 0xFFFFFF
});
text.anchor.set(0.5, 0.5);
notification.addChild(text);
notification.x = 1024;
notification.y = 600;
notification.alpha = 0;
tween(notification, {
alpha: 1
}, {
duration: 500,
onFinish: function onFinish() {
LK.setTimeout(function () {
tween(notification, {
alpha: 0
}, {
duration: 500,
onFinish: function onFinish() {
notification.destroy();
}
});
}, 2000);
}
});
return;
}
// Calculate total cost
var totalCost = 0;
selectedFeatures.forEach(function (feature) {
totalCost += feature.cost;
});
// Check if player can afford
if (gameState.money < totalCost) {
return;
}
// Deduct costs
gameState.money -= totalCost;
updateUI();
projectMenu.visible = false;
developmentScreen.visible = true;
// (Game Engine UI removed from development screen)
// Display trends
for (var i = trendsContainer.children.length - 1; i > 0; i--) {
trendsContainer.children[i].destroy();
}
gameState.marketTrends.forEach(function (trend, index) {
var trendText = new Text2(trend + ' is trending!', {
size: 30,
fill: 0xFF5722
});
trendText.anchor.set(0.5, 0.5);
trendText.y = 40 + index * 35;
trendsContainer.addChild(trendText);
});
// Calculate target score
var baseTarget = 100;
targetScoreText.setText('Target Score: ' + baseTarget);
// Use selected genre from projectMenu
var selectedGenre = projectMenu.selectedGenre || null;
// Start project
gameState.currentProject = {
features: selectedFeatures,
targetScore: baseTarget,
currentScore: 0,
developmentSpeed: 0,
genre: selectedGenre,
price: typeof projectMenu.selectedPrice === "number" ? projectMenu.selectedPrice : 1
};
// Assign features to developers (main character is always included and can contribute to all features)
var assignedDevelopers = [];
var assignedFeatures = [];
// Always include main character as a developer
var allDevs = [{
name: gameState.mainCharacter.name,
specialty: "All",
skill: gameState.mainCharacter.skill,
featurePoints: Object.assign({}, gameState.mainCharacter.featurePoints)
}].concat(gameState.developers.map(function (dev) {
return {
name: dev.name,
specialty: dev.specialty,
skill: dev.skill,
assignedFeature: null
};
}));
// Assign features: each feature is assigned to a developer, but main character always contributes to all
var devAssignments = [];
selectedFeatures.forEach(function (feature, idx) {
// Assign to next available developer (skip main character for assignment, but main character always contributes)
var devIdx = (idx + 1) % allDevs.length;
if (devIdx === 0 && allDevs.length > 1) devIdx = 1; // avoid assigning all to main character
devAssignments.push({
dev: allDevs[devIdx],
feature: feature
});
allDevs[devIdx].assignedFeature = feature.name;
});
// Calculate development speed
var totalSpeed = 0;
// Main character always contributes to all features
selectedFeatures.forEach(function (feature) {
var fp = gameState.mainCharacter.featurePoints[feature.type] || 1;
totalSpeed += (gameState.mainCharacter.skill + fp) * 0.5;
});
// Other developers contribute to their assigned feature
devAssignments.forEach(function (assignment) {
if (assignment.dev.name !== gameState.mainCharacter.name) {
totalSpeed += assignment.dev.skill * 0.5;
}
});
gameState.currentProject.developmentSpeed = totalSpeed;
gameState.currentProject.devAssignments = devAssignments;
LK.getSound('develop').play();
releaseBtn.visible = false;
progressBarFill.scaleX = 0;
}
function releaseGame() {
var project = gameState.currentProject;
// Calculate final score with bonuses
var finalScore = project.currentScore;
// (Game Engine quality bonus removed)
// Trend bonus
var trendMultiplier = 1;
project.features.forEach(function (feature) {
if (gameState.marketTrends.indexOf(feature.type) !== -1) {
finalScore *= 1.5;
trendMultiplier += 0.3;
}
});
// Genre bonus
if (project.genre) {
finalScore *= project.genre.baseMultiplier;
if (gameState.marketTrends.some(function (trend) {
return trend.indexOf(project.genre.name) !== -1;
})) {
finalScore *= 1.3;
trendMultiplier += 0.4;
}
}
// Calculate initial sales potential
var baseSalesMultiplier = 20;
if (finalScore >= project.targetScore) {
baseSalesMultiplier = 40;
}
// Price effect on sales: higher price = lower sales, lower price = higher sales
var priceSalesMultiplier = 1;
if (project.price) {
if (project.price > 1) {
priceSalesMultiplier = 1 / (0.7 + (project.price - 1) * 0.5); // $2 = ~0.67x, $5 = ~0.29x
if (priceSalesMultiplier < 0.15) priceSalesMultiplier = 0.15;
} else if (project.price < 1) {
priceSalesMultiplier = 1 + (1 - project.price) * 0.7; // $0.5 = 1.35x
}
}
// --- Ava: Reduce sales multiplier if features and review score are low and price is high ---
var featureQuality = 0;
for (var i = 0; i < project.features.length; i++) {
featureQuality += project.features[i].basePoints || 0;
}
var avgFeatureQuality = featureQuality / project.features.length;
var reviewScoreForPenalty = 0;
var scoreRatio = finalScore / project.targetScore;
if (scoreRatio >= 1.5) reviewScoreForPenalty = 95;else if (scoreRatio >= 1.2) reviewScoreForPenalty = 85;else if (scoreRatio >= 1.0) reviewScoreForPenalty = 75;else if (scoreRatio >= 0.8) reviewScoreForPenalty = 60;else reviewScoreForPenalty = 40;
// If price is high, but features and review are low, apply a penalty to sales
var pricePenaltyMultiplier = 1;
if (project.price > 2) {
// If both feature quality and review are low, penalize more
if (avgFeatureQuality < 5 && reviewScoreForPenalty < 70) {
pricePenaltyMultiplier = 0.5 - Math.min((project.price - 2) * 0.1, 0.3); // up to -30% more penalty
} else if (avgFeatureQuality < 6 || reviewScoreForPenalty < 75) {
pricePenaltyMultiplier = 0.7 - Math.min((project.price - 2) * 0.05, 0.2); // up to -20% more penalty
}
// Never less than 0.2x
if (pricePenaltyMultiplier < 0.2) pricePenaltyMultiplier = 0.2;
}
// Find selected platform and apply its salesBonus
var selectedPlatform = null;
for (var i = 0; i < platforms.length; i++) {
if (platforms[i].name === gameState.selectedPlatform) {
selectedPlatform = platforms[i];
break;
}
}
var platformSalesBonus = selectedPlatform && selectedPlatform.salesBonus ? 1 + selectedPlatform.salesBonus : 1;
var initialDailySales = Math.floor(finalScore / project.targetScore * baseSalesMultiplier * trendMultiplier * priceSalesMultiplier * pricePenaltyMultiplier * platformSalesBonus);
var gameName = currentGameName && currentGameName.length > 0 ? currentGameName : 'Game #' + (gameState.completedGames + 1);
// --- Review and score system ---
// Ava: Reviewers are now much more pessimistic!
// Only 5 reviewers, each with unique focus: feature, price, platform, etc.
var reviewCompanies = ["IGN", "GameSpot", "Polygon", "Eurogamer", "Kotaku"];
var reviews = [];
var reviewScore = 0;
var genreTrend = gameState.marketTrends.find(function (trend) {
return project.genre && trend.indexOf(project.genre.name) !== -1;
});
var featureTrend = gameState.marketTrends.indexOf(project.features[0].type) !== -1 || gameState.marketTrends.indexOf(project.features[1].type) !== -1 || gameState.marketTrends.indexOf(project.features[2].type) !== -1 || project.features.length > 3 && gameState.marketTrends.indexOf(project.features[3].type) !== -1 || project.features.length > 4 && gameState.marketTrends.indexOf(project.features[4].type) !== -1;
// Calculate review score (0-100) -- pessimistic version
var scoreRatio = finalScore / project.targetScore;
if (scoreRatio >= 1.5) reviewScore = 80 + Math.floor(Math.random() * 6); // was 95+
else if (scoreRatio >= 1.2) reviewScore = 65 + Math.floor(Math.random() * 10); // was 85+
else if (scoreRatio >= 1.0) reviewScore = 55 + Math.floor(Math.random() * 10); // was 75+
else if (scoreRatio >= 0.8) reviewScore = 40 + Math.floor(Math.random() * 10); // was 60+
else reviewScore = 20 + Math.floor(Math.random() * 20); // was 40+
// If genre matches trend, boost score (less than before)
if (genreTrend) reviewScore += 2;
if (featureTrend) reviewScore += 2;
// --- Price effect on review score ---
if (project.price) {
// $1 is neutral, higher price reduces review, lower price increases (harsher penalty)
if (project.price > 1) {
reviewScore -= Math.floor((project.price - 1) * 7); // -7 puan/extra dollar
} else if (project.price < 1) {
reviewScore += Math.floor((1 - project.price) * 3); // +3 puan/discounted dollar
}
}
if (reviewScore > 100) reviewScore = 100;
if (reviewScore < 0) reviewScore = 0;
// --- 5 unique reviews: each with a different focus ---
// 1. Feature focus
var feature = project.features[0];
var featureScore = reviewScore + Math.floor(Math.random() * 5 - 2);
if (featureScore > 100) featureScore = 100;
if (featureScore < 0) featureScore = 0;
var featureText = "";
if (featureScore >= 80) {
featureText = "The standout feature is '" + feature.name + "'. It really elevates the experience.";
} else if (featureScore >= 60) {
featureText = "'" + feature.name + "' is decent, but could use more polish.";
} else {
featureText = "The '" + feature.name + "' feature is a major letdown.";
}
reviews.push({
company: reviewCompanies[0],
score: featureScore,
text: featureText
});
// 2. Price focus
var priceScore = reviewScore + Math.floor(Math.random() * 5 - 2);
if (priceScore > 100) priceScore = 100;
if (priceScore < 0) priceScore = 0;
var priceText = "";
if (project.price > 3) {
priceText = "At $" + project.price + ", the game feels overpriced for what it offers.";
} else if (project.price < 1) {
priceText = "Great value for money! The low price makes this game more appealing.";
} else {
priceText = "The price is fair for the content provided.";
}
reviews.push({
company: reviewCompanies[1],
score: priceScore,
text: priceText
});
// 3. Platform compatibility focus
var platformName = gameState.selectedPlatform || "PC";
var platformScore = reviewScore + Math.floor(Math.random() * 5 - 2);
if (platformScore > 100) platformScore = 100;
if (platformScore < 0) platformScore = 0;
var platformText = "";
if (platformName === "PC") {
platformText = "Runs smoothly on PC, but we'd love to see more platform options.";
} else {
platformText = "Great to see support for " + platformName + ".";
}
reviews.push({
company: reviewCompanies[2],
score: platformScore,
text: platformText
});
// 4. Trend/genre focus
var trendScore = reviewScore + Math.floor(Math.random() * 5 - 2);
if (trendScore > 100) trendScore = 100;
if (trendScore < 0) trendScore = 0;
var trendText = "";
if (genreTrend) {
trendText = "Smart move to follow the '" + project.genre.name + "' trend. It pays off!";
} else if (featureTrend) {
trendText = "The game tries to follow current feature trends, but doesn't quite hit the mark.";
} else {
trendText = "Misses out on current market trends, making it feel a bit outdated.";
}
reviews.push({
company: reviewCompanies[3],
score: trendScore,
text: trendText
});
// 5. General polish/compatibility focus
var polishScore = reviewScore + Math.floor(Math.random() * 5 - 2);
if (polishScore > 100) polishScore = 100;
if (polishScore < 0) polishScore = 0;
var polishText = "";
if (polishScore >= 80) {
polishText = "A well-polished game with few bugs. Impressive work!";
} else if (polishScore >= 60) {
polishText = "Some rough edges, but overall a stable experience.";
} else {
polishText = "Technical issues and lack of polish hold this game back.";
}
reviews.push({
company: reviewCompanies[4],
score: polishScore,
text: polishText
});
var releasedGame = {
name: gameName,
releaseDay: gameState.currentDay,
score: finalScore,
targetScore: project.targetScore,
initialDailySales: initialDailySales,
currentDailySales: initialDailySales,
totalSales: 0,
features: project.features,
trendBonus: trendMultiplier,
price: project.price || 1,
// Add main character as a developer in the released game
developers: [{
name: gameState.mainCharacter.name,
specialty: "All",
skill: gameState.mainCharacter.skill
}].concat(gameState.developers.slice()),
genre: project.genre,
reviews: reviews,
reviewScore: reviewScore
};
// Reset game name after use
currentGameName = '';
gameNameDisplay.setText('');
// Clear marketTrends so new trends are generated for the next project
gameState.marketTrends = [];
gameState.releasedGames.push(releasedGame);
// Success check
if (finalScore >= project.targetScore) {
gameState.money += Math.floor(finalScore * 0.00025); // 95% less
gameState.completedGames++;
LK.getSound('success').play();
LK.setScore(gameState.completedGames);
if (gameState.completedGames >= 10) {
LK.showYouWin();
}
} else {
gameState.money += Math.floor(finalScore * 0.0000625); // 95% less
}
LK.getSound('release').play();
// Reset
gameState.currentProject = null;
developmentScreen.visible = false;
mainMenu.visible = true;
updateUI();
updateSalesLog();
// --- Rakiplerden biri de oyun çıkarsın (oyuncu oyun çıkardığında) ---
if (gameState.rivals && gameState.rivals.length > 0) {
// Rastgele bir rakip seç
var rivalIndex = Math.floor(Math.random() * gameState.rivals.length);
var rival = gameState.rivals[rivalIndex];
// Oyun ismi ve gelirini üret
var gameNames = ["Super", "Mega", "Ultra", "Epic", "Legend", "Pixel", "Quest", "Saga", "Chronicles", "World"];
var gameSuffix = ["Adventure", "Battle", "Story", "Kingdom", "Odyssey", "Arena", "Tycoon", "Empire", "Run", "Hero"];
var name = gameNames[Math.floor(Math.random() * gameNames.length)] + " " + gameSuffix[Math.floor(Math.random() * gameSuffix.length)];
// Son 3 oyunun ortalamasını bul
var last3 = rival.games && rival.games.length > 0 ? rival.games.slice(-3) : [];
var avg = 40000;
if (last3.length > 0) {
var sum = 0;
for (var i = 0; i < last3.length; i++) sum += last3[i].revenue;
avg = Math.floor(sum / last3.length);
}
// Rakip oyun kazancı, rakip şirket değerinin %1-%20 aralığında kâr veya %1-%20 aralığında zarar olacak şekilde ayarlandı
var percent = (Math.random() < 0.5 ? -1 : 1) * (0.01 + Math.random() * 0.19); // -0.01 ile -0.20 veya +0.01 ile +0.20 arası
var baseValue = rival.value || 100000;
var revenue = Math.floor(baseValue * Math.abs(percent));
var originalRevenue = revenue;
if (percent < 0) {
revenue = -revenue;
}
var originalLoss = 0;
if (revenue < 0) {
originalLoss = -revenue;
revenue = 0;
}
// Oyun objesi
var rivalGame = {
name: name,
releaseDay: gameState.currentDay,
revenue: revenue,
_originalRevenue: percent < 0 ? -originalRevenue : originalRevenue,
_originalLoss: originalLoss
};
rival.games.push(rivalGame);
// Sadece son 3 oyunu tut
if (rival.games.length > 3) rival.games = rival.games.slice(-3);
// Firma değerini anlık olarak kâr/zarara göre değiştir: kâr ise artır, zarar ise azalt
if (revenue > 0) {
rival.value += revenue + Math.floor(revenue * 0.1);
} else if (originalLoss > 0) {
rival.value -= originalLoss;
}
// Firma değeri 0'ın altına düşmesin
if (rival.value < 0) rival.value = 0;
// Son 3 oyunun ortalamasını güncelle
var sum2 = 0;
for (var i = 0; i < rival.games.length; i++) sum2 += rival.games[i].revenue;
rival.avgRevenue = Math.floor(sum2 / rival.games.length);
}
}
// Game update
var dayTimer = 0;
game.update = function () {
// Handle research progress
if (gameState.currentResearch) {
gameState.currentResearch.timeRemaining--;
if (gameState.currentResearch.timeRemaining <= 0) {
// Research complete
var research = gameState.currentResearch;
if (research.category === 'Platforms') {
// Mark platform as researched
if (gameState.platforms && gameState.platforms[research.name]) {
gameState.platforms[research.name].researched = true;
}
} else if (research.category === 'IncreaseLimit_Graphics' || research.category === 'IncreaseLimit_Sound' || research.category === 'IncreaseLimit_Gameplay') {
// Increase the selection limit for the relevant category
var cat = research.category.replace('IncreaseLimit_', '');
if (!gameState.featureSelectionLimit) gameState.featureSelectionLimit = {};
if (typeof gameState.featureSelectionLimit[cat] !== "number") gameState.featureSelectionLimit[cat] = 1;
gameState.featureSelectionLimit[cat]++;
} else {
gameState.researchedFeatures[research.category].push(research.name);
}
gameState.currentResearch = null;
LK.getSound('success').play();
// Show notification
var notification = new Container();
game.addChild(notification);
var bg = LK.getAsset('card', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2,
scaleY: 0.8
});
bg.tint = 0x4CAF50;
notification.addChild(bg);
var text = new Text2('Research Complete: ' + research.name, {
size: 35,
fill: 0xFFFFFF
});
text.anchor.set(0.5, 0.5);
notification.addChild(text);
notification.x = 1024;
notification.y = 600;
notification.alpha = 0;
tween(notification, {
alpha: 1
}, {
duration: 500,
onFinish: function onFinish() {
LK.setTimeout(function () {
tween(notification, {
alpha: 0
}, {
duration: 500,
onFinish: function onFinish() {
notification.destroy();
}
});
}, 2000);
}
});
}
}
// Day progression (every 3 seconds = 1 day)
dayTimer++;
if (dayTimer >= 180) {
// 60 fps * 3 seconds
dayTimer = 0;
gameState.currentDay++;
// --- Bank: Process credit and deposit on day change ---
// Credit: No daily penalty, payment handled at normal interest (see showBankMenu)
// Deposit: If matured, do NOT auto-renew. Wait for user to withdraw. (Faiz zamanı tamamlanınca dursun, çek butonu görüntülensin)
// No action needed here; handled in showBankMenu withdrawBtn
// Kredi vadesi dolunca faiz eklenmesin, borç vadesi dolunca beklesin (hiçbir işlem yapılmaz)
updateUI();
// Fan Store günlük satış sistemi: Her gün başında çalıştır
processFanStoreDailySale();
// Process game sales
for (var i = gameState.releasedGames.length - 1; i >= 0; i--) {
var releasedGame = gameState.releasedGames[i];
var daysSinceRelease = gameState.currentDay - releasedGame.releaseDay;
// Calculate sales decline
var declineRate = 0.75; // Base 25% daily decline
// Better games decline slower
if (releasedGame.score >= releasedGame.targetScore * 1.5) {
declineRate = 0.85;
} else if (releasedGame.score >= releasedGame.targetScore) {
declineRate = 0.80;
}
// Apply trend bonus to decline rate
declineRate += (releasedGame.trendBonus - 1) * 0.03;
declineRate = Math.min(declineRate, 0.90);
// Calculate review score multiplier (0.3x for <60, 1x for 60-74, 1.7x for 75-89, 2.5x for 90+)
// Ava: Review scores now have a much stronger effect on sales!
var reviewMultiplier = 1;
if (releasedGame.reviewScore !== undefined) {
if (releasedGame.reviewScore >= 90) reviewMultiplier = 2.5;else if (releasedGame.reviewScore >= 75) reviewMultiplier = 1.7;else if (releasedGame.reviewScore >= 60) reviewMultiplier = 1;else reviewMultiplier = 0.3;
}
// Calculate fan sales bonus: proportional, e.g. 200 fan = %2, 1000 fan = %10, max 100%
// Platform-specific: always use the selected platform's salesBonus
var fanSalesBonus = 1;
var selectedPlatformObj = null;
if (gameState.selectedPlatform) {
for (var pi = 0; pi < platforms.length; pi++) {
if (platforms[pi].name === gameState.selectedPlatform) {
selectedPlatformObj = platforms[pi];
break;
}
}
}
if (gameState.fans && gameState.fans > 0) {
var bonusPercent = gameState.fans / 100000 * 100; // 100000 fan = %100 bonus
if (bonusPercent > 100) bonusPercent = 100;
// Always use platform's salesBonus if available
if (selectedPlatformObj && typeof selectedPlatformObj.salesBonus === "number") {
fanSalesBonus = 1 + bonusPercent * selectedPlatformObj.salesBonus / 100;
} else {
fanSalesBonus = 1 + bonusPercent / 100;
}
}
// Calculate current day sales
// Ava: +200% general sales boost, then reduce by 25% (multiply by 0.75)
// Satışları %35 artırmak için çarpanı 3.0*0.75 yerine 3.0*0.75*1.35 yapıyoruz
releasedGame.currentDailySales = Math.floor(releasedGame.initialDailySales * Math.pow(declineRate, daysSinceRelease) * reviewMultiplier * fanSalesBonus * 3.0 * 0.75 * 1.35);
// Add to total sales and money
if (releasedGame.currentDailySales > 0) {
releasedGame.totalSales += releasedGame.currentDailySales;
var pricePerCopy = releasedGame.price || 1;
var revenue = Math.floor(releasedGame.currentDailySales * pricePerCopy); // 100% of price per copy to player
gameState.money += revenue;
// --- Fan gain from sales: Her 10 kopya satışta 1-5 arası rastgele fan kazandır ---
if (!releasedGame._fanSalesRemainder) releasedGame._fanSalesRemainder = 0;
var totalSalesForFan = releasedGame.currentDailySales + releasedGame._fanSalesRemainder;
var fansGained = 0;
if (totalSalesForFan >= 10) {
var fanAwardCount = Math.floor(totalSalesForFan / 10);
for (var f = 0; f < fanAwardCount; f++) {
fansGained += 1 + Math.floor(Math.random() * 2); // 1-2 arası rastgele
}
releasedGame._fanSalesRemainder = totalSalesForFan % 10;
} else {
releasedGame._fanSalesRemainder = totalSalesForFan;
}
if (!gameState.fans) gameState.fans = 0;
gameState.fans += fansGained;
// --- Eski random fanGainPercent sistemini kaldır ---
// (Kaldırıldı)
} else {
// Game no longer selling - remove from market
var removedGame = gameState.releasedGames.splice(i, 1)[0];
gameState.gameHistory.push(removedGame);
// Show notification
var notification = new Container();
game.addChild(notification);
var bg = LK.getAsset('card', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2,
scaleY: 1.2
});
bg.tint = 0x0f3460;
notification.addChild(bg);
var titleText = new Text2(removedGame.name + ' removed from market', {
size: 35,
fill: 0xFFFFFF
});
titleText.anchor.set(0.5, 0.5);
titleText.y = -30;
notification.addChild(titleText);
var salesText = new Text2('Total copies sold: ' + removedGame.totalSales, {
size: 30,
fill: 0x4CAF50
});
salesText.anchor.set(0.5, 0.5);
salesText.y = 20;
notification.addChild(salesText);
notification.x = 1024;
notification.y = 1366;
notification.alpha = 0;
// Animate notification
tween(notification, {
alpha: 1,
y: 1000
}, {
duration: 500,
onFinish: function onFinish() {
LK.setTimeout(function () {
tween(notification, {
alpha: 0
}, {
duration: 500,
onFinish: function onFinish() {
notification.destroy();
}
});
}, 2000);
}
});
}
}
updateUI();
updateSalesLog();
}
if (gameState.currentProject && developmentScreen.visible) {
var project = gameState.currentProject;
// Development progress
if (project.currentScore < project.targetScore) {
// --- Ava: Make score gain speed depend on studio level and total developer skill ---
// Calculate base points per tick
var pointsPerTick = project.developmentSpeed / 30;
// Calculate total skill of all developers (including main character)
var totalDevSkill = gameState.mainCharacter.skill;
for (var i = 0; i < gameState.developers.length; i++) {
totalDevSkill += gameState.developers[i].skill;
}
// Studio level bonus: higher level = faster progress
var studioLevelBonus = 1 + (gameState.studioLevel - 1) * 0.15; // +15% per studio level above 1
// Skill bonus: more total skill = faster progress, but with diminishing returns
var skillBonus = 0.5 + Math.log(1 + totalDevSkill) * 0.5; // log curve, min 0.5x
// Feature synergy bonus (as before)
var synergy = 1;
if (gameState.mainCharacter.featurePoints) {
project.features.forEach(function (feature) {
if (gameState.mainCharacter.featurePoints[feature.type] && gameState.mainCharacter.featurePoints[feature.type] > 0) {
synergy += 0.1;
}
});
}
project.features.forEach(function (feature) {
gameState.developers.forEach(function (dev) {
if (dev.specialty === feature.type) {
synergy += 0.1;
}
});
});
// Final points per tick: base * studioLevelBonus * skillBonus * synergy
var finalPointsPerTick = pointsPerTick * studioLevelBonus * skillBonus * synergy;
// Clamp minimum progress to avoid being stuck at 0
if (finalPointsPerTick < 0.01) finalPointsPerTick = 0.01;
project.currentScore += finalPointsPerTick;
// Update UI
currentScoreText.setText('Current Score: ' + Math.floor(project.currentScore));
var progress = Math.min(project.currentScore / project.targetScore, 1);
progressBarFill.scaleX = progress;
// Show release button when ready
if (progress >= 1 && !releaseBtn.visible) {
releaseBtn.visible = true;
tween(releaseBtn, {
scaleX: 1.1,
scaleY: 1.1
}, {
duration: 500,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(releaseBtn, {
scaleX: 1,
scaleY: 1
}, {
duration: 500
});
}
});
}
}
}
// Check game over
if (gameState.money < 100 && gameState.developers.length === 0 && !gameState.currentProject) {
LK.showGameOver();
}
};
// Global Back Button (bottom)
var globalBackBtn = new Button();
globalBackBtn.setLabel('Geri');
// Place at bottom center, matching other menu button size (400x100)
globalBackBtn.x = 1024;
globalBackBtn.y = 2600;
globalBackBtn.visible = false;
LK.gui.bottom.addChild(globalBackBtn);
// --- Reset Game Button (bottom left) ---
var resetGameBtn = new Button();
resetGameBtn.setLabel('Reset Game');
resetGameBtn.x = 220; // 200px from left, avoid top left menu area
resetGameBtn.y = 2600; // bottom, same as globalBackBtn
resetGameBtn.scaleX = 1;
resetGameBtn.scaleY = 1;
resetGameBtn.onClick = function () {
LK.showGameOver(); // This will reset the game state and show the game over popup
};
LK.gui.bottomLeft.addChild(resetGameBtn);
// Global Back Button (top)
var globalBackBtnTop = new Button();
globalBackBtnTop.setLabel('Geri');
globalBackBtnTop.x = 1024;
globalBackBtnTop.y = 100;
globalBackBtnTop.visible = false;
LK.gui.top.addChild(globalBackBtnTop);
// --- Reset Game Button (bottom left) ---
var resetGameBtn = new Button();
resetGameBtn.setLabel('Reset Game');
resetGameBtn.x = 220; // 200px from left, avoid top left menu area
resetGameBtn.y = 2600; // bottom, same as globalBackBtn
resetGameBtn.scaleX = 1;
resetGameBtn.scaleY = 1;
resetGameBtn.onClick = function () {
LK.showGameOver(); // This will reset the game state and show the game over popup
};
LK.gui.bottomLeft.addChild(resetGameBtn);
// Helper to check if any menu except mainMenu is visible
function isAnyMenuOpen() {
return upgradeMenu.visible || researchMenu.visible || researchCategoryMenu.visible || nameGameMenu.visible || allGamesMenu.visible || gameDetailView.visible || hireMenu.visible || projectMenu.visible || featureCategoryMenu.visible || developmentScreen.visible;
}
// Helper to close the topmost open menu and return to mainMenu
function closeCurrentMenu() {
if (upgradeMenu.visible) {
upgradeMenu.visible = false;
mainMenu.visible = true;
} else if (researchCategoryMenu.visible) {
researchCategoryMenu.visible = false;
researchMenu.visible = true;
} else if (researchMenu.visible) {
researchMenu.visible = false;
mainMenu.visible = true;
} else if (nameGameMenu.visible) {
nameGameMenu.visible = false;
mainMenu.visible = true;
gameNameInput.setText('');
currentGameName = '';
} else if (allGamesMenu.visible) {
allGamesMenu.visible = false;
mainMenu.visible = true;
} else if (gameDetailView.visible) {
gameDetailView.visible = false;
allGamesMenu.visible = true;
} else if (hireMenu.visible) {
hireMenu.visible = false;
mainMenu.visible = true;
} else if (featureCategoryMenu.visible) {
featureCategoryMenu.visible = false;
projectMenu.visible = true;
// Update total cost in project menu
var totalCost = 0;
selectedFeatures.forEach(function (f) {
totalCost += f.cost;
});
if (projectMenu.totalCostText) {
projectMenu.totalCostText.setText('Total Cost: $' + totalCost);
}
} else if (projectMenu.visible) {
projectMenu.visible = false;
mainMenu.visible = true;
selectedFeatures = [];
featureCards.forEach(function (card) {
card.setSelected(false);
});
// Restore persistent buttons if missing (for next open)
if (projectMenu.priceBtn && projectMenu.children.indexOf(projectMenu.priceBtn) === -1) {
projectMenu.addChild(projectMenu.priceBtn);
}
if (projectMenu.platformBtn && projectMenu.children.indexOf(projectMenu.platformBtn) === -1) {
projectMenu.addChild(projectMenu.platformBtn);
}
if (projectMenu.gameGenresResearchBtn && projectMenu.children.indexOf(projectMenu.gameGenresResearchBtn) === -1) {
projectMenu.addChild(projectMenu.gameGenresResearchBtn);
}
} else if (developmentScreen.visible) {
developmentScreen.visible = false;
mainMenu.visible = true;
}
}
// Attach handler to global back button
globalBackBtn.onClick = function () {
closeCurrentMenu();
};
globalBackBtnTop.onClick = function () {
closeCurrentMenu();
};
// Show/hide global back button depending on menu state
function updateGlobalBackBtn() {
// Show if any menu except mainMenu is visible
var show = isAnyMenuOpen() && !mainMenu.visible;
globalBackBtn.visible = show;
globalBackBtnTop.visible = show;
}
// Patch all menu show functions to update global back button
var _showUpgradeMenu = showUpgradeMenu;
showUpgradeMenu = function showUpgradeMenu() {
_showUpgradeMenu();
updateGlobalBackBtn();
};
var _showPlatformMenu = showPlatformMenu;
showPlatformMenu = function showPlatformMenu() {
_showPlatformMenu();
updateGlobalBackBtn();
};
var _showResearchMenu = showResearchMenu;
showResearchMenu = function showResearchMenu() {
_showResearchMenu();
updateGlobalBackBtn();
};
var _showAllGamesMenu = showAllGamesMenu;
showAllGamesMenu = function showAllGamesMenu() {
_showAllGamesMenu();
updateGlobalBackBtn();
};
var _showHireMenu = showHireMenu;
showHireMenu = function showHireMenu() {
_showHireMenu();
updateGlobalBackBtn();
};
var _showProjectMenu = showProjectMenu;
showProjectMenu = function showProjectMenu() {
_showProjectMenu();
updateGlobalBackBtn();
};
var _showFeatureCategory = showFeatureCategory;
showFeatureCategory = function showFeatureCategory(category) {
_showFeatureCategory(category);
updateGlobalBackBtn();
};
var _showResearchCategory = showResearchCategory;
showResearchCategory = function showResearchCategory(category) {
_showResearchCategory(category);
updateGlobalBackBtn();
};
var _showNameGameMenu = showNameGameMenu;
showNameGameMenu = function showNameGameMenu() {
_showNameGameMenu();
updateGlobalBackBtn();
};
var _showGameDetail = showGameDetail;
showGameDetail = function showGameDetail(gameData) {
_showGameDetail(gameData);
updateGlobalBackBtn();
};
// Patch all menu back/close buttons to update global back button
function patchBackBtn(btn, closeFn) {
var old = btn.onClick;
btn.onClick = function () {
if (old) old();
updateGlobalBackBtn();
};
}
patchBackBtn(backFromUpgradeBtn);
patchBackBtn(researchBackBtn);
patchBackBtn(categoryBackBtn);
patchBackBtn(backFromNameBtn);
patchBackBtn(backFromAllGamesBtn);
patchBackBtn(detailBackBtn);
patchBackBtn(backFromHireBtn);
patchBackBtn(backFromProjectBtn);
patchBackBtn(categoryBackBtn);
patchBackBtn(researchBackBtn);
patchBackBtn(categoryBackBtn);
// Also update on developmentScreen close (release)
var _releaseGame = releaseGame;
releaseGame = function releaseGame() {
_releaseGame();
updateGlobalBackBtn();
};
// Also update on game update (in case of state changes)
var _updateUI = updateUI;
updateUI = function updateUI() {
_updateUI();
updateGlobalBackBtn();
};
// Initialize
updateUI();
updateGlobalBackBtn();