/**** * 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();