/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var storage = LK.import("@upit/storage.v1", { money: 0, clickValue: 1, clickUpgradeCost: 50, passiveIncome: 0, passiveUpgradeCost: 100 }); /**** * Classes ****/ // Passive Income Upgrade Button var PassiveButton = Container.expand(function () { var self = Container.call(this); var btn = self.attachAsset('passiveBtn', { anchorX: 0.5, anchorY: 0.5 }); var txt = new Text2('', { size: 44, fill: 0xFFFBE6 }); txt.anchor.set(0.5, 0.5); self.addChild(txt); function updateText() { txt.setText("Auto-Sell\n$" + storage.passiveUpgradeCost); } self.updateText = updateText; self.down = function (x, y, obj) { if (storage.money >= storage.passiveUpgradeCost) { storage.money -= storage.passiveUpgradeCost; storage.passiveIncome += 1; storage.passiveUpgradeCost = Math.floor(storage.passiveUpgradeCost * 1.7 + 20); updateMoneyDisplay(); updatePassiveDisplay(); updateUpgradeButtons(); // Animate tween(self, { scaleX: 1.1, scaleY: 1.1 }, { duration: 80, easing: tween.easeOut, onFinish: function onFinish() { tween(self, { scaleX: 1, scaleY: 1 }, { duration: 80, easing: tween.easeIn }); } }); LK.getSound('upgrade').play(); } else { // Subtle shake if not enough money tween(self, { x: self.x + 18 }, { duration: 60, easing: tween.easeIn, onFinish: function onFinish() { tween(self, { x: self.x - 36 }, { duration: 60, easing: tween.easeIn, onFinish: function onFinish() { tween(self, { x: self.x + 18 }, { duration: 60, easing: tween.easeOut }); } }); } }); } }; updateText(); return self; }); // Shoe Button (tap to sell) var ShoeButton = Container.expand(function () { var self = Container.call(this); var btn = self.attachAsset('shoeBtn', { anchorX: 0.5, anchorY: 0.5 }); // Decorative: subtle bounce on tap self.down = function (x, y, obj) { // Animate scale tween(self, { scaleX: 0.92, scaleY: 0.92 }, { duration: 60, easing: tween.easeIn, onFinish: function onFinish() { tween(self, { scaleX: 1, scaleY: 1 }, { duration: 80, easing: tween.easeOut }); } }); // Play sale sound LK.getSound('sale').play(); // Add money storage.money += storage.clickValue; updateMoneyDisplay(); // Subtle money icon pop popMoneyIcon(); }; return self; }); // Upgrade Button (tap to increase click value) var UpgradeButton = Container.expand(function () { var self = Container.call(this); var btn = self.attachAsset('upgradeBtn', { anchorX: 0.5, anchorY: 0.5 }); var txt = new Text2('', { size: 48, fill: 0xFFFBE6 }); txt.anchor.set(0.5, 0.5); self.addChild(txt); function updateText() { txt.setText("Upgrade\n$" + storage.clickUpgradeCost); } self.updateText = updateText; self.down = function (x, y, obj) { if (storage.money >= storage.clickUpgradeCost) { storage.money -= storage.clickUpgradeCost; storage.clickValue += 1; storage.clickUpgradeCost = Math.floor(storage.clickUpgradeCost * 1.5 + 10); updateMoneyDisplay(); updateClickValueDisplay(); updateUpgradeButtons(); // Animate tween(self, { scaleX: 1.1, scaleY: 1.1 }, { duration: 80, easing: tween.easeOut, onFinish: function onFinish() { tween(self, { scaleX: 1, scaleY: 1 }, { duration: 80, easing: tween.easeIn }); } }); LK.getSound('upgrade').play(); } else { // Subtle shake if not enough money tween(self, { x: self.x + 18 }, { duration: 60, easing: tween.easeIn, onFinish: function onFinish() { tween(self, { x: self.x - 36 }, { duration: 60, easing: tween.easeIn, onFinish: function onFinish() { tween(self, { x: self.x + 18 }, { duration: 60, easing: tween.easeOut }); } }); } }); } }; updateText(); return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0xede7d2 // Subtle vintage beige }); /**** * Game Code ****/ // Sound for upgrade // Sound for sale // Boutique background (subtle, not a full background, just a decorative element) // Money icon // Passive income upgrade button // Upgrade button // Main shoe button (luxury shoe) // Decorative boutique ellipse at top var boutiqueDeco = LK.getAsset('boutiqueDeco', { anchorX: 0.5, anchorY: 0, x: 2048 / 2, y: 0, scaleX: 1.1, scaleY: 1 }); game.addChild(boutiqueDeco); // Money display var moneyIcon = LK.getAsset('moneyIcon', { anchorX: 0.5, anchorY: 0.5, x: 2048 / 2 - 120, y: 120 }); moneyIcon.scaleX = 1.1; moneyIcon.scaleY = 1.1; game.addChild(moneyIcon); var moneyTxt = new Text2('', { size: 90, fill: 0x7C6F57 }); moneyTxt.anchor.set(0, 0.5); moneyTxt.x = 2048 / 2 - 60; moneyTxt.y = 120; game.addChild(moneyTxt); function formatMoney(val) { if (val >= 1e9) { return (val / 1e9).toFixed(2) + "B"; } if (val >= 1e6) { return (val / 1e6).toFixed(2) + "M"; } if (val >= 1e3) { return (val / 1e3).toFixed(1) + "K"; } return "" + Math.floor(val); } function updateMoneyDisplay() { moneyTxt.setText("$" + formatMoney(storage.money)); } function popMoneyIcon() { tween.stop(moneyIcon, { scaleX: true, scaleY: true }); moneyIcon.scaleX = 1.1; moneyIcon.scaleY = 1.1; tween(moneyIcon, { scaleX: 1.25, scaleY: 1.25 }, { duration: 60, easing: tween.easeOut, onFinish: function onFinish() { tween(moneyIcon, { scaleX: 1.1, scaleY: 1.1 }, { duration: 80, easing: tween.easeIn }); } }); } // Click value display var clickValueTxt = new Text2('', { size: 48, fill: 0x8B7B5A }); clickValueTxt.anchor.set(0.5, 0); clickValueTxt.x = 2048 / 2; clickValueTxt.y = 320; game.addChild(clickValueTxt); function updateClickValueDisplay() { clickValueTxt.setText("Per Tap: $" + formatMoney(storage.clickValue)); } // Passive income display var passiveTxt = new Text2('', { size: 44, fill: 0xB7A77A }); passiveTxt.anchor.set(0.5, 0); passiveTxt.x = 2048 / 2; passiveTxt.y = 390; game.addChild(passiveTxt); function updatePassiveDisplay() { if (storage.passiveIncome > 0) { passiveTxt.setText("Auto: $" + formatMoney(storage.passiveIncome) + "/sec"); } else { passiveTxt.setText("Auto: $0/sec"); } } // Main shoe button var shoeBtn = new ShoeButton(); shoeBtn.x = 2048 / 2; shoeBtn.y = 800; game.addChild(shoeBtn); // Upgrade buttons var upgradeBtn = new UpgradeButton(); upgradeBtn.x = 2048 / 2 - 220; upgradeBtn.y = 1200; game.addChild(upgradeBtn); var passiveBtn = new PassiveButton(); passiveBtn.x = 2048 / 2 + 220; passiveBtn.y = 1200; game.addChild(passiveBtn); function updateUpgradeButtons() { upgradeBtn.updateText(); passiveBtn.updateText(); } // --- START MENU IMPLEMENTATION --- var startMenuContainer = new Container(); var startBg = LK.getAsset('boutiqueDeco', { anchorX: 0.5, anchorY: 0.5, x: 2048 / 2, y: 2732 / 2, scaleX: 2.2, scaleY: 2.2 }); startMenuContainer.addChild(startBg); var startTitle = new Text2('SHOE TYCOON', { size: 120, fill: 0x7C6F57 }); startTitle.anchor.set(0.5, 0.5); startTitle.x = 2048 / 2; startTitle.y = 900; startMenuContainer.addChild(startTitle); var playBtn = LK.getAsset('upgradeBtn', { anchorX: 0.5, anchorY: 0.5, x: 2048 / 2, y: 1500, scaleX: 1.4, scaleY: 1.2 }); startMenuContainer.addChild(playBtn); var playTxt = new Text2('PLAY', { size: 80, fill: 0xFFFBE6 }); playTxt.anchor.set(0.5, 0.5); playTxt.x = 2048 / 2; playTxt.y = 1400; startMenuContainer.addChild(playTxt); game.addChild(startMenuContainer); // Hide all gameplay UI until play is pressed function setGameplayUIVisible(visible) { moneyIcon.visible = visible; moneyTxt.visible = visible; clickValueTxt.visible = visible; passiveTxt.visible = visible; shoeBtn.visible = visible; upgradeBtn.visible = visible; passiveBtn.visible = visible; boutiqueDeco.visible = visible; if (typeof titleTxt !== "undefined" && titleTxt) { titleTxt.visible = visible; } } setGameplayUIVisible(false); // Play button handler playBtn.interactive = true; playBtn.down = function (x, y, obj) { // Animate play button tween(playBtn, { scaleX: 1.2, scaleY: 1.1 }, { duration: 80, easing: tween.easeOut, onFinish: function onFinish() { tween(playBtn, { scaleX: 1.4, scaleY: 1.2 }, { duration: 80, easing: tween.easeIn }); } }); // Fade out menu tween(startMenuContainer, { alpha: 0 }, { duration: 220, easing: tween.easeIn, onFinish: function onFinish() { startMenuContainer.visible = false; setGameplayUIVisible(true); } }); }; // GUI Title var titleTxt = new Text2('SHOE TYCOON', { size: 100, fill: 0x7C6F57 }); titleTxt.anchor.set(0.5, 0); LK.gui.top.addChild(titleTxt); // Center title, but not in top left 100x100 titleTxt.x = LK.gui.top.width / 100; titleTxt.y = 1300; // Initial display update updateMoneyDisplay(); updateClickValueDisplay(); updatePassiveDisplay(); updateUpgradeButtons(); // Passive income timer var passiveTimer = LK.setInterval(function () { if (storage.passiveIncome > 0) { storage.money += storage.passiveIncome; updateMoneyDisplay(); popMoneyIcon(); } }, 1000); // Save progress every 2 seconds var saveTimer = LK.setInterval(function () { // Storage is auto-persistent, but we can force a write if needed // (No-op, but placeholder for future expansion) }, 2000); // Game update (not much needed, but could be used for future features) game.update = function () { // No per-frame logic needed for MVP }; // Clean up on game over (not strictly needed, but good practice) game.on('destroy', function () { LK.clearInterval(passiveTimer); LK.clearInterval(saveTimer); }); // Touch handling for shoeBtn and upgrade buttons // (Handled by their own .down methods, no need for game.down) // Prevent elements in top left 100x100 // (All elements are centered or offset from center, so this is satisfied);
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1", {
money: 0,
clickValue: 1,
clickUpgradeCost: 50,
passiveIncome: 0,
passiveUpgradeCost: 100
});
/****
* Classes
****/
// Passive Income Upgrade Button
var PassiveButton = Container.expand(function () {
var self = Container.call(this);
var btn = self.attachAsset('passiveBtn', {
anchorX: 0.5,
anchorY: 0.5
});
var txt = new Text2('', {
size: 44,
fill: 0xFFFBE6
});
txt.anchor.set(0.5, 0.5);
self.addChild(txt);
function updateText() {
txt.setText("Auto-Sell\n$" + storage.passiveUpgradeCost);
}
self.updateText = updateText;
self.down = function (x, y, obj) {
if (storage.money >= storage.passiveUpgradeCost) {
storage.money -= storage.passiveUpgradeCost;
storage.passiveIncome += 1;
storage.passiveUpgradeCost = Math.floor(storage.passiveUpgradeCost * 1.7 + 20);
updateMoneyDisplay();
updatePassiveDisplay();
updateUpgradeButtons();
// Animate
tween(self, {
scaleX: 1.1,
scaleY: 1.1
}, {
duration: 80,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(self, {
scaleX: 1,
scaleY: 1
}, {
duration: 80,
easing: tween.easeIn
});
}
});
LK.getSound('upgrade').play();
} else {
// Subtle shake if not enough money
tween(self, {
x: self.x + 18
}, {
duration: 60,
easing: tween.easeIn,
onFinish: function onFinish() {
tween(self, {
x: self.x - 36
}, {
duration: 60,
easing: tween.easeIn,
onFinish: function onFinish() {
tween(self, {
x: self.x + 18
}, {
duration: 60,
easing: tween.easeOut
});
}
});
}
});
}
};
updateText();
return self;
});
// Shoe Button (tap to sell)
var ShoeButton = Container.expand(function () {
var self = Container.call(this);
var btn = self.attachAsset('shoeBtn', {
anchorX: 0.5,
anchorY: 0.5
});
// Decorative: subtle bounce on tap
self.down = function (x, y, obj) {
// Animate scale
tween(self, {
scaleX: 0.92,
scaleY: 0.92
}, {
duration: 60,
easing: tween.easeIn,
onFinish: function onFinish() {
tween(self, {
scaleX: 1,
scaleY: 1
}, {
duration: 80,
easing: tween.easeOut
});
}
});
// Play sale sound
LK.getSound('sale').play();
// Add money
storage.money += storage.clickValue;
updateMoneyDisplay();
// Subtle money icon pop
popMoneyIcon();
};
return self;
});
// Upgrade Button (tap to increase click value)
var UpgradeButton = Container.expand(function () {
var self = Container.call(this);
var btn = self.attachAsset('upgradeBtn', {
anchorX: 0.5,
anchorY: 0.5
});
var txt = new Text2('', {
size: 48,
fill: 0xFFFBE6
});
txt.anchor.set(0.5, 0.5);
self.addChild(txt);
function updateText() {
txt.setText("Upgrade\n$" + storage.clickUpgradeCost);
}
self.updateText = updateText;
self.down = function (x, y, obj) {
if (storage.money >= storage.clickUpgradeCost) {
storage.money -= storage.clickUpgradeCost;
storage.clickValue += 1;
storage.clickUpgradeCost = Math.floor(storage.clickUpgradeCost * 1.5 + 10);
updateMoneyDisplay();
updateClickValueDisplay();
updateUpgradeButtons();
// Animate
tween(self, {
scaleX: 1.1,
scaleY: 1.1
}, {
duration: 80,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(self, {
scaleX: 1,
scaleY: 1
}, {
duration: 80,
easing: tween.easeIn
});
}
});
LK.getSound('upgrade').play();
} else {
// Subtle shake if not enough money
tween(self, {
x: self.x + 18
}, {
duration: 60,
easing: tween.easeIn,
onFinish: function onFinish() {
tween(self, {
x: self.x - 36
}, {
duration: 60,
easing: tween.easeIn,
onFinish: function onFinish() {
tween(self, {
x: self.x + 18
}, {
duration: 60,
easing: tween.easeOut
});
}
});
}
});
}
};
updateText();
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0xede7d2 // Subtle vintage beige
});
/****
* Game Code
****/
// Sound for upgrade
// Sound for sale
// Boutique background (subtle, not a full background, just a decorative element)
// Money icon
// Passive income upgrade button
// Upgrade button
// Main shoe button (luxury shoe)
// Decorative boutique ellipse at top
var boutiqueDeco = LK.getAsset('boutiqueDeco', {
anchorX: 0.5,
anchorY: 0,
x: 2048 / 2,
y: 0,
scaleX: 1.1,
scaleY: 1
});
game.addChild(boutiqueDeco);
// Money display
var moneyIcon = LK.getAsset('moneyIcon', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2 - 120,
y: 120
});
moneyIcon.scaleX = 1.1;
moneyIcon.scaleY = 1.1;
game.addChild(moneyIcon);
var moneyTxt = new Text2('', {
size: 90,
fill: 0x7C6F57
});
moneyTxt.anchor.set(0, 0.5);
moneyTxt.x = 2048 / 2 - 60;
moneyTxt.y = 120;
game.addChild(moneyTxt);
function formatMoney(val) {
if (val >= 1e9) {
return (val / 1e9).toFixed(2) + "B";
}
if (val >= 1e6) {
return (val / 1e6).toFixed(2) + "M";
}
if (val >= 1e3) {
return (val / 1e3).toFixed(1) + "K";
}
return "" + Math.floor(val);
}
function updateMoneyDisplay() {
moneyTxt.setText("$" + formatMoney(storage.money));
}
function popMoneyIcon() {
tween.stop(moneyIcon, {
scaleX: true,
scaleY: true
});
moneyIcon.scaleX = 1.1;
moneyIcon.scaleY = 1.1;
tween(moneyIcon, {
scaleX: 1.25,
scaleY: 1.25
}, {
duration: 60,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(moneyIcon, {
scaleX: 1.1,
scaleY: 1.1
}, {
duration: 80,
easing: tween.easeIn
});
}
});
}
// Click value display
var clickValueTxt = new Text2('', {
size: 48,
fill: 0x8B7B5A
});
clickValueTxt.anchor.set(0.5, 0);
clickValueTxt.x = 2048 / 2;
clickValueTxt.y = 320;
game.addChild(clickValueTxt);
function updateClickValueDisplay() {
clickValueTxt.setText("Per Tap: $" + formatMoney(storage.clickValue));
}
// Passive income display
var passiveTxt = new Text2('', {
size: 44,
fill: 0xB7A77A
});
passiveTxt.anchor.set(0.5, 0);
passiveTxt.x = 2048 / 2;
passiveTxt.y = 390;
game.addChild(passiveTxt);
function updatePassiveDisplay() {
if (storage.passiveIncome > 0) {
passiveTxt.setText("Auto: $" + formatMoney(storage.passiveIncome) + "/sec");
} else {
passiveTxt.setText("Auto: $0/sec");
}
}
// Main shoe button
var shoeBtn = new ShoeButton();
shoeBtn.x = 2048 / 2;
shoeBtn.y = 800;
game.addChild(shoeBtn);
// Upgrade buttons
var upgradeBtn = new UpgradeButton();
upgradeBtn.x = 2048 / 2 - 220;
upgradeBtn.y = 1200;
game.addChild(upgradeBtn);
var passiveBtn = new PassiveButton();
passiveBtn.x = 2048 / 2 + 220;
passiveBtn.y = 1200;
game.addChild(passiveBtn);
function updateUpgradeButtons() {
upgradeBtn.updateText();
passiveBtn.updateText();
}
// --- START MENU IMPLEMENTATION ---
var startMenuContainer = new Container();
var startBg = LK.getAsset('boutiqueDeco', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2,
y: 2732 / 2,
scaleX: 2.2,
scaleY: 2.2
});
startMenuContainer.addChild(startBg);
var startTitle = new Text2('SHOE TYCOON', {
size: 120,
fill: 0x7C6F57
});
startTitle.anchor.set(0.5, 0.5);
startTitle.x = 2048 / 2;
startTitle.y = 900;
startMenuContainer.addChild(startTitle);
var playBtn = LK.getAsset('upgradeBtn', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2,
y: 1500,
scaleX: 1.4,
scaleY: 1.2
});
startMenuContainer.addChild(playBtn);
var playTxt = new Text2('PLAY', {
size: 80,
fill: 0xFFFBE6
});
playTxt.anchor.set(0.5, 0.5);
playTxt.x = 2048 / 2;
playTxt.y = 1400;
startMenuContainer.addChild(playTxt);
game.addChild(startMenuContainer);
// Hide all gameplay UI until play is pressed
function setGameplayUIVisible(visible) {
moneyIcon.visible = visible;
moneyTxt.visible = visible;
clickValueTxt.visible = visible;
passiveTxt.visible = visible;
shoeBtn.visible = visible;
upgradeBtn.visible = visible;
passiveBtn.visible = visible;
boutiqueDeco.visible = visible;
if (typeof titleTxt !== "undefined" && titleTxt) {
titleTxt.visible = visible;
}
}
setGameplayUIVisible(false);
// Play button handler
playBtn.interactive = true;
playBtn.down = function (x, y, obj) {
// Animate play button
tween(playBtn, {
scaleX: 1.2,
scaleY: 1.1
}, {
duration: 80,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(playBtn, {
scaleX: 1.4,
scaleY: 1.2
}, {
duration: 80,
easing: tween.easeIn
});
}
});
// Fade out menu
tween(startMenuContainer, {
alpha: 0
}, {
duration: 220,
easing: tween.easeIn,
onFinish: function onFinish() {
startMenuContainer.visible = false;
setGameplayUIVisible(true);
}
});
};
// GUI Title
var titleTxt = new Text2('SHOE TYCOON', {
size: 100,
fill: 0x7C6F57
});
titleTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(titleTxt);
// Center title, but not in top left 100x100
titleTxt.x = LK.gui.top.width / 100;
titleTxt.y = 1300;
// Initial display update
updateMoneyDisplay();
updateClickValueDisplay();
updatePassiveDisplay();
updateUpgradeButtons();
// Passive income timer
var passiveTimer = LK.setInterval(function () {
if (storage.passiveIncome > 0) {
storage.money += storage.passiveIncome;
updateMoneyDisplay();
popMoneyIcon();
}
}, 1000);
// Save progress every 2 seconds
var saveTimer = LK.setInterval(function () {
// Storage is auto-persistent, but we can force a write if needed
// (No-op, but placeholder for future expansion)
}, 2000);
// Game update (not much needed, but could be used for future features)
game.update = function () {
// No per-frame logic needed for MVP
};
// Clean up on game over (not strictly needed, but good practice)
game.on('destroy', function () {
LK.clearInterval(passiveTimer);
LK.clearInterval(saveTimer);
});
// Touch handling for shoeBtn and upgrade buttons
// (Handled by their own .down methods, no need for game.down)
// Prevent elements in top left 100x100
// (All elements are centered or offset from center, so this is satisfied);