/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1", {
money: 0,
tapValue: 1,
autoIncome: 0,
upgrades: 0,
objectives: 0
});
/****
* Classes
****/
// Automation Icon (shows if auto income is unlocked)
var AutoIcon = Container.expand(function () {
var self = Container.call(this);
var icon = self.attachAsset('autoIcon', {
anchorX: 0.5,
anchorY: 0.5
});
var label = new Text2('AUTO', {
size: 32,
fill: "#fff"
});
label.anchor.set(0.5, 0.5);
self.addChild(label);
return self;
});
// Money Button (main clickable)
var MoneyButton = Container.expand(function () {
var self = Container.call(this);
var btn = self.attachAsset('moneyBtn', {
anchorX: 0.5,
anchorY: 0.5
});
// Animate on tap
self.flash = function () {
tween(self, {
scaleX: 1.1,
scaleY: 1.1
}, {
duration: 80,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(self, {
scaleX: 1,
scaleY: 1
}, {
duration: 120,
easing: tween.easeIn
});
}
});
};
// Touch event
self.down = function (x, y, obj) {
self.flash();
addMoney(tapValue);
};
return self;
});
// Objective Badge
var ObjectiveBadge = Container.expand(function () {
var self = Container.call(this);
var badge = self.attachAsset('objectiveBadge', {
anchorX: 0.5,
anchorY: 0.5
});
var label = new Text2('', {
size: 36,
fill: "#333"
});
label.anchor.set(0.5, 0.5);
self.addChild(label);
self.setLabel = function (txt) {
label.setText(txt);
};
return self;
});
// Upgrade Button
var UpgradeButton = Container.expand(function () {
var self = Container.call(this);
var btn = self.attachAsset('upgradeBtn', {
anchorX: 0.5,
anchorY: 0.5
});
var label = new Text2('', {
size: 48,
fill: "#fff"
});
label.anchor.set(0.5, 0.5);
self.addChild(label);
self.setLabel = function (txt) {
label.setText(txt);
};
self.setEnabled = function (enabled) {
btn.alpha = enabled ? 1 : 0.5;
self.interactive = enabled;
};
// Touch event
self.down = function (x, y, obj) {
if (canUpgrade()) {
doUpgrade();
}
};
return self;
});
// Villain (tries to steal money, can be fought off)
var Villain = Container.expand(function () {
var self = Container.call(this);
var villainAsset = self.attachAsset('character', {
anchorX: 0.5,
anchorY: 0.5
});
villainAsset.tint = 0x880000;
villainAsset.width = 180;
villainAsset.height = 180;
self.visible = false;
self.isActive = false;
self.stealAmount = 0;
self.timer = null;
self.lastX = 0;
self.lastY = 0;
// Called when villain appears
self.appear = function (amount) {
self.x = 2048 + 100;
self.y = 1200;
self.lastX = self.x;
self.visible = true;
self.isActive = true;
self.stealAmount = amount;
// Animate villain moving to moneyBtn
tween(self, {
x: moneyBtn.x + 220
}, {
duration: 800,
easing: tween.easeIn,
onFinish: function onFinish() {
// If not fought off, steal money
if (self.isActive) {
self.steal();
}
}
});
};
// Called when player taps villain to fight off
self.down = function (x, y, obj) {
if (!self.isActive) return;
self.fightOff();
};
// Steal money
self.steal = function () {
if (!self.isActive) return;
self.isActive = false;
self.visible = false;
var steal = Math.min(money, self.stealAmount);
if (steal > 0) {
money -= steal;
storage.money = money;
updateMoneyDisplay();
showVillainText("-$" + formatMoney(steal) + " stolen!");
LK.effects.flashObject(moneyBtn, 0xff0000, 600);
}
};
// Fight off villain
self.fightOff = function () {
if (!self.isActive) return;
self.isActive = false;
self.visible = false;
showVillainText("Villain repelled!");
LK.effects.flashObject(self, 0x00ff00, 400);
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x222222
});
/****
* Game Code
****/
// --- Persistent State ---
// Main money button (big, green, round)
// Upgrade button (smaller, blue, round)
// Objective badge (yellow, round)
// Automation icon (orange, square)
var money = storage.money || 0;
var tapValue = storage.tapValue || 1;
var autoIncome = storage.autoIncome || 0;
var upgrades = storage.upgrades || 0;
var objectives = storage.objectives || 0;
// --- UI Elements ---
var moneyBtn = new MoneyButton();
var upgradeBtn = new UpgradeButton();
var autoIcon = new AutoIcon();
var objectiveBadge = new ObjectiveBadge();
// --- Text Displays ---
var moneyTxt = new Text2('', {
size: 120,
fill: "#fff"
});
moneyTxt.anchor.set(0.5, 0);
// Upgrade cost and effect
function getUpgradeCost() {
// Cost increases exponentially
return 50 * Math.pow(2, upgrades);
}
function getUpgradeEffect() {
// Every upgrade increases tap value by 1, every 3rd upgrade unlocks auto income
return 1;
}
function getAutoIncome() {
// Every 3rd upgrade gives +1 auto income per second
return Math.floor(upgrades / 3);
}
// Objective system
var objectiveList = [{
desc: "Earn $100",
check: function check() {
return money >= 100;
},
reward: function reward() {
tapValue += 1;
},
rewardText: "+1 Tap Value"
}, {
desc: "Buy 3 Upgrades",
check: function check() {
return upgrades >= 3;
},
reward: function reward() {
autoIncome += 1;
},
rewardText: "+1 Auto Income"
}, {
desc: "Earn $1000",
check: function check() {
return money >= 1000;
},
reward: function reward() {
tapValue += 2;
},
rewardText: "+2 Tap Value"
}, {
desc: "Buy 6 Upgrades",
check: function check() {
return upgrades >= 6;
},
reward: function reward() {
autoIncome += 2;
},
rewardText: "+2 Auto Income"
}, {
desc: "Earn $10000",
check: function check() {
return money >= 10000;
},
reward: function reward() {
tapValue += 5;
},
rewardText: "+5 Tap Value"
}, {
desc: "Buy 10 Upgrades",
check: function check() {
return upgrades >= 10;
},
reward: function reward() {
autoIncome += 5;
},
rewardText: "+5 Auto Income"
}
// Add more objectives as needed
];
// --- Helper Functions ---
function addMoney(amount) {
money += amount;
storage.money = money;
updateMoneyDisplay();
checkObjectives();
}
function canUpgrade() {
return money >= getUpgradeCost();
}
function doUpgrade() {
var cost = getUpgradeCost();
if (money >= cost) {
money -= cost;
upgrades += 1;
tapValue += getUpgradeEffect();
autoIncome = getAutoIncome();
storage.money = money;
storage.upgrades = upgrades;
storage.tapValue = tapValue;
storage.autoIncome = autoIncome;
updateMoneyDisplay();
updateUpgradeDisplay();
updateAutoIcon();
checkObjectives();
}
}
function updateMoneyDisplay() {
moneyTxt.setText('$' + formatMoney(money));
}
function updateUpgradeDisplay() {
var cost = getUpgradeCost();
upgradeBtn.setLabel('Upgrade\n$' + formatMoney(cost));
upgradeBtn.setEnabled(money >= cost);
}
function updateAutoIcon() {
if (autoIncome > 0) {
autoIcon.visible = true;
} else {
autoIcon.visible = false;
}
}
function updateObjectiveBadge() {
if (objectives < objectiveList.length) {
var obj = objectiveList[objectives];
objectiveBadge.setLabel(objectives + 1 + '');
objectiveBadge.visible = true;
} else {
objectiveBadge.visible = false;
}
}
function checkObjectives() {
if (objectives < objectiveList.length) {
var obj = objectiveList[objectives];
if (obj.check()) {
// Show reward flash
LK.effects.flashObject(objectiveBadge, 0x00e676, 800);
// Reward
obj.reward();
storage.tapValue = tapValue;
storage.autoIncome = autoIncome;
objectives += 1;
storage.objectives = objectives;
// Show reward text
showObjectiveReward(obj.rewardText);
updateAutoIcon();
updateUpgradeDisplay();
updateObjectiveBadge();
}
}
}
function showObjectiveReward(txt) {
var rewardTxt = new Text2(txt, {
size: 60,
fill: 0xFFD600
});
rewardTxt.anchor.set(0.5, 0.5);
rewardTxt.x = 2048 / 2;
rewardTxt.y = 900;
game.addChild(rewardTxt);
tween(rewardTxt, {
y: rewardTxt.y - 120,
alpha: 0
}, {
duration: 1200,
easing: tween.easeOut,
onFinish: function onFinish() {
rewardTxt.destroy();
}
});
}
// Format money for display
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(2) + 'K';
return Math.floor(val);
}
// --- Layout ---
function layoutUI() {
// Money Button: center
moneyBtn.x = 2048 / 2;
moneyBtn.y = 1200;
moneyBtn.scaleX = 1;
moneyBtn.scaleY = 1;
// Money Text: above button
moneyTxt.x = 2048 / 2;
moneyTxt.y = 400;
// Upgrade Button: below button
upgradeBtn.x = 2048 / 2;
upgradeBtn.y = 1700;
// Auto Icon: right of button
autoIcon.x = 2048 / 2 + 350;
autoIcon.y = 1200;
// Objective Badge: left of button
objectiveBadge.x = 2048 / 2 - 350;
objectiveBadge.y = 1200;
// Villain: always above moneyBtn, same y
if (typeof villain !== "undefined") {
villain.y = moneyBtn.y;
}
}
// --- Add to Game ---
game.addChild(moneyBtn);
game.addChild(moneyTxt);
game.addChild(upgradeBtn);
game.addChild(autoIcon);
game.addChild(objectiveBadge);
// --- GUI: Title ---
var titleTxt = new Text2('Money Clicker Tycoon', {
size: 70,
fill: "#fff"
});
titleTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(titleTxt);
// --- Initial State ---
updateMoneyDisplay();
updateUpgradeDisplay();
updateAutoIcon();
updateObjectiveBadge();
layoutUI();
// --- Idle Income Timer ---
var autoTimer = LK.setInterval(function () {
if (autoIncome > 0) {
addMoney(autoIncome);
// Animate auto icon
tween(autoIcon, {
scaleX: 1.2,
scaleY: 1.2
}, {
duration: 80,
onFinish: function onFinish() {
tween(autoIcon, {
scaleX: 1,
scaleY: 1
}, {
duration: 120
});
}
});
}
}, 1000);
// --- Villain Logic ---
var villain = new Villain();
game.addChild(villain);
// Show villain text feedback
function showVillainText(txt) {
var vtxt = new Text2(txt, {
size: 60,
fill: 0xFF4444
});
vtxt.anchor.set(0.5, 0.5);
vtxt.x = 2048 / 2;
vtxt.y = 1000;
game.addChild(vtxt);
tween(vtxt, {
y: vtxt.y - 100,
alpha: 0
}, {
duration: 1000,
easing: tween.easeOut,
onFinish: function onFinish() {
vtxt.destroy();
}
});
}
// Villain spawn timer
var villainTimer = LK.setInterval(function () {
// Villain appears every 10-20 seconds, only if not already active and player has at least $100
if (!villain.isActive && money >= 100) {
if (Math.random() < 0.15) {
// ~15% chance per second
var steal = Math.max(50, Math.floor(money * 0.1));
villain.appear(steal);
}
}
}, 1000);
// --- Game Update Loop ---
game.update = function () {
// Defensive: update villain lastX/lastY for event logic if needed
if (villain.visible) {
villain.lastX = villain.x;
villain.lastY = villain.y;
}
};
// --- Responsive Layout on Resize ---
game.on('resize', function () {
layoutUI();
});
// --- Prevent UI in top-left 100x100 px ---
titleTxt.x = LK.gui.top.width / 2;
titleTxt.y = 0;
// --- Touchscreen: No drag, only tap ---
// --- End of File --- /****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1", {
money: 0,
tapValue: 1,
autoIncome: 0,
upgrades: 0,
objectives: 0
});
/****
* Classes
****/
// Automation Icon (shows if auto income is unlocked)
var AutoIcon = Container.expand(function () {
var self = Container.call(this);
var icon = self.attachAsset('autoIcon', {
anchorX: 0.5,
anchorY: 0.5
});
var label = new Text2('AUTO', {
size: 32,
fill: "#fff"
});
label.anchor.set(0.5, 0.5);
self.addChild(label);
return self;
});
// Money Button (main clickable)
var MoneyButton = Container.expand(function () {
var self = Container.call(this);
var btn = self.attachAsset('moneyBtn', {
anchorX: 0.5,
anchorY: 0.5
});
// Animate on tap
self.flash = function () {
tween(self, {
scaleX: 1.1,
scaleY: 1.1
}, {
duration: 80,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(self, {
scaleX: 1,
scaleY: 1
}, {
duration: 120,
easing: tween.easeIn
});
}
});
};
// Touch event
self.down = function (x, y, obj) {
self.flash();
addMoney(tapValue);
};
return self;
});
// Objective Badge
var ObjectiveBadge = Container.expand(function () {
var self = Container.call(this);
var badge = self.attachAsset('objectiveBadge', {
anchorX: 0.5,
anchorY: 0.5
});
var label = new Text2('', {
size: 36,
fill: "#333"
});
label.anchor.set(0.5, 0.5);
self.addChild(label);
self.setLabel = function (txt) {
label.setText(txt);
};
return self;
});
// Upgrade Button
var UpgradeButton = Container.expand(function () {
var self = Container.call(this);
var btn = self.attachAsset('upgradeBtn', {
anchorX: 0.5,
anchorY: 0.5
});
var label = new Text2('', {
size: 48,
fill: "#fff"
});
label.anchor.set(0.5, 0.5);
self.addChild(label);
self.setLabel = function (txt) {
label.setText(txt);
};
self.setEnabled = function (enabled) {
btn.alpha = enabled ? 1 : 0.5;
self.interactive = enabled;
};
// Touch event
self.down = function (x, y, obj) {
if (canUpgrade()) {
doUpgrade();
}
};
return self;
});
// Villain (tries to steal money, can be fought off)
var Villain = Container.expand(function () {
var self = Container.call(this);
var villainAsset = self.attachAsset('character', {
anchorX: 0.5,
anchorY: 0.5
});
villainAsset.tint = 0x880000;
villainAsset.width = 180;
villainAsset.height = 180;
self.visible = false;
self.isActive = false;
self.stealAmount = 0;
self.timer = null;
self.lastX = 0;
self.lastY = 0;
// Called when villain appears
self.appear = function (amount) {
self.x = 2048 + 100;
self.y = 1200;
self.lastX = self.x;
self.visible = true;
self.isActive = true;
self.stealAmount = amount;
// Animate villain moving to moneyBtn
tween(self, {
x: moneyBtn.x + 220
}, {
duration: 800,
easing: tween.easeIn,
onFinish: function onFinish() {
// If not fought off, steal money
if (self.isActive) {
self.steal();
}
}
});
};
// Called when player taps villain to fight off
self.down = function (x, y, obj) {
if (!self.isActive) return;
self.fightOff();
};
// Steal money
self.steal = function () {
if (!self.isActive) return;
self.isActive = false;
self.visible = false;
var steal = Math.min(money, self.stealAmount);
if (steal > 0) {
money -= steal;
storage.money = money;
updateMoneyDisplay();
showVillainText("-$" + formatMoney(steal) + " stolen!");
LK.effects.flashObject(moneyBtn, 0xff0000, 600);
}
};
// Fight off villain
self.fightOff = function () {
if (!self.isActive) return;
self.isActive = false;
self.visible = false;
showVillainText("Villain repelled!");
LK.effects.flashObject(self, 0x00ff00, 400);
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x222222
});
/****
* Game Code
****/
// --- Persistent State ---
// Main money button (big, green, round)
// Upgrade button (smaller, blue, round)
// Objective badge (yellow, round)
// Automation icon (orange, square)
var money = storage.money || 0;
var tapValue = storage.tapValue || 1;
var autoIncome = storage.autoIncome || 0;
var upgrades = storage.upgrades || 0;
var objectives = storage.objectives || 0;
// --- UI Elements ---
var moneyBtn = new MoneyButton();
var upgradeBtn = new UpgradeButton();
var autoIcon = new AutoIcon();
var objectiveBadge = new ObjectiveBadge();
// --- Text Displays ---
var moneyTxt = new Text2('', {
size: 120,
fill: "#fff"
});
moneyTxt.anchor.set(0.5, 0);
// Upgrade cost and effect
function getUpgradeCost() {
// Cost increases exponentially
return 50 * Math.pow(2, upgrades);
}
function getUpgradeEffect() {
// Every upgrade increases tap value by 1, every 3rd upgrade unlocks auto income
return 1;
}
function getAutoIncome() {
// Every 3rd upgrade gives +1 auto income per second
return Math.floor(upgrades / 3);
}
// Objective system
var objectiveList = [{
desc: "Earn $100",
check: function check() {
return money >= 100;
},
reward: function reward() {
tapValue += 1;
},
rewardText: "+1 Tap Value"
}, {
desc: "Buy 3 Upgrades",
check: function check() {
return upgrades >= 3;
},
reward: function reward() {
autoIncome += 1;
},
rewardText: "+1 Auto Income"
}, {
desc: "Earn $1000",
check: function check() {
return money >= 1000;
},
reward: function reward() {
tapValue += 2;
},
rewardText: "+2 Tap Value"
}, {
desc: "Buy 6 Upgrades",
check: function check() {
return upgrades >= 6;
},
reward: function reward() {
autoIncome += 2;
},
rewardText: "+2 Auto Income"
}, {
desc: "Earn $10000",
check: function check() {
return money >= 10000;
},
reward: function reward() {
tapValue += 5;
},
rewardText: "+5 Tap Value"
}, {
desc: "Buy 10 Upgrades",
check: function check() {
return upgrades >= 10;
},
reward: function reward() {
autoIncome += 5;
},
rewardText: "+5 Auto Income"
}
// Add more objectives as needed
];
// --- Helper Functions ---
function addMoney(amount) {
money += amount;
storage.money = money;
updateMoneyDisplay();
checkObjectives();
}
function canUpgrade() {
return money >= getUpgradeCost();
}
function doUpgrade() {
var cost = getUpgradeCost();
if (money >= cost) {
money -= cost;
upgrades += 1;
tapValue += getUpgradeEffect();
autoIncome = getAutoIncome();
storage.money = money;
storage.upgrades = upgrades;
storage.tapValue = tapValue;
storage.autoIncome = autoIncome;
updateMoneyDisplay();
updateUpgradeDisplay();
updateAutoIcon();
checkObjectives();
}
}
function updateMoneyDisplay() {
moneyTxt.setText('$' + formatMoney(money));
}
function updateUpgradeDisplay() {
var cost = getUpgradeCost();
upgradeBtn.setLabel('Upgrade\n$' + formatMoney(cost));
upgradeBtn.setEnabled(money >= cost);
}
function updateAutoIcon() {
if (autoIncome > 0) {
autoIcon.visible = true;
} else {
autoIcon.visible = false;
}
}
function updateObjectiveBadge() {
if (objectives < objectiveList.length) {
var obj = objectiveList[objectives];
objectiveBadge.setLabel(objectives + 1 + '');
objectiveBadge.visible = true;
} else {
objectiveBadge.visible = false;
}
}
function checkObjectives() {
if (objectives < objectiveList.length) {
var obj = objectiveList[objectives];
if (obj.check()) {
// Show reward flash
LK.effects.flashObject(objectiveBadge, 0x00e676, 800);
// Reward
obj.reward();
storage.tapValue = tapValue;
storage.autoIncome = autoIncome;
objectives += 1;
storage.objectives = objectives;
// Show reward text
showObjectiveReward(obj.rewardText);
updateAutoIcon();
updateUpgradeDisplay();
updateObjectiveBadge();
}
}
}
function showObjectiveReward(txt) {
var rewardTxt = new Text2(txt, {
size: 60,
fill: 0xFFD600
});
rewardTxt.anchor.set(0.5, 0.5);
rewardTxt.x = 2048 / 2;
rewardTxt.y = 900;
game.addChild(rewardTxt);
tween(rewardTxt, {
y: rewardTxt.y - 120,
alpha: 0
}, {
duration: 1200,
easing: tween.easeOut,
onFinish: function onFinish() {
rewardTxt.destroy();
}
});
}
// Format money for display
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(2) + 'K';
return Math.floor(val);
}
// --- Layout ---
function layoutUI() {
// Money Button: center
moneyBtn.x = 2048 / 2;
moneyBtn.y = 1200;
moneyBtn.scaleX = 1;
moneyBtn.scaleY = 1;
// Money Text: above button
moneyTxt.x = 2048 / 2;
moneyTxt.y = 400;
// Upgrade Button: below button
upgradeBtn.x = 2048 / 2;
upgradeBtn.y = 1700;
// Auto Icon: right of button
autoIcon.x = 2048 / 2 + 350;
autoIcon.y = 1200;
// Objective Badge: left of button
objectiveBadge.x = 2048 / 2 - 350;
objectiveBadge.y = 1200;
// Villain: always above moneyBtn, same y
if (typeof villain !== "undefined") {
villain.y = moneyBtn.y;
}
}
// --- Add to Game ---
game.addChild(moneyBtn);
game.addChild(moneyTxt);
game.addChild(upgradeBtn);
game.addChild(autoIcon);
game.addChild(objectiveBadge);
// --- GUI: Title ---
var titleTxt = new Text2('Money Clicker Tycoon', {
size: 70,
fill: "#fff"
});
titleTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(titleTxt);
// --- Initial State ---
updateMoneyDisplay();
updateUpgradeDisplay();
updateAutoIcon();
updateObjectiveBadge();
layoutUI();
// --- Idle Income Timer ---
var autoTimer = LK.setInterval(function () {
if (autoIncome > 0) {
addMoney(autoIncome);
// Animate auto icon
tween(autoIcon, {
scaleX: 1.2,
scaleY: 1.2
}, {
duration: 80,
onFinish: function onFinish() {
tween(autoIcon, {
scaleX: 1,
scaleY: 1
}, {
duration: 120
});
}
});
}
}, 1000);
// --- Villain Logic ---
var villain = new Villain();
game.addChild(villain);
// Show villain text feedback
function showVillainText(txt) {
var vtxt = new Text2(txt, {
size: 60,
fill: 0xFF4444
});
vtxt.anchor.set(0.5, 0.5);
vtxt.x = 2048 / 2;
vtxt.y = 1000;
game.addChild(vtxt);
tween(vtxt, {
y: vtxt.y - 100,
alpha: 0
}, {
duration: 1000,
easing: tween.easeOut,
onFinish: function onFinish() {
vtxt.destroy();
}
});
}
// Villain spawn timer
var villainTimer = LK.setInterval(function () {
// Villain appears every 10-20 seconds, only if not already active and player has at least $100
if (!villain.isActive && money >= 100) {
if (Math.random() < 0.15) {
// ~15% chance per second
var steal = Math.max(50, Math.floor(money * 0.1));
villain.appear(steal);
}
}
}, 1000);
// --- Game Update Loop ---
game.update = function () {
// Defensive: update villain lastX/lastY for event logic if needed
if (villain.visible) {
villain.lastX = villain.x;
villain.lastY = villain.y;
}
};
// --- Responsive Layout on Resize ---
game.on('resize', function () {
layoutUI();
});
// --- Prevent UI in top-left 100x100 px ---
titleTxt.x = LK.gui.top.width / 2;
titleTxt.y = 0;
// --- Touchscreen: No drag, only tap ---
// --- End of File ---