/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
// Coin class: clickable coin that gives bitcoin
var Coin = Container.expand(function () {
var self = Container.call(this);
// Attach coin asset, center anchor
var coinGfx = self.attachAsset('coin', {
anchorX: 0.5,
anchorY: 0.5
});
// Animate coin (simple scale pulse)
self.pulseTween = function () {
tween(self, {
scaleX: 1.15,
scaleY: 1.15
}, {
duration: 120,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(self, {
scaleX: 1,
scaleY: 1
}, {
duration: 120,
easing: tween.easeIn
});
}
});
};
// On tap/click
self.down = function (x, y, obj) {
if (marketOpen) return; // Ignore if market is open
self.pulseTween();
addBitcoin(clickPower);
showFloatingText("+" + formatNumber(clickPower), self.x, self.y);
};
return self;
});
// Market Button class (top-right)
var MarketButton = Container.expand(function () {
var self = Container.call(this);
var btn = self.attachAsset('marketBtn', {
anchorX: 1,
anchorY: 0
});
// Add text
var txt = new Text2("Shop", {
size: 60,
fill: "#fff"
});
txt.anchor.set(0.5, 0.5);
txt.x = btn.width / 2;
txt.y = btn.height / 2;
self.addChild(txt);
// On tap/click
self.down = function (x, y, obj) {
if (!marketOpen) openMarket();
};
return self;
});
// Market Overlay class
var MarketOverlay = Container.expand(function () {
var self = Container.call(this);
// Market background image (centered, not full screen)
var marketBgWidth = 1400;
var marketBgHeight = 2000;
var bg = self.attachAsset('marketBg', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2,
y: 2732 / 2,
width: marketBgWidth,
height: marketBgHeight
});
bg.alpha = 0.92; // Slight transparency for overlay effect
self.addChild(bg);
// Title
var title = new Text2("Shop", {
size: 120,
fill: "#fff"
});
title.anchor.set(0.5, 0);
title.x = 2048 / 2;
title.y = 2732 / 2 - 2000 / 2 + 60;
self.addChild(title);
// Upgrades list
self.upgradeButtons = [];
// Close button (top right of market background)
var closeBtn = self.attachAsset('closeBtn', {
anchorX: 1,
anchorY: 0,
x: 2048 / 2 + 1400 / 2 - 40,
y: 2732 / 2 - 2000 / 2 + 40
});
closeBtn.down = function (x, y, obj) {
closeMarket();
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x181818
});
/****
* Game Code
****/
// Close button: red box
// Upgrade button: green box
// Market button: blue box
// Coin asset: gold ellipse
// --- Global State ---
// Market background image (full screen, placeholder id)
var bitcoin = 0;
var clickPower = 1;
var upgrades = [{
id: "mult1",
name: "Click Power x2",
desc: "Double your click power.",
cost: 50,
owned: false,
apply: function apply() {
clickPower *= 2;
}
}, {
id: "mult2",
name: "Click Power x3",
desc: "Triple your click power.",
cost: 250,
owned: false,
apply: function apply() {
clickPower *= 3;
}
}, {
id: "autoclick1",
name: "Auto-Clicker",
desc: "Earn 1 bitcoin per second automatically.",
cost: 100,
owned: false,
apply: function apply() {
startAutoClicker(1);
}
}, {
id: "autoclick2",
name: "Auto-Clicker+",
desc: "Earn 5 bitcoin per second automatically.",
cost: 500,
owned: false,
apply: function apply() {
startAutoClicker(5);
}
}];
var marketOpen = false;
var coin = null;
var marketBtn = null;
var marketOverlay = null;
var bitcoinTxt = null;
var floatingTexts = [];
var autoClickerInterval = null;
var autoClickerAmount = 0;
// --- Utility Functions ---
function formatNumber(n) {
if (n >= 1e9) return (n / 1e9).toFixed(2) + "B";
if (n >= 1e6) return (n / 1e6).toFixed(2) + "M";
if (n >= 1e3) return (n / 1e3).toFixed(2) + "K";
return "" + Math.floor(n);
}
function addBitcoin(amount) {
bitcoin += amount;
updateBitcoinText();
}
function updateBitcoinText() {
bitcoinTxt.setText("₿ " + formatNumber(bitcoin));
}
function showFloatingText(text, x, y) {
var txt = new Text2(text, {
size: 70,
fill: 0xFFD700
});
txt.anchor.set(0.5, 0.5);
txt.x = x;
txt.y = y;
game.addChild(txt);
floatingTexts.push(txt);
// Animate up and fade out
tween(txt, {
y: y - 120,
alpha: 0
}, {
duration: 900,
easing: tween.cubicOut,
onFinish: function onFinish() {
txt.destroy();
var idx = floatingTexts.indexOf(txt);
if (idx !== -1) floatingTexts.splice(idx, 1);
}
});
}
function openMarket() {
if (marketOpen) return;
marketOpen = true;
marketOverlay = new MarketOverlay();
// Add upgrade buttons
var marketBgWidth = 1400;
var marketBgHeight = 2000;
var startY = 2732 / 2 - marketBgHeight / 2 + 220;
var gapY = 220;
for (var i = 0; i < upgrades.length; ++i) {
var upg = upgrades[i];
// --- Upgrade Button (below texts) ---
var btn = LK.getAsset('upgradeBtn', {
anchorX: 0.5,
anchorY: 0,
x: 2048 / 2,
y: startY + i * gapY
});
marketOverlay.addChild(btn);
marketOverlay.upgradeButtons.push(btn);
// --- Upgrade Name Text ---
var upgTxt = new Text2(upg.name + (upg.owned ? " (Owned)" : ""), {
size: 60,
fill: upg.owned ? "#bbb" : "#fff"
});
upgTxt.anchor.set(0.5, 0);
upgTxt.x = 2048 / 2;
upgTxt.y = startY + i * gapY + 18;
marketOverlay.addChild(upgTxt);
// --- Upgrade Description Text ---
var descTxt = new Text2(upg.desc, {
size: 38,
fill: 0xE0E0E0
});
descTxt.anchor.set(0.5, 0);
descTxt.x = 2048 / 2;
descTxt.y = startY + i * gapY + 80;
marketOverlay.addChild(descTxt);
// --- Upgrade Cost Text ---
var costTxt = new Text2("Cost: " + formatNumber(upg.cost) + " ₿", {
size: 38,
fill: upg.owned ? "#bbb" : "#ffd700"
});
costTxt.anchor.set(0.5, 0);
costTxt.x = 2048 / 2;
costTxt.y = startY + i * gapY + 130;
marketOverlay.addChild(costTxt);
// Multi-purchase upgrades with increasing cost
if (typeof upg.count === "undefined") upg.count = 0;
if (typeof upg.baseCost === "undefined") upg.baseCost = upg.cost;
(function (upg, btn, upgTxt, costTxt) {
btn.down = function (x, y, obj) {
// If not enough bitcoin, flash red
if (bitcoin < upg.cost) {
LK.effects.flashObject(btn, 0xff0000, 400);
return;
}
// Purchase upgrade
bitcoin -= upg.cost;
upg.count = (upg.count || 0) + 1;
upg.owned = true; // For legacy code, but we now allow multi-buy
upg.apply();
updateBitcoinText();
showFloatingText("-" + formatNumber(upg.cost), btn.x, btn.y + 40);
// Increase cost for next purchase (1.5x, rounded up)
upg.cost = Math.ceil(upg.baseCost * Math.pow(1.5, upg.count));
// Update UI
upgTxt.setText(upg.name + (upg.count > 0 ? " (x" + upg.count + ")" : ""));
costTxt.setText("Cost: " + formatNumber(upg.cost) + " ₿");
if (costTxt.style) costTxt.style.fill = "#ffd700";
if (upgTxt.style) upgTxt.style.fill = "#fff";
};
})(upg, btn, upgTxt, costTxt);
}
// Add overlay to game
game.addChild(marketOverlay);
}
function closeMarket() {
if (!marketOpen) return;
if (marketOverlay) {
marketOverlay.destroy();
marketOverlay = null;
}
marketOpen = false;
}
// Start or increase auto-clicker
function startAutoClicker(amount) {
autoClickerAmount += amount;
if (!autoClickerInterval) {
autoClickerInterval = LK.setInterval(function () {
if (!marketOpen) {
addBitcoin(autoClickerAmount);
showFloatingText("+" + formatNumber(autoClickerAmount), coin.x, coin.y - coin.height / 2 - 30);
}
}, 1000);
}
}
// --- UI Setup ---
// Bitcoin text (top center, below safe area)
bitcoinTxt = new Text2("₿ 0", {
size: 110,
fill: 0xFFD700
});
bitcoinTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(bitcoinTxt);
// Market button (top right, below safe area)
marketBtn = new MarketButton();
marketBtn.x = 0;
marketBtn.y = 0;
LK.gui.topRight.addChild(marketBtn);
// Coin (centered)
coin = new Coin();
coin.x = 2048 / 2;
coin.y = 2732 / 2 + 120;
game.addChild(coin);
// --- Game Update Loop ---
game.update = function () {
// Animate floating texts (handled by tween, but clean up if any remain)
for (var i = floatingTexts.length - 1; i >= 0; --i) {
var txt = floatingTexts[i];
if (txt.alpha <= 0.01) {
txt.destroy();
floatingTexts.splice(i, 1);
}
}
// No other per-frame logic needed for MVP
};
// --- Initial State ---
updateBitcoinText(); /****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
// Coin class: clickable coin that gives bitcoin
var Coin = Container.expand(function () {
var self = Container.call(this);
// Attach coin asset, center anchor
var coinGfx = self.attachAsset('coin', {
anchorX: 0.5,
anchorY: 0.5
});
// Animate coin (simple scale pulse)
self.pulseTween = function () {
tween(self, {
scaleX: 1.15,
scaleY: 1.15
}, {
duration: 120,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(self, {
scaleX: 1,
scaleY: 1
}, {
duration: 120,
easing: tween.easeIn
});
}
});
};
// On tap/click
self.down = function (x, y, obj) {
if (marketOpen) return; // Ignore if market is open
self.pulseTween();
addBitcoin(clickPower);
showFloatingText("+" + formatNumber(clickPower), self.x, self.y);
};
return self;
});
// Market Button class (top-right)
var MarketButton = Container.expand(function () {
var self = Container.call(this);
var btn = self.attachAsset('marketBtn', {
anchorX: 1,
anchorY: 0
});
// Add text
var txt = new Text2("Shop", {
size: 60,
fill: "#fff"
});
txt.anchor.set(0.5, 0.5);
txt.x = btn.width / 2;
txt.y = btn.height / 2;
self.addChild(txt);
// On tap/click
self.down = function (x, y, obj) {
if (!marketOpen) openMarket();
};
return self;
});
// Market Overlay class
var MarketOverlay = Container.expand(function () {
var self = Container.call(this);
// Market background image (centered, not full screen)
var marketBgWidth = 1400;
var marketBgHeight = 2000;
var bg = self.attachAsset('marketBg', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2,
y: 2732 / 2,
width: marketBgWidth,
height: marketBgHeight
});
bg.alpha = 0.92; // Slight transparency for overlay effect
self.addChild(bg);
// Title
var title = new Text2("Shop", {
size: 120,
fill: "#fff"
});
title.anchor.set(0.5, 0);
title.x = 2048 / 2;
title.y = 2732 / 2 - 2000 / 2 + 60;
self.addChild(title);
// Upgrades list
self.upgradeButtons = [];
// Close button (top right of market background)
var closeBtn = self.attachAsset('closeBtn', {
anchorX: 1,
anchorY: 0,
x: 2048 / 2 + 1400 / 2 - 40,
y: 2732 / 2 - 2000 / 2 + 40
});
closeBtn.down = function (x, y, obj) {
closeMarket();
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x181818
});
/****
* Game Code
****/
// Close button: red box
// Upgrade button: green box
// Market button: blue box
// Coin asset: gold ellipse
// --- Global State ---
// Market background image (full screen, placeholder id)
var bitcoin = 0;
var clickPower = 1;
var upgrades = [{
id: "mult1",
name: "Click Power x2",
desc: "Double your click power.",
cost: 50,
owned: false,
apply: function apply() {
clickPower *= 2;
}
}, {
id: "mult2",
name: "Click Power x3",
desc: "Triple your click power.",
cost: 250,
owned: false,
apply: function apply() {
clickPower *= 3;
}
}, {
id: "autoclick1",
name: "Auto-Clicker",
desc: "Earn 1 bitcoin per second automatically.",
cost: 100,
owned: false,
apply: function apply() {
startAutoClicker(1);
}
}, {
id: "autoclick2",
name: "Auto-Clicker+",
desc: "Earn 5 bitcoin per second automatically.",
cost: 500,
owned: false,
apply: function apply() {
startAutoClicker(5);
}
}];
var marketOpen = false;
var coin = null;
var marketBtn = null;
var marketOverlay = null;
var bitcoinTxt = null;
var floatingTexts = [];
var autoClickerInterval = null;
var autoClickerAmount = 0;
// --- Utility Functions ---
function formatNumber(n) {
if (n >= 1e9) return (n / 1e9).toFixed(2) + "B";
if (n >= 1e6) return (n / 1e6).toFixed(2) + "M";
if (n >= 1e3) return (n / 1e3).toFixed(2) + "K";
return "" + Math.floor(n);
}
function addBitcoin(amount) {
bitcoin += amount;
updateBitcoinText();
}
function updateBitcoinText() {
bitcoinTxt.setText("₿ " + formatNumber(bitcoin));
}
function showFloatingText(text, x, y) {
var txt = new Text2(text, {
size: 70,
fill: 0xFFD700
});
txt.anchor.set(0.5, 0.5);
txt.x = x;
txt.y = y;
game.addChild(txt);
floatingTexts.push(txt);
// Animate up and fade out
tween(txt, {
y: y - 120,
alpha: 0
}, {
duration: 900,
easing: tween.cubicOut,
onFinish: function onFinish() {
txt.destroy();
var idx = floatingTexts.indexOf(txt);
if (idx !== -1) floatingTexts.splice(idx, 1);
}
});
}
function openMarket() {
if (marketOpen) return;
marketOpen = true;
marketOverlay = new MarketOverlay();
// Add upgrade buttons
var marketBgWidth = 1400;
var marketBgHeight = 2000;
var startY = 2732 / 2 - marketBgHeight / 2 + 220;
var gapY = 220;
for (var i = 0; i < upgrades.length; ++i) {
var upg = upgrades[i];
// --- Upgrade Button (below texts) ---
var btn = LK.getAsset('upgradeBtn', {
anchorX: 0.5,
anchorY: 0,
x: 2048 / 2,
y: startY + i * gapY
});
marketOverlay.addChild(btn);
marketOverlay.upgradeButtons.push(btn);
// --- Upgrade Name Text ---
var upgTxt = new Text2(upg.name + (upg.owned ? " (Owned)" : ""), {
size: 60,
fill: upg.owned ? "#bbb" : "#fff"
});
upgTxt.anchor.set(0.5, 0);
upgTxt.x = 2048 / 2;
upgTxt.y = startY + i * gapY + 18;
marketOverlay.addChild(upgTxt);
// --- Upgrade Description Text ---
var descTxt = new Text2(upg.desc, {
size: 38,
fill: 0xE0E0E0
});
descTxt.anchor.set(0.5, 0);
descTxt.x = 2048 / 2;
descTxt.y = startY + i * gapY + 80;
marketOverlay.addChild(descTxt);
// --- Upgrade Cost Text ---
var costTxt = new Text2("Cost: " + formatNumber(upg.cost) + " ₿", {
size: 38,
fill: upg.owned ? "#bbb" : "#ffd700"
});
costTxt.anchor.set(0.5, 0);
costTxt.x = 2048 / 2;
costTxt.y = startY + i * gapY + 130;
marketOverlay.addChild(costTxt);
// Multi-purchase upgrades with increasing cost
if (typeof upg.count === "undefined") upg.count = 0;
if (typeof upg.baseCost === "undefined") upg.baseCost = upg.cost;
(function (upg, btn, upgTxt, costTxt) {
btn.down = function (x, y, obj) {
// If not enough bitcoin, flash red
if (bitcoin < upg.cost) {
LK.effects.flashObject(btn, 0xff0000, 400);
return;
}
// Purchase upgrade
bitcoin -= upg.cost;
upg.count = (upg.count || 0) + 1;
upg.owned = true; // For legacy code, but we now allow multi-buy
upg.apply();
updateBitcoinText();
showFloatingText("-" + formatNumber(upg.cost), btn.x, btn.y + 40);
// Increase cost for next purchase (1.5x, rounded up)
upg.cost = Math.ceil(upg.baseCost * Math.pow(1.5, upg.count));
// Update UI
upgTxt.setText(upg.name + (upg.count > 0 ? " (x" + upg.count + ")" : ""));
costTxt.setText("Cost: " + formatNumber(upg.cost) + " ₿");
if (costTxt.style) costTxt.style.fill = "#ffd700";
if (upgTxt.style) upgTxt.style.fill = "#fff";
};
})(upg, btn, upgTxt, costTxt);
}
// Add overlay to game
game.addChild(marketOverlay);
}
function closeMarket() {
if (!marketOpen) return;
if (marketOverlay) {
marketOverlay.destroy();
marketOverlay = null;
}
marketOpen = false;
}
// Start or increase auto-clicker
function startAutoClicker(amount) {
autoClickerAmount += amount;
if (!autoClickerInterval) {
autoClickerInterval = LK.setInterval(function () {
if (!marketOpen) {
addBitcoin(autoClickerAmount);
showFloatingText("+" + formatNumber(autoClickerAmount), coin.x, coin.y - coin.height / 2 - 30);
}
}, 1000);
}
}
// --- UI Setup ---
// Bitcoin text (top center, below safe area)
bitcoinTxt = new Text2("₿ 0", {
size: 110,
fill: 0xFFD700
});
bitcoinTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(bitcoinTxt);
// Market button (top right, below safe area)
marketBtn = new MarketButton();
marketBtn.x = 0;
marketBtn.y = 0;
LK.gui.topRight.addChild(marketBtn);
// Coin (centered)
coin = new Coin();
coin.x = 2048 / 2;
coin.y = 2732 / 2 + 120;
game.addChild(coin);
// --- Game Update Loop ---
game.update = function () {
// Animate floating texts (handled by tween, but clean up if any remain)
for (var i = floatingTexts.length - 1; i >= 0; --i) {
var txt = floatingTexts[i];
if (txt.alpha <= 0.01) {
txt.destroy();
floatingTexts.splice(i, 1);
}
}
// No other per-frame logic needed for MVP
};
// --- Initial State ---
updateBitcoinText();