/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var storage = LK.import("@upit/storage.v1", { money: 0, businesses: {}, lastTick: 0 }); /**** * Classes ****/ // Business class: represents a single business row var Business = Container.expand(function () { var self = Container.call(this); // Properties (set after creation) self.bizId = null; self.bizData = null; self.index = 0; // UI elements var icon = null; var nameTxt = null; var levelTxt = null; var costTxt = null; var profitTxt = null; var timerBar = null; var upgradeBtn = null; var managerBtn = null; // State self.timer = 0; // ms left for current run self.running = false; // Setup method (called after creation) self.setup = function (bizId, bizData, index) { self.bizId = bizId; self.bizData = bizData; self.index = index; // Icon icon = self.attachAsset(bizData.asset, { anchorX: 0.5, anchorY: 0.5, x: 0, y: 0 }); // Name nameTxt = new Text2(bizData.name, { size: 48, fill: "#222", font: "'GillSans-Bold', Impact, 'Arial Black', Tahoma" }); nameTxt.anchor.set(0, 0.5); nameTxt.x = 140; nameTxt.y = 0; self.addChild(nameTxt); // Level levelTxt = new Text2("Lvl 0", { size: 40, fill: "#444", font: "'GillSans-Bold', Impact, 'Arial Black', Tahoma" }); levelTxt.anchor.set(0, 0.5); levelTxt.x = 140; levelTxt.y = 50; self.addChild(levelTxt); // Cost costTxt = new Text2("Buy: $0", { size: 36, fill: "#666", font: "'GillSans-Bold', Impact, 'Arial Black', Tahoma" }); costTxt.anchor.set(0, 0.5); costTxt.x = 140; costTxt.y = -50; self.addChild(costTxt); // Profit profitTxt = new Text2("+$0", { size: 48, fill: 0x008000, font: "'GillSans-Bold', Impact, 'Arial Black', Tahoma" }); profitTxt.anchor.set(1, 0.5); profitTxt.x = 900; profitTxt.y = 0; self.addChild(profitTxt); // Timer bar background (shows total progress area) var timerBarBg = self.attachAsset('slider_sprite', { anchorX: 0, anchorY: 0.5, x: 140, y: 80, width: 320, height: 24, // match new thinner asset height for best appearance tint: 0x000000 // transparent black }); timerBarBg.alpha = 0.5; self.addChild(timerBarBg); // Timer bar (progress fill) timerBar = self.attachAsset('slider_sprite', { anchorX: 0, anchorY: 0.5, x: 140, y: 80, width: 0, height: 24 // match new thinner asset height for best appearance }); timerBar.alpha = 0.5; // Upgrade button upgradeBtn = self.attachAsset('upgrade_btn', { anchorX: 0.5, anchorY: 0.5, x: 1100, y: 0 }); upgradeBtn.interactive = true; upgradeBtn.down = function (x, y, obj) { if (self.down) self.down(x, y, upgradeBtn); }; // Removed upgradeTxt label // (Auto/manager button removed) // Event listeners self.down = function (x, y, obj) { // If tap on icon, start business if unlocked if (self.isUnlocked() && !self.isAuto() && self.timer <= 0) { self.startRun(); } // If tap on upgrade button if (self.isUnlocked() && obj === upgradeBtn && upgradeBtn.alpha >= 1) { self.tryUpgrade(); } // (Auto/manager button tap logic removed) // If tap anywhere on the business row and not unlocked, allow buying if (!self.isUnlocked()) { self.tryUpgrade(); } }; // Update UI self.refresh(); }; // Is business unlocked? self.isUnlocked = function () { return businesses[self.bizId].level > 0; }; // Is manager hired? self.isAuto = function () { return businesses[self.bizId].manager; }; // Start a run (manual or auto) self.startRun = function () { if (!self.isUnlocked()) return; if (self.timer > 0) return; self.timer = self.getDuration(); self.running = true; }; // Try to buy/upgrade self.tryUpgrade = function () { // Calculate how many upgrades we can afford with the current multiplier var maxUpgrades = typeof upgradeMultiplier !== "undefined" ? upgradeMultiplier : 1; var bought = 0; for (var i = 0; i < maxUpgrades; ++i) { var cost = self.getCost(); if (money >= cost && upgradeBtn.alpha >= 1) { money -= cost; businesses[self.bizId].level += 1; bought++; } else { break; } } if (bought > 0) { self.refresh(); updateMoneyUI(); saveGame(); } }; // Try to hire manager self.tryHireManager = function () { var mCost = self.getManagerCost(); if (money >= mCost && !self.isAuto()) { money -= mCost; businesses[self.bizId].manager = true; self.refresh(); updateMoneyUI(); saveGame(); } }; // Get current cost to buy/upgrade self.getCost = function () { var lvl = businesses[self.bizId].level; return Math.floor(self.bizData.baseCost * Math.pow(self.bizData.costMult, lvl)); }; // Get current profit self.getProfit = function () { var lvl = businesses[self.bizId].level; if (lvl === 0) return 0; return Math.floor(self.bizData.baseProfit * lvl * Math.pow(1.07, lvl - 1)); }; // Get duration (ms) self.getDuration = function () { return self.bizData.baseTime; }; // Get manager cost self.getManagerCost = function () { return self.bizData.managerCost; }; // Update UI self.refresh = function () { var lvl = businesses[self.bizId].level; var unlocked = lvl > 0; var profit = self.getProfit(); var cost = self.getCost(); var mCost = self.getManagerCost(); levelTxt.setText("Lvl " + lvl); costTxt.setText(unlocked ? "Upgrade: $" + formatNum(cost) : "Buy: $" + formatNum(cost)); profitTxt.setText("+$" + formatNum(profit)); profitTxt.alpha = unlocked ? 1 : 0.3; levelTxt.alpha = unlocked ? 1 : 0.3; icon.alpha = unlocked ? 1 : 0.3; // Timer bar timerBar.width = 320 * (self.timer > 0 ? 1 - self.timer / self.getDuration() : 0); // Upgrade button upgradeBtn.alpha = money >= cost ? 1 : 0.5; // (Auto/manager button UI refresh removed) }; // Update per tick self.update = function () { if (!self.isUnlocked()) { self.refresh(); return; } // Auto-run if manager or level > 1 if ((self.isAuto() || businesses[self.bizId].level > 1) && self.timer <= 0) { self.startRun(); // Ensure running is set so update continues ticking self.running = true; } // Progress timer if (self.timer > 0) { self.timer -= 1000 / 60; if (self.timer <= 0) { self.timer = 0; // Award profit var profit = self.getProfit(); money += profit; updateMoneyUI(); saveGame(); self.refresh(); // Money particle effect: spawn several particles at the top center if (typeof moneyParticles !== "undefined") { var particleCount = Math.min(10, 2 + Math.floor(profit / 10)); for (var i = 0; i < particleCount; ++i) { var p = new MoneyParticle(); // Spawn at random X across the top of the screen p.x = 100 + Math.random() * (2048 - 200); // avoid extreme edges p.y = 120 + Math.random() * 40; if (typeof game !== "undefined") game.addChild(p); moneyParticles.push(p); } } // If auto, start again next frame } self.refresh(); } }; return self; }); // MoneyParticle class: represents a single falling money particle var MoneyParticle = Container.expand(function () { var self = Container.call(this); // Use the 'money_bg' asset as a simple money particle (could be replaced with a coin image if available) var particle = self.attachAsset('money_bg', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.7, scaleY: 0.7, x: 0, y: 0, alpha: 0.7 // set transparency for money particle image }); // Removed dollar text from MoneyParticle // Give each particle a random burst direction and distance var burstAngle = Math.random() * Math.PI * 2; var burstDistance = 80 + Math.random() * 40; self.vx = Math.cos(burstAngle) * burstDistance / 40; self.vy = Math.sin(burstAngle) * burstDistance / 40 + 2; // Add random rotation to the particle var startRotation = Math.random() * Math.PI * 2; self.rotation = startRotation; // Add random delay before burst self._burstStarted = false; self._burstDelay = Math.random() * 300; // up to 300ms delay self._burstTimer = 0; self._burstLife = 40 + Math.floor(Math.random() * 20); self._fadeStarted = false; // Overwrite update to handle movement, fade, and cleanup self.update = function () { if (!self._burstStarted) { self._burstTimer += 1000 / 60; if (self._burstTimer >= self._burstDelay) { self._burstStarted = true; // Start fade out tween after burst starts tween(self, { alpha: 0 }, { duration: self._burstLife * 32, easing: tween.linear }); // Animate rotation to a new random value during the burst var endRotation = startRotation + (Math.random() - 0.5) * Math.PI * 2; tween(self, { rotation: endRotation }, { duration: self._burstLife * 16, easing: tween.linear }); } else { return; } } self.x += self.vx; self.y += self.vy; self._burstLife--; if (self._burstLife <= 0) { if (self.parent) self.parent.removeChild(self); if (typeof moneyParticles !== "undefined") { var idx = moneyParticles.indexOf(self); if (idx !== -1) moneyParticles.splice(idx, 1); } } }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x87ceeb // Changed to a sky blue color }); /**** * Game Code ****/ // --- Game Data --- // Business icons (simple colored boxes for MVP) // Reference for business row background // Reference: To change the slider sprite, update the asset below with your own image id and dimensions. var businessList = [{ id: 'lemon', name: 'hawli doruk', asset: 'biz_lemon', baseCost: 4, costMult: 1.07, baseProfit: 1, baseTime: 1000, managerCost: 100 }, { id: 'newspaper', name: 'kwzx10r', asset: 'biz_newspaper', baseCost: 60, costMult: 1.15, baseProfit: 8, baseTime: 3000, managerCost: 500 }, { id: 'carwash', name: 'motor yıkama', asset: 'biz_carwash', baseCost: 720, costMult: 1.14, baseProfit: 64, baseTime: 6000, managerCost: 3000 }, { id: 'pizza', name: 'Pizza Delivery', asset: 'biz_pizza', baseCost: 8640, costMult: 1.13, baseProfit: 576, baseTime: 12000, managerCost: 10000 }, { id: 'movie', name: 'Movie Studio', asset: 'biz_movie', baseCost: 103680, costMult: 1.12, baseProfit: 5184, baseTime: 24000, managerCost: 100000 }, { id: 'bank', name: 'Bank', asset: 'biz_bank', baseCost: 1244160, costMult: 1.11, baseProfit: 46656, baseTime: 48000, managerCost: 500000 }, { id: 'oil', name: 'Oil Company', asset: 'biz_oil', baseCost: 14929920, costMult: 1.10, baseProfit: 419904, baseTime: 96000, managerCost: 1200000 }, // New business types { id: 'icecream', name: 'Ice Cream Truck', asset: 'biz_lemon', // Use lemon asset as placeholder, update with new asset if available baseCost: 20000000, costMult: 1.09, baseProfit: 800000, baseTime: 120000, managerCost: 2500000 }]; // --- State --- var money = 0; var businesses = {}; var businessObjs = []; var lastTick = 0; // --- Money Particle System --- var moneyParticles = []; // --- UI Elements --- var moneyTxt = null; var tapBtn = null; var tapBtnTxt = null; // --- Utility Functions --- function formatNum(n) { if (n < 1000) return "" + n; var units = ['K', 'M', 'B', 'T', 'Qa', 'Qi', 'Sx', 'Sp', 'Oc', 'No', 'Dc']; var u = -1; while (n >= 1000 && u < units.length - 1) { n /= 1000; u++; } return n.toFixed(2) + units[u]; } function updateMoneyUI() { moneyTxt.setText("$" + formatNum(money)); } // --- Save/Load --- function saveGame() { storage.money = money; storage.businesses = {}; for (var i = 0; i < businessList.length; ++i) { var id = businessList[i].id; storage.businesses[id + "_level"] = businesses[id].level; storage.businesses[id + "_manager"] = businesses[id].manager; } storage.lastTick = Date.now(); } function loadGame() { money = storage.money || 0; businesses = {}; for (var i = 0; i < businessList.length; ++i) { var id = businessList[i].id; // Start with 1 lemonade stand businesses[id] = { level: id === 'lemon' ? 1 : 0, manager: false }; if (storage.businesses) { if (typeof storage.businesses[id + "_level"] !== "undefined") { businesses[id].level = storage.businesses[id + "_level"]; } if (typeof storage.businesses[id + "_manager"] !== "undefined") { businesses[id].manager = !!storage.businesses[id + "_manager"]; } } } lastTick = storage.lastTick || Date.now(); } // --- Offline Progress --- function applyOfflineEarnings() { var now = Date.now(); var dt = now - lastTick; if (dt < 1000) return; var total = 0; for (var i = 0; i < businessList.length; ++i) { var biz = businessList[i]; var b = businesses[biz.id]; if (b.level > 0 && b.manager) { var cycles = Math.floor(dt / biz.baseTime); var profit = Math.floor(biz.baseProfit * b.level * Math.pow(1.07, b.level - 1)); total += cycles * profit; } } if (total > 0) { money += total; updateMoneyUI(); } } // --- Game Setup --- // Add background image behind all game elements var bgImage = LK.getAsset('bg_main', { anchorX: 0.5, anchorY: 0.5, x: 2048 / 2, y: 2732 / 2, scaleX: 1, scaleY: 1 }); game.addChild(bgImage); // (Removed bottom overlay image that hid overflowing businesses) // No overlay is added, so businesses can overflow the screen as needed. function setupUI() { // Add total money text to the top center of the GUI moneyTxt = new Text2("$0", { size: 90, fill: "#222", font: "'GillSans-Bold', Impact, 'Arial Black', Tahoma" }); moneyTxt.anchor.set(0.5, 0); moneyTxt.y = 40; // Move the money text a little bit down from the top LK.gui.top.addChild(moneyTxt); // Update the money text with the current money value updateMoneyUI = function updateMoneyUI() { if (moneyTxt) { moneyTxt.setText("$" + formatNum(money)); } }; // Tap button (big, bottom right) tapBtn = LK.getAsset('tap_btn', { anchorX: 1, anchorY: 1, // bottom right of the screen x: 2048 - 80, y: 2732 - 80, scaleX: 1.5, scaleY: 1.5 }); tapBtn.interactive = true; // Removed tapBtnTxt label tapBtn.down = function (x, y, obj) { if (game.down) game.down(x, y, tapBtn); }; game.addChild(tapBtn); // Move to front after all other addChild calls tapBtn.zIndex = 9999; // Defensive: ensure it's on top if zIndex is supported // Business rows // Slideable area for businesses // ... later in setupUI: var businessScrollArea = new Container(); businessScrollArea.x = 0; businessScrollArea.y = 0; game.addChild(businessScrollArea); // (Removed mask area and mask logic so businesses can overflow the screen) var startY = 500; var gapY = 260; // Further increased gap for even more space between businesses for (var i = 0; i < businessList.length; ++i) { var biz = businessList[i]; // Add background image for business row var bizRowBg = LK.getAsset('biz_row_bg', { anchorX: 0, anchorY: 0.5, x: 20, // squish more to the left y: startY + i * gapY, scaleX: 0.7, // squish width to 70% scaleY: 1 }); bizRowBg.alpha = 0.5; // Set transparency for business row background businessScrollArea.addChild(bizRowBg); // Create business row on top of background var bizObj = new Business(); bizObj.setup(biz.id, biz, i); bizObj.x = 200; bizObj.y = startY + i * gapY; businessScrollArea.addChild(bizObj); businessObjs.push(bizObj); } // --- Slide/scroll logic for businessScrollArea --- var scrollY = 0; var scrollStartY = 0; var scrollTouchStartY = 0; var isScrolling = false; var minScrollY = Math.min(0, 2732 - (startY + businessList.length * gapY + 200)); var maxScrollY = 0; // Touch/mouse down on scroll area game.down = function (origDown) { return function (x, y, obj) { // If tap is inside the business area (not tapBtn), start scroll if (y > startY - gapY && y < 2732 - 400 && obj !== tapBtn) { isScrolling = true; scrollTouchStartY = y; scrollStartY = scrollY; } // Pass through to original tap logic (for tapBtn, etc) if (typeof origDown === "function") origDown(x, y, obj); }; }(game.down); // Touch/mouse move game.move = function (x, y, obj) { if (isScrolling) { var dy = y - scrollTouchStartY; scrollY = scrollStartY + dy; // Clamp scroll if (scrollY > maxScrollY) scrollY = maxScrollY; if (scrollY < minScrollY) scrollY = minScrollY; businessScrollArea.y = scrollY; } }; // Touch/mouse up game.up = function (x, y, obj) { isScrolling = false; }; } // (Removed code that added bottomOverlay in front of everything) // No overlay is added, so businesses can overflow the screen as needed. // --- Upgrade Multiplier Buttons --- var upgradeMultipliers = [1, 10, 100]; var upgradeMultiplier = 1; // Default to x1 var upgradeBtns = []; var upgradeBtnLabels = ["x1", "x10", "x100"]; var btnStartY = 700; var btnGapY = 180; for (var i = 0; i < upgradeMultipliers.length; ++i) { var btn = LK.getAsset('manager_btn', { anchorX: 1, anchorY: 0.5, x: 2048 - 60, y: btnStartY + i * btnGapY, width: 220, height: 120 }); btn.interactive = true; // Add label var btnTxt = new Text2(upgradeBtnLabels[i], { size: 60, fill: "#fff", font: "'GillSans-Bold', Impact, 'Arial Black', Tahoma" }); btnTxt.anchor.set(0.5, 0.5); btnTxt.x = btn.width / 2; btnTxt.y = btn.height / 2; btn.addChild(btnTxt); // Highlight selected btn.alpha = i === 0 ? 1 : 0.6; // Closure for index (function (idx, btnRef) { btn.down = function (x, y, obj) { upgradeMultiplier = upgradeMultipliers[idx]; // Update button alphas for selection for (var j = 0; j < upgradeBtns.length; ++j) { upgradeBtns[j].alpha = j === idx ? 1 : 0.6; } }; })(i, btn); LK.gui.right.addChild(btn); upgradeBtns.push(btn); } // --- Tap Handler --- game.down = function (x, y, obj) { // Tap on tapBtn if (obj === tapBtn || obj === tapBtnTxt) { var tapVal = 1 + Math.floor(businesses['lemon'].level / 10); money += tapVal; updateMoneyUI(); saveGame(); // Money particle effect: spawn several particles at the top center var particleCount = Math.min(10, 2 + Math.floor(tapVal / 5)); for (var i = 0; i < particleCount; ++i) { var p = new MoneyParticle(); // Spawn at random X across the top of the screen p.x = 100 + Math.random() * (2048 - 200); // avoid extreme edges p.y = 120 + Math.random() * 40; game.addChild(p); moneyParticles.push(p); } // Animate tapBtn tween(tapBtn, { scaleX: 1.3, scaleY: 1.3 }, { duration: 80, easing: tween.easeOut, onFinish: function onFinish() { tween(tapBtn, { scaleX: 1.5, scaleY: 1.5 }, { duration: 80, easing: tween.easeIn }); } }); } }; // --- Game Update --- game.update = function () { // Update all businesses for (var i = 0; i < businessObjs.length; ++i) { if (!businessObjs[i]) { continue; } var bizObj = businessObjs[i]; if (typeof bizObj.update === "function") { bizObj.update(); } // (Removed mask/unmask logic so businesses can overflow the screen) } // Update and animate money particles for (var i = moneyParticles.length - 1; i >= 0; --i) { moneyParticles[i].update(); } }; // --- Init --- loadGame(); applyOfflineEarnings(); setupUI(); updateMoneyUI(); // --- Save every 5 seconds --- LK.setInterval(function () { saveGame(); }, 5000); ;
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1", {
money: 0,
businesses: {},
lastTick: 0
});
/****
* Classes
****/
// Business class: represents a single business row
var Business = Container.expand(function () {
var self = Container.call(this);
// Properties (set after creation)
self.bizId = null;
self.bizData = null;
self.index = 0;
// UI elements
var icon = null;
var nameTxt = null;
var levelTxt = null;
var costTxt = null;
var profitTxt = null;
var timerBar = null;
var upgradeBtn = null;
var managerBtn = null;
// State
self.timer = 0; // ms left for current run
self.running = false;
// Setup method (called after creation)
self.setup = function (bizId, bizData, index) {
self.bizId = bizId;
self.bizData = bizData;
self.index = index;
// Icon
icon = self.attachAsset(bizData.asset, {
anchorX: 0.5,
anchorY: 0.5,
x: 0,
y: 0
});
// Name
nameTxt = new Text2(bizData.name, {
size: 48,
fill: "#222",
font: "'GillSans-Bold', Impact, 'Arial Black', Tahoma"
});
nameTxt.anchor.set(0, 0.5);
nameTxt.x = 140;
nameTxt.y = 0;
self.addChild(nameTxt);
// Level
levelTxt = new Text2("Lvl 0", {
size: 40,
fill: "#444",
font: "'GillSans-Bold', Impact, 'Arial Black', Tahoma"
});
levelTxt.anchor.set(0, 0.5);
levelTxt.x = 140;
levelTxt.y = 50;
self.addChild(levelTxt);
// Cost
costTxt = new Text2("Buy: $0", {
size: 36,
fill: "#666",
font: "'GillSans-Bold', Impact, 'Arial Black', Tahoma"
});
costTxt.anchor.set(0, 0.5);
costTxt.x = 140;
costTxt.y = -50;
self.addChild(costTxt);
// Profit
profitTxt = new Text2("+$0", {
size: 48,
fill: 0x008000,
font: "'GillSans-Bold', Impact, 'Arial Black', Tahoma"
});
profitTxt.anchor.set(1, 0.5);
profitTxt.x = 900;
profitTxt.y = 0;
self.addChild(profitTxt);
// Timer bar background (shows total progress area)
var timerBarBg = self.attachAsset('slider_sprite', {
anchorX: 0,
anchorY: 0.5,
x: 140,
y: 80,
width: 320,
height: 24,
// match new thinner asset height for best appearance
tint: 0x000000 // transparent black
});
timerBarBg.alpha = 0.5;
self.addChild(timerBarBg);
// Timer bar (progress fill)
timerBar = self.attachAsset('slider_sprite', {
anchorX: 0,
anchorY: 0.5,
x: 140,
y: 80,
width: 0,
height: 24 // match new thinner asset height for best appearance
});
timerBar.alpha = 0.5;
// Upgrade button
upgradeBtn = self.attachAsset('upgrade_btn', {
anchorX: 0.5,
anchorY: 0.5,
x: 1100,
y: 0
});
upgradeBtn.interactive = true;
upgradeBtn.down = function (x, y, obj) {
if (self.down) self.down(x, y, upgradeBtn);
};
// Removed upgradeTxt label
// (Auto/manager button removed)
// Event listeners
self.down = function (x, y, obj) {
// If tap on icon, start business if unlocked
if (self.isUnlocked() && !self.isAuto() && self.timer <= 0) {
self.startRun();
}
// If tap on upgrade button
if (self.isUnlocked() && obj === upgradeBtn && upgradeBtn.alpha >= 1) {
self.tryUpgrade();
}
// (Auto/manager button tap logic removed)
// If tap anywhere on the business row and not unlocked, allow buying
if (!self.isUnlocked()) {
self.tryUpgrade();
}
};
// Update UI
self.refresh();
};
// Is business unlocked?
self.isUnlocked = function () {
return businesses[self.bizId].level > 0;
};
// Is manager hired?
self.isAuto = function () {
return businesses[self.bizId].manager;
};
// Start a run (manual or auto)
self.startRun = function () {
if (!self.isUnlocked()) return;
if (self.timer > 0) return;
self.timer = self.getDuration();
self.running = true;
};
// Try to buy/upgrade
self.tryUpgrade = function () {
// Calculate how many upgrades we can afford with the current multiplier
var maxUpgrades = typeof upgradeMultiplier !== "undefined" ? upgradeMultiplier : 1;
var bought = 0;
for (var i = 0; i < maxUpgrades; ++i) {
var cost = self.getCost();
if (money >= cost && upgradeBtn.alpha >= 1) {
money -= cost;
businesses[self.bizId].level += 1;
bought++;
} else {
break;
}
}
if (bought > 0) {
self.refresh();
updateMoneyUI();
saveGame();
}
};
// Try to hire manager
self.tryHireManager = function () {
var mCost = self.getManagerCost();
if (money >= mCost && !self.isAuto()) {
money -= mCost;
businesses[self.bizId].manager = true;
self.refresh();
updateMoneyUI();
saveGame();
}
};
// Get current cost to buy/upgrade
self.getCost = function () {
var lvl = businesses[self.bizId].level;
return Math.floor(self.bizData.baseCost * Math.pow(self.bizData.costMult, lvl));
};
// Get current profit
self.getProfit = function () {
var lvl = businesses[self.bizId].level;
if (lvl === 0) return 0;
return Math.floor(self.bizData.baseProfit * lvl * Math.pow(1.07, lvl - 1));
};
// Get duration (ms)
self.getDuration = function () {
return self.bizData.baseTime;
};
// Get manager cost
self.getManagerCost = function () {
return self.bizData.managerCost;
};
// Update UI
self.refresh = function () {
var lvl = businesses[self.bizId].level;
var unlocked = lvl > 0;
var profit = self.getProfit();
var cost = self.getCost();
var mCost = self.getManagerCost();
levelTxt.setText("Lvl " + lvl);
costTxt.setText(unlocked ? "Upgrade: $" + formatNum(cost) : "Buy: $" + formatNum(cost));
profitTxt.setText("+$" + formatNum(profit));
profitTxt.alpha = unlocked ? 1 : 0.3;
levelTxt.alpha = unlocked ? 1 : 0.3;
icon.alpha = unlocked ? 1 : 0.3;
// Timer bar
timerBar.width = 320 * (self.timer > 0 ? 1 - self.timer / self.getDuration() : 0);
// Upgrade button
upgradeBtn.alpha = money >= cost ? 1 : 0.5;
// (Auto/manager button UI refresh removed)
};
// Update per tick
self.update = function () {
if (!self.isUnlocked()) {
self.refresh();
return;
}
// Auto-run if manager or level > 1
if ((self.isAuto() || businesses[self.bizId].level > 1) && self.timer <= 0) {
self.startRun();
// Ensure running is set so update continues ticking
self.running = true;
}
// Progress timer
if (self.timer > 0) {
self.timer -= 1000 / 60;
if (self.timer <= 0) {
self.timer = 0;
// Award profit
var profit = self.getProfit();
money += profit;
updateMoneyUI();
saveGame();
self.refresh();
// Money particle effect: spawn several particles at the top center
if (typeof moneyParticles !== "undefined") {
var particleCount = Math.min(10, 2 + Math.floor(profit / 10));
for (var i = 0; i < particleCount; ++i) {
var p = new MoneyParticle();
// Spawn at random X across the top of the screen
p.x = 100 + Math.random() * (2048 - 200); // avoid extreme edges
p.y = 120 + Math.random() * 40;
if (typeof game !== "undefined") game.addChild(p);
moneyParticles.push(p);
}
}
// If auto, start again next frame
}
self.refresh();
}
};
return self;
});
// MoneyParticle class: represents a single falling money particle
var MoneyParticle = Container.expand(function () {
var self = Container.call(this);
// Use the 'money_bg' asset as a simple money particle (could be replaced with a coin image if available)
var particle = self.attachAsset('money_bg', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.7,
scaleY: 0.7,
x: 0,
y: 0,
alpha: 0.7 // set transparency for money particle image
});
// Removed dollar text from MoneyParticle
// Give each particle a random burst direction and distance
var burstAngle = Math.random() * Math.PI * 2;
var burstDistance = 80 + Math.random() * 40;
self.vx = Math.cos(burstAngle) * burstDistance / 40;
self.vy = Math.sin(burstAngle) * burstDistance / 40 + 2;
// Add random rotation to the particle
var startRotation = Math.random() * Math.PI * 2;
self.rotation = startRotation;
// Add random delay before burst
self._burstStarted = false;
self._burstDelay = Math.random() * 300; // up to 300ms delay
self._burstTimer = 0;
self._burstLife = 40 + Math.floor(Math.random() * 20);
self._fadeStarted = false;
// Overwrite update to handle movement, fade, and cleanup
self.update = function () {
if (!self._burstStarted) {
self._burstTimer += 1000 / 60;
if (self._burstTimer >= self._burstDelay) {
self._burstStarted = true;
// Start fade out tween after burst starts
tween(self, {
alpha: 0
}, {
duration: self._burstLife * 32,
easing: tween.linear
});
// Animate rotation to a new random value during the burst
var endRotation = startRotation + (Math.random() - 0.5) * Math.PI * 2;
tween(self, {
rotation: endRotation
}, {
duration: self._burstLife * 16,
easing: tween.linear
});
} else {
return;
}
}
self.x += self.vx;
self.y += self.vy;
self._burstLife--;
if (self._burstLife <= 0) {
if (self.parent) self.parent.removeChild(self);
if (typeof moneyParticles !== "undefined") {
var idx = moneyParticles.indexOf(self);
if (idx !== -1) moneyParticles.splice(idx, 1);
}
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x87ceeb // Changed to a sky blue color
});
/****
* Game Code
****/
// --- Game Data ---
// Business icons (simple colored boxes for MVP)
// Reference for business row background
// Reference: To change the slider sprite, update the asset below with your own image id and dimensions.
var businessList = [{
id: 'lemon',
name: 'hawli doruk',
asset: 'biz_lemon',
baseCost: 4,
costMult: 1.07,
baseProfit: 1,
baseTime: 1000,
managerCost: 100
}, {
id: 'newspaper',
name: 'kwzx10r',
asset: 'biz_newspaper',
baseCost: 60,
costMult: 1.15,
baseProfit: 8,
baseTime: 3000,
managerCost: 500
}, {
id: 'carwash',
name: 'motor yıkama',
asset: 'biz_carwash',
baseCost: 720,
costMult: 1.14,
baseProfit: 64,
baseTime: 6000,
managerCost: 3000
}, {
id: 'pizza',
name: 'Pizza Delivery',
asset: 'biz_pizza',
baseCost: 8640,
costMult: 1.13,
baseProfit: 576,
baseTime: 12000,
managerCost: 10000
}, {
id: 'movie',
name: 'Movie Studio',
asset: 'biz_movie',
baseCost: 103680,
costMult: 1.12,
baseProfit: 5184,
baseTime: 24000,
managerCost: 100000
}, {
id: 'bank',
name: 'Bank',
asset: 'biz_bank',
baseCost: 1244160,
costMult: 1.11,
baseProfit: 46656,
baseTime: 48000,
managerCost: 500000
}, {
id: 'oil',
name: 'Oil Company',
asset: 'biz_oil',
baseCost: 14929920,
costMult: 1.10,
baseProfit: 419904,
baseTime: 96000,
managerCost: 1200000
},
// New business types
{
id: 'icecream',
name: 'Ice Cream Truck',
asset: 'biz_lemon',
// Use lemon asset as placeholder, update with new asset if available
baseCost: 20000000,
costMult: 1.09,
baseProfit: 800000,
baseTime: 120000,
managerCost: 2500000
}];
// --- State ---
var money = 0;
var businesses = {};
var businessObjs = [];
var lastTick = 0;
// --- Money Particle System ---
var moneyParticles = [];
// --- UI Elements ---
var moneyTxt = null;
var tapBtn = null;
var tapBtnTxt = null;
// --- Utility Functions ---
function formatNum(n) {
if (n < 1000) return "" + n;
var units = ['K', 'M', 'B', 'T', 'Qa', 'Qi', 'Sx', 'Sp', 'Oc', 'No', 'Dc'];
var u = -1;
while (n >= 1000 && u < units.length - 1) {
n /= 1000;
u++;
}
return n.toFixed(2) + units[u];
}
function updateMoneyUI() {
moneyTxt.setText("$" + formatNum(money));
}
// --- Save/Load ---
function saveGame() {
storage.money = money;
storage.businesses = {};
for (var i = 0; i < businessList.length; ++i) {
var id = businessList[i].id;
storage.businesses[id + "_level"] = businesses[id].level;
storage.businesses[id + "_manager"] = businesses[id].manager;
}
storage.lastTick = Date.now();
}
function loadGame() {
money = storage.money || 0;
businesses = {};
for (var i = 0; i < businessList.length; ++i) {
var id = businessList[i].id;
// Start with 1 lemonade stand
businesses[id] = {
level: id === 'lemon' ? 1 : 0,
manager: false
};
if (storage.businesses) {
if (typeof storage.businesses[id + "_level"] !== "undefined") {
businesses[id].level = storage.businesses[id + "_level"];
}
if (typeof storage.businesses[id + "_manager"] !== "undefined") {
businesses[id].manager = !!storage.businesses[id + "_manager"];
}
}
}
lastTick = storage.lastTick || Date.now();
}
// --- Offline Progress ---
function applyOfflineEarnings() {
var now = Date.now();
var dt = now - lastTick;
if (dt < 1000) return;
var total = 0;
for (var i = 0; i < businessList.length; ++i) {
var biz = businessList[i];
var b = businesses[biz.id];
if (b.level > 0 && b.manager) {
var cycles = Math.floor(dt / biz.baseTime);
var profit = Math.floor(biz.baseProfit * b.level * Math.pow(1.07, b.level - 1));
total += cycles * profit;
}
}
if (total > 0) {
money += total;
updateMoneyUI();
}
}
// --- Game Setup ---
// Add background image behind all game elements
var bgImage = LK.getAsset('bg_main', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2,
y: 2732 / 2,
scaleX: 1,
scaleY: 1
});
game.addChild(bgImage);
// (Removed bottom overlay image that hid overflowing businesses)
// No overlay is added, so businesses can overflow the screen as needed.
function setupUI() {
// Add total money text to the top center of the GUI
moneyTxt = new Text2("$0", {
size: 90,
fill: "#222",
font: "'GillSans-Bold', Impact, 'Arial Black', Tahoma"
});
moneyTxt.anchor.set(0.5, 0);
moneyTxt.y = 40; // Move the money text a little bit down from the top
LK.gui.top.addChild(moneyTxt);
// Update the money text with the current money value
updateMoneyUI = function updateMoneyUI() {
if (moneyTxt) {
moneyTxt.setText("$" + formatNum(money));
}
};
// Tap button (big, bottom right)
tapBtn = LK.getAsset('tap_btn', {
anchorX: 1,
anchorY: 1,
// bottom right of the screen
x: 2048 - 80,
y: 2732 - 80,
scaleX: 1.5,
scaleY: 1.5
});
tapBtn.interactive = true;
// Removed tapBtnTxt label
tapBtn.down = function (x, y, obj) {
if (game.down) game.down(x, y, tapBtn);
};
game.addChild(tapBtn); // Move to front after all other addChild calls
tapBtn.zIndex = 9999; // Defensive: ensure it's on top if zIndex is supported
// Business rows
// Slideable area for businesses
// ... later in setupUI:
var businessScrollArea = new Container();
businessScrollArea.x = 0;
businessScrollArea.y = 0;
game.addChild(businessScrollArea);
// (Removed mask area and mask logic so businesses can overflow the screen)
var startY = 500;
var gapY = 260; // Further increased gap for even more space between businesses
for (var i = 0; i < businessList.length; ++i) {
var biz = businessList[i];
// Add background image for business row
var bizRowBg = LK.getAsset('biz_row_bg', {
anchorX: 0,
anchorY: 0.5,
x: 20,
// squish more to the left
y: startY + i * gapY,
scaleX: 0.7,
// squish width to 70%
scaleY: 1
});
bizRowBg.alpha = 0.5; // Set transparency for business row background
businessScrollArea.addChild(bizRowBg);
// Create business row on top of background
var bizObj = new Business();
bizObj.setup(biz.id, biz, i);
bizObj.x = 200;
bizObj.y = startY + i * gapY;
businessScrollArea.addChild(bizObj);
businessObjs.push(bizObj);
}
// --- Slide/scroll logic for businessScrollArea ---
var scrollY = 0;
var scrollStartY = 0;
var scrollTouchStartY = 0;
var isScrolling = false;
var minScrollY = Math.min(0, 2732 - (startY + businessList.length * gapY + 200));
var maxScrollY = 0;
// Touch/mouse down on scroll area
game.down = function (origDown) {
return function (x, y, obj) {
// If tap is inside the business area (not tapBtn), start scroll
if (y > startY - gapY && y < 2732 - 400 && obj !== tapBtn) {
isScrolling = true;
scrollTouchStartY = y;
scrollStartY = scrollY;
}
// Pass through to original tap logic (for tapBtn, etc)
if (typeof origDown === "function") origDown(x, y, obj);
};
}(game.down);
// Touch/mouse move
game.move = function (x, y, obj) {
if (isScrolling) {
var dy = y - scrollTouchStartY;
scrollY = scrollStartY + dy;
// Clamp scroll
if (scrollY > maxScrollY) scrollY = maxScrollY;
if (scrollY < minScrollY) scrollY = minScrollY;
businessScrollArea.y = scrollY;
}
};
// Touch/mouse up
game.up = function (x, y, obj) {
isScrolling = false;
};
}
// (Removed code that added bottomOverlay in front of everything)
// No overlay is added, so businesses can overflow the screen as needed.
// --- Upgrade Multiplier Buttons ---
var upgradeMultipliers = [1, 10, 100];
var upgradeMultiplier = 1; // Default to x1
var upgradeBtns = [];
var upgradeBtnLabels = ["x1", "x10", "x100"];
var btnStartY = 700;
var btnGapY = 180;
for (var i = 0; i < upgradeMultipliers.length; ++i) {
var btn = LK.getAsset('manager_btn', {
anchorX: 1,
anchorY: 0.5,
x: 2048 - 60,
y: btnStartY + i * btnGapY,
width: 220,
height: 120
});
btn.interactive = true;
// Add label
var btnTxt = new Text2(upgradeBtnLabels[i], {
size: 60,
fill: "#fff",
font: "'GillSans-Bold', Impact, 'Arial Black', Tahoma"
});
btnTxt.anchor.set(0.5, 0.5);
btnTxt.x = btn.width / 2;
btnTxt.y = btn.height / 2;
btn.addChild(btnTxt);
// Highlight selected
btn.alpha = i === 0 ? 1 : 0.6;
// Closure for index
(function (idx, btnRef) {
btn.down = function (x, y, obj) {
upgradeMultiplier = upgradeMultipliers[idx];
// Update button alphas for selection
for (var j = 0; j < upgradeBtns.length; ++j) {
upgradeBtns[j].alpha = j === idx ? 1 : 0.6;
}
};
})(i, btn);
LK.gui.right.addChild(btn);
upgradeBtns.push(btn);
}
// --- Tap Handler ---
game.down = function (x, y, obj) {
// Tap on tapBtn
if (obj === tapBtn || obj === tapBtnTxt) {
var tapVal = 1 + Math.floor(businesses['lemon'].level / 10);
money += tapVal;
updateMoneyUI();
saveGame();
// Money particle effect: spawn several particles at the top center
var particleCount = Math.min(10, 2 + Math.floor(tapVal / 5));
for (var i = 0; i < particleCount; ++i) {
var p = new MoneyParticle();
// Spawn at random X across the top of the screen
p.x = 100 + Math.random() * (2048 - 200); // avoid extreme edges
p.y = 120 + Math.random() * 40;
game.addChild(p);
moneyParticles.push(p);
}
// Animate tapBtn
tween(tapBtn, {
scaleX: 1.3,
scaleY: 1.3
}, {
duration: 80,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(tapBtn, {
scaleX: 1.5,
scaleY: 1.5
}, {
duration: 80,
easing: tween.easeIn
});
}
});
}
};
// --- Game Update ---
game.update = function () {
// Update all businesses
for (var i = 0; i < businessObjs.length; ++i) {
if (!businessObjs[i]) {
continue;
}
var bizObj = businessObjs[i];
if (typeof bizObj.update === "function") {
bizObj.update();
}
// (Removed mask/unmask logic so businesses can overflow the screen)
}
// Update and animate money particles
for (var i = moneyParticles.length - 1; i >= 0; --i) {
moneyParticles[i].update();
}
};
// --- Init ---
loadGame();
applyOfflineEarnings();
setupUI();
updateMoneyUI();
// --- Save every 5 seconds ---
LK.setInterval(function () {
saveGame();
}, 5000);
;
pizza store. In-Game asset. 2d. High contrast. No shadows
movie theater. In-Game asset. 2d. High contrast. No shadows
bank. In-Game asset. 2d. High contrast. No shadows
oil company. In-Game asset. 2d. High contrast. No shadows
a sunny place where the mountains are sweet. In-Game asset. 2d. High contrast. No shadows
dollar paper is sweet In-Game asset. 2d. High contrast. No shadows
button when clicked earn gold is sweeti. money logo should look like candy. In-Game asset. 2d. High contrast. No shadows
button upgrade level of business is sweetie In-Game asset. 2d. High contrast. No shadows
engine wash photo. In-Game asset. 2d. High contrast. No shadows