/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1", {
money: 1000,
day: 1,
products: 3,
customers: 0,
staff: 0,
storeLevel: 1,
priceMultiplier: 1,
lastSave: undefined
});
/****
* Classes
****/
var Button = Container.expand(function (text, width, height) {
var self = Container.call(this);
width = width || 300;
height = height || 80;
var buttonBg = self.attachAsset('btnBg', {
anchorX: 0.5,
anchorY: 0.5,
width: width,
height: height
});
var buttonText = new Text2(text, {
size: 40,
fill: 0xFFFFFF
});
buttonText.anchor.set(0.5, 0.5);
self.addChild(buttonText);
self.down = function () {
tween(buttonBg, {
scaleX: 0.95,
scaleY: 0.95
}, {
duration: 100
});
};
self.up = function () {
tween(buttonBg, {
scaleX: 1,
scaleY: 1
}, {
duration: 100
});
};
self.setText = function (newText) {
buttonText.setText(newText);
};
self.setEnabled = function (enabled) {
self.interactive = enabled;
buttonBg.alpha = enabled ? 1.0 : 0.5;
};
self.setEnabled(true);
return self;
});
var CashParticle = Container.expand(function () {
var self = Container.call(this);
var cashGraphics = self.attachAsset('cash', {
anchorX: 0.5,
anchorY: 0.5
});
self.vx = (Math.random() - 0.5) * 10;
self.vy = -5 - Math.random() * 10;
self.gravity = 0.5;
self.lifespan = 60; // 1 second at 60fps
self.update = function () {
self.x += self.vx;
self.vy += self.gravity;
self.y += self.vy;
self.lifespan--;
if (self.lifespan <= 0) {
self.readyToRemove = true;
}
};
return self;
});
var Customer = Container.expand(function () {
var self = Container.call(this);
var customerGraphics = self.attachAsset('customer', {
anchorX: 0.5,
anchorY: 0.5
});
// Customer properties
self.patience = 60 + Math.random() * 180; // 1-4 seconds patience (60fps)
self.waitTime = 0;
self.spending = 20 + Math.floor(Math.random() * 80); // How much they want to spend
self.targetProducts = 1 + Math.floor(Math.random() * 2); // How many products they want to buy
self.productsBought = 0;
self.state = "entering"; // entering, shopping, leaving
self.happiness = 1.0; // 0.0 to 1.0
// Personalization - random tint
var randomHue = Math.random() * 0x1000000;
customerGraphics.tint = randomHue;
self.update = function () {
if (self.state === "shopping") {
self.waitTime++;
// Decrease happiness as they wait
self.happiness = Math.max(0, 1 - self.waitTime / self.patience);
// Visual feedback - customer turns redder as they get impatient
var redTint = Math.floor(0xff0000 * (1 - self.happiness));
customerGraphics.tint = 0xffffff - redTint;
// Customer leaves if too impatient
if (self.waitTime >= self.patience) {
self.state = "leaving";
tween(self, {
alpha: 0
}, {
duration: 1000,
onFinish: function onFinish() {
self.readyToRemove = true;
}
});
}
}
};
self.shop = function (availableProducts) {
if (availableProducts > 0 && self.productsBought < self.targetProducts) {
self.productsBought++;
// Flash the customer when they buy something
LK.effects.flashObject(self, 0x00ff00, 500);
if (self.productsBought >= self.targetProducts) {
// Customer satisfied, will leave happy
self.state = "leaving";
tween(self, {
alpha: 0
}, {
duration: 1000,
onFinish: function onFinish() {
self.readyToRemove = true;
}
});
// Calculate money earned from this customer
var baseSpending = self.spending * self.productsBought;
var happinessBonus = baseSpending * self.happiness * 0.5;
self.moneySpent = Math.floor(baseSpending + happinessBonus);
return self.moneySpent;
}
return 0; // No money yet, still shopping
}
return 0; // No products available
};
return self;
});
var Product = Container.expand(function () {
var self = Container.call(this);
var productGraphics = self.attachAsset('product', {
anchorX: 0.5,
anchorY: 0.5
});
// Randomize product appearance a bit
var colors = [0x33cc33, 0xcc3333, 0x3333cc, 0xcccc33];
productGraphics.tint = colors[Math.floor(Math.random() * colors.length)];
return self;
});
var Store = Container.expand(function () {
var self = Container.call(this);
var storeGraphics = self.attachAsset('store', {
anchorX: 0.5,
anchorY: 0.5
});
self.level = storage.storeLevel || 1;
self.capacity = 5 + self.level * 3;
self.customerCapacity = 2 + Math.floor(self.level * 1.5);
self.customerSatisfaction = 0.8;
// Visual indicators
self.levelBadge = self.attachAsset('upgradeBadge', {
anchorX: 0.5,
anchorY: 0.5,
x: storeGraphics.width / 2 - 25,
y: -storeGraphics.height / 2 + 25
});
self.levelText = new Text2(self.level.toString(), {
size: 30,
fill: 0xFFFFFF
});
self.levelText.anchor.set(0.5, 0.5);
self.levelText.x = self.levelBadge.x;
self.levelText.y = self.levelBadge.y;
self.addChild(self.levelText);
self.updateAppearance = function () {
// Update store appearance based on level
var newWidth = 400 + self.level * 50;
var newHeight = 300 + self.level * 30;
tween(storeGraphics, {
width: newWidth,
height: newHeight
}, {
duration: 500,
easing: tween.easeOut
});
// Update tint based on store level
var baseTint = 0x80c0ff;
var levelBonus = Math.min(self.level * 0x001100, 0x7F0000);
storeGraphics.tint = baseTint + levelBonus;
// Update capacity values
self.capacity = 5 + self.level * 3;
self.customerCapacity = 2 + Math.floor(self.level * 1.5);
// Update level indicator
self.levelText.setText(self.level.toString());
};
self.upgrade = function () {
if (self.level < 10) {
// Maximum level cap
self.level++;
storage.storeLevel = self.level;
self.updateAppearance();
return true;
}
return false;
};
// Initialize appearance
self.updateAppearance();
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x87CEEB // Sky blue background
});
/****
* Game Code
****/
// Game constants
var PRODUCT_COST = 50;
var PRODUCT_PRICE = 100;
var STORE_UPGRADE_BASE_COST = 1000;
var STAFF_COST = 500;
var STAFF_DAILY_WAGE = 100;
var DAILY_EXPENSES = 200;
// Game state variables
var money = storage.money || 1000;
var products = storage.products || 3;
var customers = [];
var particles = [];
var dayCounter = storage.day || 1;
var staffCount = storage.staff || 0;
var priceMultiplier = storage.priceMultiplier || 1.0;
var customerChance = 0.02; // Chance of a new customer per frame
var lastDayTimestamp = storage.lastSave || Date.now();
// UI Elements
var moneyText = new Text2("$" + money, {
size: 60,
fill: 0xFFFFFF
});
moneyText.anchor.set(0, 0);
LK.gui.topRight.addChild(moneyText);
var dayText = new Text2("Day " + dayCounter, {
size: 40,
fill: 0xFFFFFF
});
dayText.anchor.set(0.5, 0);
LK.gui.top.addChild(dayText);
var productsText = new Text2("Products: " + products, {
size: 40,
fill: 0xFFFFFF
});
productsText.anchor.set(0, 0);
productsText.y = 70;
LK.gui.topRight.addChild(productsText);
var customersText = new Text2("Customers: 0", {
size: 40,
fill: 0xFFFFFF
});
customersText.anchor.set(0, 0);
customersText.y = 120;
LK.gui.topRight.addChild(customersText);
var staffText = new Text2("Staff: " + staffCount, {
size: 40,
fill: 0xFFFFFF
});
staffText.anchor.set(0, 0);
staffText.y = 170;
LK.gui.topRight.addChild(staffText);
// Store and tiles
var store = new Store();
store.x = 2048 / 2;
store.y = 2732 / 2 - 200;
game.addChild(store);
// Create floor tiles
var tiles = [];
for (var x = 0; x < 20; x++) {
for (var y = 0; y < 10; y++) {
var tile = LK.getAsset('tile', {
anchorX: 0.5,
anchorY: 0.5,
x: 100 + x * 100,
y: 1800 + y * 100,
alpha: 0.5 + (x + y) % 2 * 0.1
});
game.addChild(tile);
tiles.push(tile);
}
}
// Create action buttons
var buyProductButton = new Button("Buy Product\n($" + PRODUCT_COST + ")", 300, 100);
buyProductButton.x = 300;
buyProductButton.y = 2732 - 200;
game.addChild(buyProductButton);
var hireStaffButton = new Button("Hire Staff\n($" + STAFF_COST + ")", 300, 100);
hireStaffButton.x = 650;
hireStaffButton.y = 2732 - 200;
game.addChild(hireStaffButton);
var adjustPriceButton = new Button("Price: x" + priceMultiplier.toFixed(1), 300, 100);
adjustPriceButton.x = 1000;
adjustPriceButton.y = 2732 - 200;
game.addChild(adjustPriceButton);
var upgradeStoreButton = new Button("Upgrade Store\n($" + getUpgradeCost() + ")", 300, 100);
upgradeStoreButton.x = 1350;
upgradeStoreButton.y = 2732 - 200;
game.addChild(upgradeStoreButton);
var newDayButton = new Button("Start New Day", 300, 100);
newDayButton.x = 1700;
newDayButton.y = 2732 - 200;
game.addChild(newDayButton);
// Function to get the upgrade cost based on current store level
function getUpgradeCost() {
return STORE_UPGRADE_BASE_COST * Math.pow(1.5, store.level - 1);
}
// Button event handlers
buyProductButton.down = function () {
Button.prototype.down.call(this);
};
buyProductButton.up = function () {
Button.prototype.up.call(this);
if (money >= PRODUCT_COST) {
money -= PRODUCT_COST;
products++;
storage.products = products;
storage.money = money;
updateUI();
// Visual feedback - spawn a product at the button location that moves to the store
var newProduct = new Product();
newProduct.x = buyProductButton.x;
newProduct.y = buyProductButton.y;
game.addChild(newProduct);
tween(newProduct, {
x: store.x,
y: store.y
}, {
duration: 800,
easing: tween.easeInOut,
onFinish: function onFinish() {
LK.effects.flashObject(store, 0x00ff00, 500);
newProduct.destroy();
}
});
}
};
hireStaffButton.down = function () {
Button.prototype.down.call(this);
};
hireStaffButton.up = function () {
Button.prototype.up.call(this);
if (money >= STAFF_COST) {
money -= STAFF_COST;
staffCount++;
storage.staff = staffCount;
storage.money = money;
updateUI();
// Increase customer handling capacity
customerChance += 0.005;
}
};
adjustPriceButton.down = function () {
Button.prototype.down.call(this);
};
adjustPriceButton.up = function () {
Button.prototype.up.call(this);
priceMultiplier = parseFloat((priceMultiplier + 0.1).toFixed(1));
if (priceMultiplier > 2.0) {
priceMultiplier = 0.8;
}
storage.priceMultiplier = priceMultiplier;
adjustPriceButton.setText("Price: x" + priceMultiplier.toFixed(1));
};
upgradeStoreButton.down = function () {
Button.prototype.down.call(this);
};
upgradeStoreButton.up = function () {
Button.prototype.up.call(this);
var upgradeCost = getUpgradeCost();
if (money >= upgradeCost) {
money -= upgradeCost;
storage.money = money;
if (store.upgrade()) {
LK.effects.flashObject(store, 0xffff00, 1000);
upgradeStoreButton.setText("Upgrade Store\n($" + getUpgradeCost() + ")");
updateUI();
}
}
};
newDayButton.down = function () {
Button.prototype.down.call(this);
};
newDayButton.up = function () {
Button.prototype.up.call(this);
// Calculate daily expenses
var dailyExpenses = DAILY_EXPENSES + staffCount * STAFF_DAILY_WAGE;
// Check if player can afford to start a new day
if (money >= dailyExpenses) {
money -= dailyExpenses;
dayCounter++;
storage.day = dayCounter;
storage.money = money;
storage.lastSave = Date.now();
// Remove all customers
for (var i = customers.length - 1; i >= 0; i--) {
customers[i].destroy();
}
customers = [];
// Show day summary
var summaryText = "Day " + (dayCounter - 1) + " Complete!\n\n";
summaryText += "Daily Expenses: $" + dailyExpenses + "\n";
summaryText += "New Balance: $" + money + "\n\n";
summaryText += "Starting Day " + dayCounter;
var dayInfoText = new Text2(summaryText, {
size: 40,
fill: 0xFFFFFF
});
dayInfoText.anchor.set(0.5, 0.5);
dayInfoText.x = 2048 / 2;
dayInfoText.y = 2732 / 2;
LK.gui.center.addChild(dayInfoText);
// Add background for better visibility
var infoBg = LK.getAsset('btnBg', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2,
y: 2732 / 2,
width: 800,
height: 400,
alpha: 0.8
});
infoBg.tint = 0x000000;
LK.gui.center.addChild(infoBg);
LK.gui.center.swapChildren(infoBg, dayInfoText);
// Remove the info after 3 seconds
LK.setTimeout(function () {
tween(dayInfoText, {
alpha: 0
}, {
duration: 500,
onFinish: function onFinish() {
LK.gui.center.removeChild(dayInfoText);
LK.gui.center.removeChild(infoBg);
}
});
tween(infoBg, {
alpha: 0
}, {
duration: 500
});
}, 3000);
updateUI();
} else {
// Show "not enough money" notification
var errorText = new Text2("Not enough money!\nYou need $" + dailyExpenses + " for daily expenses.", {
size: 40,
fill: 0xFF0000
});
errorText.anchor.set(0.5, 0.5);
errorText.x = 2048 / 2;
errorText.y = 2732 / 2;
LK.gui.center.addChild(errorText);
// Add background for better visibility
var errorBg = LK.getAsset('btnBg', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2,
y: 2732 / 2,
width: 600,
height: 200,
alpha: 0.8
});
errorBg.tint = 0x000000;
LK.gui.center.addChild(errorBg);
LK.gui.center.swapChildren(errorBg, errorText);
// Remove the error after 2 seconds
LK.setTimeout(function () {
tween(errorText, {
alpha: 0
}, {
duration: 500,
onFinish: function onFinish() {
LK.gui.center.removeChild(errorText);
LK.gui.center.removeChild(errorBg);
}
});
tween(errorBg, {
alpha: 0
}, {
duration: 500
});
}, 2000);
}
};
// Update UI elements
function updateUI() {
moneyText.setText("$" + money);
productsText.setText("Products: " + products);
customersText.setText("Customers: " + customers.length);
staffText.setText("Staff: " + staffCount);
dayText.setText("Day " + dayCounter);
// Update button states based on available money
buyProductButton.setEnabled(money >= PRODUCT_COST);
hireStaffButton.setEnabled(money >= STAFF_COST);
upgradeStoreButton.setEnabled(money >= getUpgradeCost());
// Update button texts that show costs
buyProductButton.setText("Buy Product\n($" + PRODUCT_COST + ")");
hireStaffButton.setText("Hire Staff\n($" + STAFF_COST + ")");
upgradeStoreButton.setText("Upgrade Store\n($" + getUpgradeCost() + ")");
}
// Function to spawn a new customer
function spawnCustomer() {
if (customers.length < store.customerCapacity) {
var customer = new Customer();
// Start off-screen
customer.x = -100 + Math.random() * 200;
customer.y = 1700 + Math.random() * 200;
customer.alpha = 0;
game.addChild(customer);
customers.push(customer);
// Animate customer entering
tween(customer, {
x: 200 + Math.random() * (2048 - 400),
y: 1500 + Math.random() * 300,
alpha: 1
}, {
duration: 1000,
onFinish: function onFinish() {
customer.state = "shopping";
LK.getSound('customer_enter').play();
}
});
updateUI();
}
}
// Function to process customer shopping
function processCustomers() {
for (var i = customers.length - 1; i >= 0; i--) {
var customer = customers[i];
if (customer.readyToRemove) {
customer.destroy();
customers.splice(i, 1);
updateUI();
continue;
}
if (customer.state === "shopping" && products > 0) {
// Calculate autoservice probability based on staff
var serviceChance = 0.01 + staffCount * 0.01;
if (Math.random() < serviceChance) {
// Customer buys a product
products--;
storage.products = products;
var earnings = customer.shop(products);
if (earnings > 0) {
// Apply price multiplier to earnings
var actualEarnings = Math.floor(earnings * priceMultiplier);
money += actualEarnings;
storage.money = money;
// Play cash register sound
LK.getSound('purchase').play();
// Spawn cash particles
spawnCashParticles(customer.x, customer.y, actualEarnings);
updateUI();
}
}
}
}
}
// Function to spawn cash particles for visual feedback
function spawnCashParticles(x, y, amount) {
var particleCount = Math.min(10, Math.max(3, Math.floor(amount / 20)));
for (var i = 0; i < particleCount; i++) {
var particle = new CashParticle();
particle.x = x;
particle.y = y;
game.addChild(particle);
particles.push(particle);
}
}
// Check for game over condition
function checkGameOver() {
if (money < DAILY_EXPENSES && products === 0 && customers.length === 0) {
// Player is bankrupt and has no assets
LK.showGameOver();
}
}
// Check for time-based events (new day)
function checkTimeBasedEvents() {
var currentTime = Date.now();
var hoursPassed = (currentTime - lastDayTimestamp) / (1000 * 60 * 60);
// If real world time passed is more than 1 hour, add a free product
if (hoursPassed >= 1) {
products++;
storage.products = products;
updateUI();
// Reset timestamp
lastDayTimestamp = currentTime;
storage.lastSave = lastDayTimestamp;
}
}
// Initialize UI
updateUI();
// Play background music
LK.playMusic('bgmusic', {
loop: true,
fade: {
start: 0,
end: 0.3,
duration: 1000
}
});
// Game update loop
game.update = function () {
// Process customers
for (var i = 0; i < customers.length; i++) {
customers[i].update();
}
// Update particles
for (var j = particles.length - 1; j >= 0; j--) {
particles[j].update();
if (particles[j].readyToRemove) {
particles[j].destroy();
particles.splice(j, 1);
}
}
// Spawn customers based on chance
if (Math.random() < customerChance && customers.length < store.customerCapacity) {
spawnCustomer();
}
// Process customer shopping
processCustomers();
// Check time-based events
if (LK.ticks % 300 === 0) {
// Check every 5 seconds
checkTimeBasedEvents();
}
// Check for game over
if (LK.ticks % 180 === 0) {
// Check every 3 seconds
checkGameOver();
// Auto-save game state
storage.money = money;
storage.products = products;
storage.day = dayCounter;
storage.staff = staffCount;
storage.priceMultiplier = priceMultiplier;
storage.storeLevel = store.level;
}
};
// Prevent placing UI elements in the top-left corner (reserved for menu)
game.down = function (x, y, obj) {
// Nothing to do here, buttons handle their own events
};
game.up = function (x, y, obj) {
// Nothing to do here, buttons handle their own events
};
game.move = function (x, y, obj) {
// Nothing to do here, no dragging in this game
}; ===================================================================
--- original.js
+++ change.js
@@ -1,6 +1,669 @@
-/****
+/****
+* Plugins
+****/
+var tween = LK.import("@upit/tween.v1");
+var storage = LK.import("@upit/storage.v1", {
+ money: 1000,
+ day: 1,
+ products: 3,
+ customers: 0,
+ staff: 0,
+ storeLevel: 1,
+ priceMultiplier: 1,
+ lastSave: undefined
+});
+
+/****
+* Classes
+****/
+var Button = Container.expand(function (text, width, height) {
+ var self = Container.call(this);
+ width = width || 300;
+ height = height || 80;
+ var buttonBg = self.attachAsset('btnBg', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ width: width,
+ height: height
+ });
+ var buttonText = new Text2(text, {
+ size: 40,
+ fill: 0xFFFFFF
+ });
+ buttonText.anchor.set(0.5, 0.5);
+ self.addChild(buttonText);
+ self.down = function () {
+ tween(buttonBg, {
+ scaleX: 0.95,
+ scaleY: 0.95
+ }, {
+ duration: 100
+ });
+ };
+ self.up = function () {
+ tween(buttonBg, {
+ scaleX: 1,
+ scaleY: 1
+ }, {
+ duration: 100
+ });
+ };
+ self.setText = function (newText) {
+ buttonText.setText(newText);
+ };
+ self.setEnabled = function (enabled) {
+ self.interactive = enabled;
+ buttonBg.alpha = enabled ? 1.0 : 0.5;
+ };
+ self.setEnabled(true);
+ return self;
+});
+var CashParticle = Container.expand(function () {
+ var self = Container.call(this);
+ var cashGraphics = self.attachAsset('cash', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ self.vx = (Math.random() - 0.5) * 10;
+ self.vy = -5 - Math.random() * 10;
+ self.gravity = 0.5;
+ self.lifespan = 60; // 1 second at 60fps
+ self.update = function () {
+ self.x += self.vx;
+ self.vy += self.gravity;
+ self.y += self.vy;
+ self.lifespan--;
+ if (self.lifespan <= 0) {
+ self.readyToRemove = true;
+ }
+ };
+ return self;
+});
+var Customer = Container.expand(function () {
+ var self = Container.call(this);
+ var customerGraphics = self.attachAsset('customer', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ // Customer properties
+ self.patience = 60 + Math.random() * 180; // 1-4 seconds patience (60fps)
+ self.waitTime = 0;
+ self.spending = 20 + Math.floor(Math.random() * 80); // How much they want to spend
+ self.targetProducts = 1 + Math.floor(Math.random() * 2); // How many products they want to buy
+ self.productsBought = 0;
+ self.state = "entering"; // entering, shopping, leaving
+ self.happiness = 1.0; // 0.0 to 1.0
+ // Personalization - random tint
+ var randomHue = Math.random() * 0x1000000;
+ customerGraphics.tint = randomHue;
+ self.update = function () {
+ if (self.state === "shopping") {
+ self.waitTime++;
+ // Decrease happiness as they wait
+ self.happiness = Math.max(0, 1 - self.waitTime / self.patience);
+ // Visual feedback - customer turns redder as they get impatient
+ var redTint = Math.floor(0xff0000 * (1 - self.happiness));
+ customerGraphics.tint = 0xffffff - redTint;
+ // Customer leaves if too impatient
+ if (self.waitTime >= self.patience) {
+ self.state = "leaving";
+ tween(self, {
+ alpha: 0
+ }, {
+ duration: 1000,
+ onFinish: function onFinish() {
+ self.readyToRemove = true;
+ }
+ });
+ }
+ }
+ };
+ self.shop = function (availableProducts) {
+ if (availableProducts > 0 && self.productsBought < self.targetProducts) {
+ self.productsBought++;
+ // Flash the customer when they buy something
+ LK.effects.flashObject(self, 0x00ff00, 500);
+ if (self.productsBought >= self.targetProducts) {
+ // Customer satisfied, will leave happy
+ self.state = "leaving";
+ tween(self, {
+ alpha: 0
+ }, {
+ duration: 1000,
+ onFinish: function onFinish() {
+ self.readyToRemove = true;
+ }
+ });
+ // Calculate money earned from this customer
+ var baseSpending = self.spending * self.productsBought;
+ var happinessBonus = baseSpending * self.happiness * 0.5;
+ self.moneySpent = Math.floor(baseSpending + happinessBonus);
+ return self.moneySpent;
+ }
+ return 0; // No money yet, still shopping
+ }
+ return 0; // No products available
+ };
+ return self;
+});
+var Product = Container.expand(function () {
+ var self = Container.call(this);
+ var productGraphics = self.attachAsset('product', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ // Randomize product appearance a bit
+ var colors = [0x33cc33, 0xcc3333, 0x3333cc, 0xcccc33];
+ productGraphics.tint = colors[Math.floor(Math.random() * colors.length)];
+ return self;
+});
+var Store = Container.expand(function () {
+ var self = Container.call(this);
+ var storeGraphics = self.attachAsset('store', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ self.level = storage.storeLevel || 1;
+ self.capacity = 5 + self.level * 3;
+ self.customerCapacity = 2 + Math.floor(self.level * 1.5);
+ self.customerSatisfaction = 0.8;
+ // Visual indicators
+ self.levelBadge = self.attachAsset('upgradeBadge', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ x: storeGraphics.width / 2 - 25,
+ y: -storeGraphics.height / 2 + 25
+ });
+ self.levelText = new Text2(self.level.toString(), {
+ size: 30,
+ fill: 0xFFFFFF
+ });
+ self.levelText.anchor.set(0.5, 0.5);
+ self.levelText.x = self.levelBadge.x;
+ self.levelText.y = self.levelBadge.y;
+ self.addChild(self.levelText);
+ self.updateAppearance = function () {
+ // Update store appearance based on level
+ var newWidth = 400 + self.level * 50;
+ var newHeight = 300 + self.level * 30;
+ tween(storeGraphics, {
+ width: newWidth,
+ height: newHeight
+ }, {
+ duration: 500,
+ easing: tween.easeOut
+ });
+ // Update tint based on store level
+ var baseTint = 0x80c0ff;
+ var levelBonus = Math.min(self.level * 0x001100, 0x7F0000);
+ storeGraphics.tint = baseTint + levelBonus;
+ // Update capacity values
+ self.capacity = 5 + self.level * 3;
+ self.customerCapacity = 2 + Math.floor(self.level * 1.5);
+ // Update level indicator
+ self.levelText.setText(self.level.toString());
+ };
+ self.upgrade = function () {
+ if (self.level < 10) {
+ // Maximum level cap
+ self.level++;
+ storage.storeLevel = self.level;
+ self.updateAppearance();
+ return true;
+ }
+ return false;
+ };
+ // Initialize appearance
+ self.updateAppearance();
+ return self;
+});
+
+/****
* Initialize Game
-****/
+****/
var game = new LK.Game({
- backgroundColor: 0x000000
-});
\ No newline at end of file
+ backgroundColor: 0x87CEEB // Sky blue background
+});
+
+/****
+* Game Code
+****/
+// Game constants
+var PRODUCT_COST = 50;
+var PRODUCT_PRICE = 100;
+var STORE_UPGRADE_BASE_COST = 1000;
+var STAFF_COST = 500;
+var STAFF_DAILY_WAGE = 100;
+var DAILY_EXPENSES = 200;
+// Game state variables
+var money = storage.money || 1000;
+var products = storage.products || 3;
+var customers = [];
+var particles = [];
+var dayCounter = storage.day || 1;
+var staffCount = storage.staff || 0;
+var priceMultiplier = storage.priceMultiplier || 1.0;
+var customerChance = 0.02; // Chance of a new customer per frame
+var lastDayTimestamp = storage.lastSave || Date.now();
+// UI Elements
+var moneyText = new Text2("$" + money, {
+ size: 60,
+ fill: 0xFFFFFF
+});
+moneyText.anchor.set(0, 0);
+LK.gui.topRight.addChild(moneyText);
+var dayText = new Text2("Day " + dayCounter, {
+ size: 40,
+ fill: 0xFFFFFF
+});
+dayText.anchor.set(0.5, 0);
+LK.gui.top.addChild(dayText);
+var productsText = new Text2("Products: " + products, {
+ size: 40,
+ fill: 0xFFFFFF
+});
+productsText.anchor.set(0, 0);
+productsText.y = 70;
+LK.gui.topRight.addChild(productsText);
+var customersText = new Text2("Customers: 0", {
+ size: 40,
+ fill: 0xFFFFFF
+});
+customersText.anchor.set(0, 0);
+customersText.y = 120;
+LK.gui.topRight.addChild(customersText);
+var staffText = new Text2("Staff: " + staffCount, {
+ size: 40,
+ fill: 0xFFFFFF
+});
+staffText.anchor.set(0, 0);
+staffText.y = 170;
+LK.gui.topRight.addChild(staffText);
+// Store and tiles
+var store = new Store();
+store.x = 2048 / 2;
+store.y = 2732 / 2 - 200;
+game.addChild(store);
+// Create floor tiles
+var tiles = [];
+for (var x = 0; x < 20; x++) {
+ for (var y = 0; y < 10; y++) {
+ var tile = LK.getAsset('tile', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ x: 100 + x * 100,
+ y: 1800 + y * 100,
+ alpha: 0.5 + (x + y) % 2 * 0.1
+ });
+ game.addChild(tile);
+ tiles.push(tile);
+ }
+}
+// Create action buttons
+var buyProductButton = new Button("Buy Product\n($" + PRODUCT_COST + ")", 300, 100);
+buyProductButton.x = 300;
+buyProductButton.y = 2732 - 200;
+game.addChild(buyProductButton);
+var hireStaffButton = new Button("Hire Staff\n($" + STAFF_COST + ")", 300, 100);
+hireStaffButton.x = 650;
+hireStaffButton.y = 2732 - 200;
+game.addChild(hireStaffButton);
+var adjustPriceButton = new Button("Price: x" + priceMultiplier.toFixed(1), 300, 100);
+adjustPriceButton.x = 1000;
+adjustPriceButton.y = 2732 - 200;
+game.addChild(adjustPriceButton);
+var upgradeStoreButton = new Button("Upgrade Store\n($" + getUpgradeCost() + ")", 300, 100);
+upgradeStoreButton.x = 1350;
+upgradeStoreButton.y = 2732 - 200;
+game.addChild(upgradeStoreButton);
+var newDayButton = new Button("Start New Day", 300, 100);
+newDayButton.x = 1700;
+newDayButton.y = 2732 - 200;
+game.addChild(newDayButton);
+// Function to get the upgrade cost based on current store level
+function getUpgradeCost() {
+ return STORE_UPGRADE_BASE_COST * Math.pow(1.5, store.level - 1);
+}
+// Button event handlers
+buyProductButton.down = function () {
+ Button.prototype.down.call(this);
+};
+buyProductButton.up = function () {
+ Button.prototype.up.call(this);
+ if (money >= PRODUCT_COST) {
+ money -= PRODUCT_COST;
+ products++;
+ storage.products = products;
+ storage.money = money;
+ updateUI();
+ // Visual feedback - spawn a product at the button location that moves to the store
+ var newProduct = new Product();
+ newProduct.x = buyProductButton.x;
+ newProduct.y = buyProductButton.y;
+ game.addChild(newProduct);
+ tween(newProduct, {
+ x: store.x,
+ y: store.y
+ }, {
+ duration: 800,
+ easing: tween.easeInOut,
+ onFinish: function onFinish() {
+ LK.effects.flashObject(store, 0x00ff00, 500);
+ newProduct.destroy();
+ }
+ });
+ }
+};
+hireStaffButton.down = function () {
+ Button.prototype.down.call(this);
+};
+hireStaffButton.up = function () {
+ Button.prototype.up.call(this);
+ if (money >= STAFF_COST) {
+ money -= STAFF_COST;
+ staffCount++;
+ storage.staff = staffCount;
+ storage.money = money;
+ updateUI();
+ // Increase customer handling capacity
+ customerChance += 0.005;
+ }
+};
+adjustPriceButton.down = function () {
+ Button.prototype.down.call(this);
+};
+adjustPriceButton.up = function () {
+ Button.prototype.up.call(this);
+ priceMultiplier = parseFloat((priceMultiplier + 0.1).toFixed(1));
+ if (priceMultiplier > 2.0) {
+ priceMultiplier = 0.8;
+ }
+ storage.priceMultiplier = priceMultiplier;
+ adjustPriceButton.setText("Price: x" + priceMultiplier.toFixed(1));
+};
+upgradeStoreButton.down = function () {
+ Button.prototype.down.call(this);
+};
+upgradeStoreButton.up = function () {
+ Button.prototype.up.call(this);
+ var upgradeCost = getUpgradeCost();
+ if (money >= upgradeCost) {
+ money -= upgradeCost;
+ storage.money = money;
+ if (store.upgrade()) {
+ LK.effects.flashObject(store, 0xffff00, 1000);
+ upgradeStoreButton.setText("Upgrade Store\n($" + getUpgradeCost() + ")");
+ updateUI();
+ }
+ }
+};
+newDayButton.down = function () {
+ Button.prototype.down.call(this);
+};
+newDayButton.up = function () {
+ Button.prototype.up.call(this);
+ // Calculate daily expenses
+ var dailyExpenses = DAILY_EXPENSES + staffCount * STAFF_DAILY_WAGE;
+ // Check if player can afford to start a new day
+ if (money >= dailyExpenses) {
+ money -= dailyExpenses;
+ dayCounter++;
+ storage.day = dayCounter;
+ storage.money = money;
+ storage.lastSave = Date.now();
+ // Remove all customers
+ for (var i = customers.length - 1; i >= 0; i--) {
+ customers[i].destroy();
+ }
+ customers = [];
+ // Show day summary
+ var summaryText = "Day " + (dayCounter - 1) + " Complete!\n\n";
+ summaryText += "Daily Expenses: $" + dailyExpenses + "\n";
+ summaryText += "New Balance: $" + money + "\n\n";
+ summaryText += "Starting Day " + dayCounter;
+ var dayInfoText = new Text2(summaryText, {
+ size: 40,
+ fill: 0xFFFFFF
+ });
+ dayInfoText.anchor.set(0.5, 0.5);
+ dayInfoText.x = 2048 / 2;
+ dayInfoText.y = 2732 / 2;
+ LK.gui.center.addChild(dayInfoText);
+ // Add background for better visibility
+ var infoBg = LK.getAsset('btnBg', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ x: 2048 / 2,
+ y: 2732 / 2,
+ width: 800,
+ height: 400,
+ alpha: 0.8
+ });
+ infoBg.tint = 0x000000;
+ LK.gui.center.addChild(infoBg);
+ LK.gui.center.swapChildren(infoBg, dayInfoText);
+ // Remove the info after 3 seconds
+ LK.setTimeout(function () {
+ tween(dayInfoText, {
+ alpha: 0
+ }, {
+ duration: 500,
+ onFinish: function onFinish() {
+ LK.gui.center.removeChild(dayInfoText);
+ LK.gui.center.removeChild(infoBg);
+ }
+ });
+ tween(infoBg, {
+ alpha: 0
+ }, {
+ duration: 500
+ });
+ }, 3000);
+ updateUI();
+ } else {
+ // Show "not enough money" notification
+ var errorText = new Text2("Not enough money!\nYou need $" + dailyExpenses + " for daily expenses.", {
+ size: 40,
+ fill: 0xFF0000
+ });
+ errorText.anchor.set(0.5, 0.5);
+ errorText.x = 2048 / 2;
+ errorText.y = 2732 / 2;
+ LK.gui.center.addChild(errorText);
+ // Add background for better visibility
+ var errorBg = LK.getAsset('btnBg', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ x: 2048 / 2,
+ y: 2732 / 2,
+ width: 600,
+ height: 200,
+ alpha: 0.8
+ });
+ errorBg.tint = 0x000000;
+ LK.gui.center.addChild(errorBg);
+ LK.gui.center.swapChildren(errorBg, errorText);
+ // Remove the error after 2 seconds
+ LK.setTimeout(function () {
+ tween(errorText, {
+ alpha: 0
+ }, {
+ duration: 500,
+ onFinish: function onFinish() {
+ LK.gui.center.removeChild(errorText);
+ LK.gui.center.removeChild(errorBg);
+ }
+ });
+ tween(errorBg, {
+ alpha: 0
+ }, {
+ duration: 500
+ });
+ }, 2000);
+ }
+};
+// Update UI elements
+function updateUI() {
+ moneyText.setText("$" + money);
+ productsText.setText("Products: " + products);
+ customersText.setText("Customers: " + customers.length);
+ staffText.setText("Staff: " + staffCount);
+ dayText.setText("Day " + dayCounter);
+ // Update button states based on available money
+ buyProductButton.setEnabled(money >= PRODUCT_COST);
+ hireStaffButton.setEnabled(money >= STAFF_COST);
+ upgradeStoreButton.setEnabled(money >= getUpgradeCost());
+ // Update button texts that show costs
+ buyProductButton.setText("Buy Product\n($" + PRODUCT_COST + ")");
+ hireStaffButton.setText("Hire Staff\n($" + STAFF_COST + ")");
+ upgradeStoreButton.setText("Upgrade Store\n($" + getUpgradeCost() + ")");
+}
+// Function to spawn a new customer
+function spawnCustomer() {
+ if (customers.length < store.customerCapacity) {
+ var customer = new Customer();
+ // Start off-screen
+ customer.x = -100 + Math.random() * 200;
+ customer.y = 1700 + Math.random() * 200;
+ customer.alpha = 0;
+ game.addChild(customer);
+ customers.push(customer);
+ // Animate customer entering
+ tween(customer, {
+ x: 200 + Math.random() * (2048 - 400),
+ y: 1500 + Math.random() * 300,
+ alpha: 1
+ }, {
+ duration: 1000,
+ onFinish: function onFinish() {
+ customer.state = "shopping";
+ LK.getSound('customer_enter').play();
+ }
+ });
+ updateUI();
+ }
+}
+// Function to process customer shopping
+function processCustomers() {
+ for (var i = customers.length - 1; i >= 0; i--) {
+ var customer = customers[i];
+ if (customer.readyToRemove) {
+ customer.destroy();
+ customers.splice(i, 1);
+ updateUI();
+ continue;
+ }
+ if (customer.state === "shopping" && products > 0) {
+ // Calculate autoservice probability based on staff
+ var serviceChance = 0.01 + staffCount * 0.01;
+ if (Math.random() < serviceChance) {
+ // Customer buys a product
+ products--;
+ storage.products = products;
+ var earnings = customer.shop(products);
+ if (earnings > 0) {
+ // Apply price multiplier to earnings
+ var actualEarnings = Math.floor(earnings * priceMultiplier);
+ money += actualEarnings;
+ storage.money = money;
+ // Play cash register sound
+ LK.getSound('purchase').play();
+ // Spawn cash particles
+ spawnCashParticles(customer.x, customer.y, actualEarnings);
+ updateUI();
+ }
+ }
+ }
+ }
+}
+// Function to spawn cash particles for visual feedback
+function spawnCashParticles(x, y, amount) {
+ var particleCount = Math.min(10, Math.max(3, Math.floor(amount / 20)));
+ for (var i = 0; i < particleCount; i++) {
+ var particle = new CashParticle();
+ particle.x = x;
+ particle.y = y;
+ game.addChild(particle);
+ particles.push(particle);
+ }
+}
+// Check for game over condition
+function checkGameOver() {
+ if (money < DAILY_EXPENSES && products === 0 && customers.length === 0) {
+ // Player is bankrupt and has no assets
+ LK.showGameOver();
+ }
+}
+// Check for time-based events (new day)
+function checkTimeBasedEvents() {
+ var currentTime = Date.now();
+ var hoursPassed = (currentTime - lastDayTimestamp) / (1000 * 60 * 60);
+ // If real world time passed is more than 1 hour, add a free product
+ if (hoursPassed >= 1) {
+ products++;
+ storage.products = products;
+ updateUI();
+ // Reset timestamp
+ lastDayTimestamp = currentTime;
+ storage.lastSave = lastDayTimestamp;
+ }
+}
+// Initialize UI
+updateUI();
+// Play background music
+LK.playMusic('bgmusic', {
+ loop: true,
+ fade: {
+ start: 0,
+ end: 0.3,
+ duration: 1000
+ }
+});
+// Game update loop
+game.update = function () {
+ // Process customers
+ for (var i = 0; i < customers.length; i++) {
+ customers[i].update();
+ }
+ // Update particles
+ for (var j = particles.length - 1; j >= 0; j--) {
+ particles[j].update();
+ if (particles[j].readyToRemove) {
+ particles[j].destroy();
+ particles.splice(j, 1);
+ }
+ }
+ // Spawn customers based on chance
+ if (Math.random() < customerChance && customers.length < store.customerCapacity) {
+ spawnCustomer();
+ }
+ // Process customer shopping
+ processCustomers();
+ // Check time-based events
+ if (LK.ticks % 300 === 0) {
+ // Check every 5 seconds
+ checkTimeBasedEvents();
+ }
+ // Check for game over
+ if (LK.ticks % 180 === 0) {
+ // Check every 3 seconds
+ checkGameOver();
+ // Auto-save game state
+ storage.money = money;
+ storage.products = products;
+ storage.day = dayCounter;
+ storage.staff = staffCount;
+ storage.priceMultiplier = priceMultiplier;
+ storage.storeLevel = store.level;
+ }
+};
+// Prevent placing UI elements in the top-left corner (reserved for menu)
+game.down = function (x, y, obj) {
+ // Nothing to do here, buttons handle their own events
+};
+game.up = function (x, y, obj) {
+ // Nothing to do here, buttons handle their own events
+};
+game.move = function (x, y, obj) {
+ // Nothing to do here, no dragging in this game
+};
\ No newline at end of file