/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var storage = LK.import("@upit/storage.v1", { cookies: 0, cursors: 0, grandmas: 0, cursorLevel: 1, grandmaLevel: 1, lastTimestamp: "undefined" }); /**** * Classes ****/ var Cookie = Container.expand(function () { var self = Container.call(this); var cookie = self.attachAsset('cookie', { anchorX: 0.5, anchorY: 0.5 }); self.startScale = 1; self.down = function (x, y, obj) { self.isPressed = true; self.scale.set(self.startScale * 0.95); // Add cookie to count var cps = getCookiesPerSecond(); cookies += cps > 0 ? cps : 1; updateCookieDisplay(); // Create click animation self.showClickAnimation(); // Play sound LK.getSound('click').play(); }; self.up = function (x, y, obj) { self.isPressed = false; self.scale.set(self.startScale); }; self.showClickAnimation = function () { // Create a text to show cookies per click var cps = getCookiesPerSecond(); var clickValue = cps > 0 ? cps : cookiesPerClick; var clickText = new Text2("+" + formatNumber(clickValue), { size: 80, fill: 0xFFFFFF }); clickText.anchor.set(0.5, 0.5); // Random position around the click point var randomOffset = 100; clickText.x = Math.random() * randomOffset - randomOffset / 2; clickText.y = -50; self.addChild(clickText); // Animate text upward and fade out tween(clickText, { y: clickText.y - 150, alpha: 0 }, { duration: 1000, easing: tween.easeOut, onFinish: function onFinish() { clickText.destroy(); } }); }; return self; }); var CookieChip = Container.expand(function () { var self = Container.call(this); var chip = self.attachAsset('cookieChip', { anchorX: 0.5, anchorY: 0.5 }); return self; }); var Factory = Container.expand(function () { var self = Container.call(this); var factoryGraphics = self.attachAsset('Factory', { anchorX: 0.5, anchorY: 0.5 }); self.timer = 30 * 60; // Initial timer for factory production in frames self.productionAmount = 5000000; // Initial production amount self.level = 1; self.update = function () { if (self.timer > 0) { self.timer--; } else { cookies += self.productionAmount; updateCookieDisplay(); // Reset all factory timers to sync them for (var i = 0; i < factories.length; i++) { factories[i].timer = Math.max(1, 30 - (factories[i].level - 1) * 3); } } }; self.upgrade = function () { self.level++; self.productionAmount *= 2; // Double the production amount self.timer = Math.max(1, 30 - (self.level - 1) * 3); // Decrease timer by 3 seconds per level }; return self; }); var Grandma = Container.expand(function () { var self = Container.call(this); var grandmaGraphics = self.attachAsset('grandma', { anchorX: 0.5, anchorY: 0.5 }); // List of names for grandmas var names = ["Mary", "Jane", "Scooter", "Sharda", "Caroline"]; // Assign a random name to the grandma self.name = names[Math.floor(Math.random() * names.length)]; // Display the name when hovered self.interactive = true; self.down = function () { var nameText = new Text2(self.name, { size: 40, fill: 0xFFFFFF }); nameText.anchor.set(0.5, 0.5); nameText.x = self.x; nameText.y = self.y - 100; // Position above the grandma game.addChild(nameText); // Remove the name text after a short delay LK.setTimeout(function () { nameText.destroy(); }, 2000); }; return self; }); var Producer = Container.expand(function () { var self = Container.call(this); self.init = function (options) { self.type = options.type; self.cost = options.baseCost; self.baseCost = options.baseCost; self.cps = options.type === 'cursor' ? 1 : options.cps; self.baseCps = options.cps; self.count = options.count || 0; self.level = options.level || 1; self.costMultiplier = options.costMultiplier || 1.15; // Create visual self.visual = self.attachAsset(options.type, { anchorX: 0.5, anchorY: 0.5, x: 75, y: 60 }); // Create button background self.background = self.attachAsset('buttonBg', { anchorX: 0.5, anchorY: 0.5, x: 200, y: 60 }); // Create counts and costs text self.countText = new Text2(self.count.toString(), { size: 60, fill: 0xFFFFFF }); self.countText.anchor.set(0, 0.5); self.countText.x = 140; self.countText.y = 40; self.addChild(self.countText); self.costText = new Text2(formatNumber(self.cost), { size: 40, fill: 0xFFFFFF }); self.costText.anchor.set(0, 0.5); self.costText.x = 140; self.costText.y = 90; self.addChild(self.costText); // Set interactivity self.interactive = true; return self; }; self.updateDisplay = function () { self.countText.setText(self.count.toString()); self.costText.setText(formatNumber(self.cost)); // Visual feedback on affordability if (cookies >= self.cost) { self.background.alpha = 1; } else { self.background.alpha = 0.6; } // Additional check for factory type if (self.type === 'Factory') { if (cookies >= self.cost) { self.background.alpha = 1; } else { self.background.alpha = 0.3; // Make it fainter for factories } } }; self.getCookiesPerSecond = function () { return self.count * self.cps * self.level; }; self.purchase = function () { if (cookies >= self.cost) { cookies -= self.cost; self.count++; self.cost = Math.floor(self.baseCost * Math.pow(self.costMultiplier, self.count)); if (self.type === 'cursor') { cursors = self.count; addCursorAnimation(); } else if (self.type === 'grandma') { grandmas = self.count; LK.getSound('grandma').play(); // Create a new Grandma instance and add it to the game var newGrandma = new Grandma(); newGrandma.x = Math.random() * 2048; // Random x position newGrandma.y = 2732 - 150; // Position at the bottom of the screen game.addChild(newGrandma); grandmas = self.count; LK.getSound('grandma').play(); } else if (self.type === 'Factory') { var newFactory = new Factory(); newFactory.x = 2048 - 100; // Position on the right edge newFactory.y = Math.random() * 2732; // Random y position game.addChild(newFactory); factories.push(newFactory); if (factories === 1) { // Create a circle in the top right corner var topRightCircle = LK.getAsset('cookieChip', { anchorX: 0.5, anchorY: 0.5 }); topRightCircle.scale.set(5); // Increase the size of the circle by 250% topRightCircle.tint = 0x0000FF; // Change color to blue topRightCircle.x = 2048 - topRightCircle.width - 100; // Move at least 100 pixels off the right corner topRightCircle.y = topRightCircle.height + 100; // Move at least 100 pixels off the top corner // Add text to the circle to show the time until factories give money var factoryTimerText = new Text2(newFactory.timer.toString(), { size: 40, fill: 0xFFFFFF }); factoryTimerText.anchor.set(0.5, 0.5); factoryTimerText.x = topRightCircle.x; factoryTimerText.y = topRightCircle.y; game.addChild(factoryTimerText); // Update the text every tick game.update = function () { factoryTimerText.setText(factories.length > 0 ? factories[0].timer.toString() : "0"); }; game.addChild(topRightCircle); } } self.updateDisplay(); updateCookieDisplay(); updateCpsDisplay(); updateCpsDisplay(); // Play buy sound LK.getSound('buy').play(); // Animation tween(self.visual, { scale: 1.3 }, { duration: 300, easing: tween.easeOut, onFinish: function onFinish() { tween(self.visual, { scale: 1 }, { duration: 300, easing: tween.easeIn }); } }); return true; } return false; }; self.down = function (x, y, obj) { self.purchase(); }; self.upgradeProducer = function (newLevel) { if (newLevel > self.level) { self.level = newLevel; self.cps = self.baseCps * self.level; if (self.type === 'grandma' && self.level === 2) { self.cps *= 8; // Double the amount by 8 at level 2 } if (self.type === 'cursor' && self.level === 2) { self.cps = 2; // Set cursor cps to 2 at level 2 } if (self.type === 'cursor') { cursorLevel = self.level; } else if (self.type === 'grandma') { grandmaLevel = self.level; } updateCpsDisplay(); if (self.type === 'cursor') { updateCpsDisplay(); // Ensure display updates when cursor level changes } return true; } return false; }; return self; }); var Upgrade = Container.expand(function () { var self = Container.call(this); self.init = function (options) { self.type = options.type; self.cost = options.cost; self.level = options.level; self.multiplier = options.multiplier || 2; self.purchased = false; // Create visual self.visual = self.attachAsset('upgrade', { anchorX: 0.5, anchorY: 0.5, x: 60, y: 60 }); // Add image of what the upgrade buys to the left self.image = self.attachAsset(self.type, { anchorX: 0.5, anchorY: 0.5, x: -120, y: 60 }); self.addChild(self.image); // Create level and cost text self.levelText = new Text2("Lvl " + self.level, { size: 30, fill: 0xFFFFFF }); self.levelText.anchor.set(0.5, 0.5); self.levelText.x = 60; self.levelText.y = 30; self.addChild(self.levelText); self.costText = new Text2(formatNumber(self.cost), { size: 30, fill: 0xFFFFFF }); self.costText.anchor.set(0.5, 0.5); self.costText.x = 60; self.costText.y = 90; self.addChild(self.costText); // Set interactivity self.interactive = true; return self; }; self.updateDisplay = function () { // Visual feedback on affordability if (cookies >= self.cost) { self.visual.alpha = 1; } else { self.visual.alpha = 0.6; } }; self.down = function (x, y, obj) { if (cookies >= self.cost) { cookies -= self.cost; // Apply upgrade based on type if (self.type === 'cursor') { cursorProducer.upgradeProducer(self.level + 1); self.level++; self.cost *= 4; self.levelText.setText("Lvl " + self.level); self.costText.setText(formatNumber(self.cost)); } else if (self.type === 'grandma') { grandmaProducer.upgradeProducer(self.level + 1); self.level++; self.cost *= 6; self.levelText.setText("Lvl " + self.level); self.costText.setText(formatNumber(self.cost)); } else if (self.type === 'Factory') { factoryProducer.upgradeProducer(self.level + 1); self.level++; self.cost *= 8; self.levelText.setText("Lvl " + self.level); self.costText.setText(formatNumber(self.cost)); } updateCookieDisplay(); updateCpsDisplay(); updateCpsDisplay(); // Play buy sound LK.getSound('buy').play(); return true; } return false; }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x8B4513 }); /**** * Game Code ****/ function updateFactories() { for (var i = 0; i < factories.length; i++) { factories[i].update(); } } // Function to add cursor animation around the cookie function addCursorAnimation() { var cursorAsset = LK.getAsset('cursor', { anchorX: 0.5, anchorY: 0.5 }); var angle = 0; var radius = 300; // Distance from the cookie var centerX = cookieObj.x; var centerY = cookieObj.y; // Update function to animate cursor around the cookie cursorAsset.update = function () { angle += 0.01; // Speed of rotation cursorAsset.x = centerX + Math.cos(angle) * radius; cursorAsset.y = centerY + Math.sin(angle) * radius; }; game.addChild(cursorAsset); } var factories = []; var cookies = 0; var cursors = 0; var grandmas = 0; var cursorLevel = 1; var grandmaLevel = 1; var cookiesPerClick = 1; var lastTimestamp = Date.now(); // UI elements var cookieDisplay; var cpsDisplay; var cookieObj; var cursorProducer; var grandmaProducer; var factoryProducer; var upgrades = []; // Helper functions function formatNumber(num) { if (num >= 1e27) { return (num / 1e27).toFixed(1) + "O"; // Octillions } else if (num >= 1e24) { return (num / 1e24).toFixed(1) + "SP"; // Septillions } else if (num >= 1e21) { return (num / 1e21).toFixed(1) + "SX"; // Sextillions } else if (num >= 1e18) { return (num / 1e18).toFixed(1) + "QT"; // Quintillions } else if (num >= 1e15) { return (num / 1e15).toFixed(1) + "QD"; // Quadrillions } else if (num >= 1e12) { return (num / 1e12).toFixed(1) + "T"; // Trillions } else if (num >= 1e9) { return (num / 1e9).toFixed(1) + "B"; // Billions } else if (num >= 1e6) { return (num / 1e6).toFixed(1) + "M"; // Millions } else if (num >= 1e3) { return (num / 1e3).toFixed(1) + "K"; // Thousands } return Math.floor(num); } function updateCookieDisplay() { cookieDisplay.setText(formatNumber(cookies) + " cookies"); // Save to storage storage.cookies = cookies; storage.cursors = cursors; storage.grandmas = grandmas; storage.cursorLevel = cursorLevel; storage.grandmaLevel = grandmaLevel; storage.lastTimestamp = Date.now(); // Update producers affordability cursorProducer.updateDisplay(); grandmaProducer.updateDisplay(); // Update upgrades affordability for (var i = 0; i < upgrades.length; i++) { if (upgrades[i].visible) { upgrades[i].updateDisplay(); } } } function updateCpsDisplay() { var totalCps = getCookiesPerSecond(); cpsDisplay.setText(formatNumber(totalCps) + " per second"); } function getCookiesPerSecond() { var cursorCps = cursorProducer ? cursorProducer.count * cursorProducer.level : 0; var grandmaCps = grandmaProducer ? (grandmaProducer.level === 2 ? 8 : 6) * Math.pow(1.5, grandmaProducer.count - 1) * grandmaProducer.count : 0; var factoryCps = factoryProducer ? factoryProducer.count * factoryProducer.level * 5000000 / Math.max(1, 30 - (factoryProducer.level - 1) * 3) : 0; return cursorCps + grandmaCps + factoryCps; } function calculateOfflineCookies() { var now = Date.now(); var timeDiff = (now - lastTimestamp) / 1000; // convert to seconds if (timeDiff > 0) { var cps = getCookiesPerSecond(); var offlineCookies = cps * timeDiff; if (offlineCookies > 0) { cookies += offlineCookies; // Create notification about offline cookies if (offlineCookies >= 1) { var offlineText = new Text2("You earned " + formatNumber(offlineCookies) + " cookies while away!", { size: 60, fill: 0xFFD700 }); offlineText.anchor.set(0.5, 0.5); offlineText.x = 2048 / 2; offlineText.y = 300; game.addChild(offlineText); // Fade out after a few seconds LK.setTimeout(function () { tween(offlineText, { alpha: 0 }, { duration: 1000, onFinish: function onFinish() { offlineText.destroy(); } }); }, 3000); } } } lastTimestamp = now; storage.lastTimestamp = now; } // Initialize game components function initGameComponents() { // Set background color game.setBackgroundColor(0xFDEBD0); // Play background music LK.playMusic('bgmusic'); // Calculate offline earnings calculateOfflineCookies(); // Cookie counter display cookieDisplay = new Text2(formatNumber(cookies) + " cookies", { size: 100, fill: 0x4B2504 }); cookieDisplay.anchor.set(0.5, 0); LK.gui.top.addChild(cookieDisplay); cookieDisplay.y = 100; // CPS display cpsDisplay = new Text2(formatNumber(getCookiesPerSecond()) + " per second", { size: 60, fill: 0x5D4037 }); cpsDisplay.anchor.set(0.5, 0); LK.gui.top.addChild(cpsDisplay); cpsDisplay.y = 220; // Create the cookie cookieObj = new Cookie(); cookieObj.x = 2048 / 2; cookieObj.y = 800; cookieObj.scale.set(1.2); game.addChild(cookieObj); // Create producers // Cursor cursorProducer = new Producer(); cursorProducer.init({ type: 'cursor', baseCost: 15, cps: 0.1, count: cursors, level: cursorLevel }); cursorProducer.x = 200; cursorProducer.y = 1300; game.addChild(cursorProducer); // Grandma grandmaProducer = new Producer(); grandmaProducer.init({ type: 'grandma', baseCost: 100, cps: 1, count: grandmas, level: grandmaLevel }); grandmaProducer.x = 200; grandmaProducer.y = 1500; game.addChild(grandmaProducer); // Create separate upgrade buttons for cursors and grandmas var cursorUpgradeButton = new Upgrade(); cursorUpgradeButton.init({ type: 'cursor', cost: 50, level: 1, multiplier: 1.5 }); cursorUpgradeButton.x = 650; cursorUpgradeButton.y = 1300; game.addChild(cursorUpgradeButton); upgrades.push(cursorUpgradeButton); var grandmaUpgradeButton = new Upgrade(); grandmaUpgradeButton.init({ type: 'grandma', cost: 200, level: 1, multiplier: 1.5 }); grandmaUpgradeButton.x = 650; grandmaUpgradeButton.y = 1500; game.addChild(grandmaUpgradeButton); upgrades.push(grandmaUpgradeButton); // Factory factoryProducer = new Producer(); factoryProducer.init({ type: 'Factory', baseCost: 10000000, cps: 0, count: 0, level: 1 }); factoryProducer.x = 200; factoryProducer.y = 1700; game.addChild(factoryProducer); // Factory Upgrade Button var factoryUpgradeButton = new Upgrade(); factoryUpgradeButton.init({ type: 'Factory', cost: 50000000, level: 1, multiplier: 2 }); factoryUpgradeButton.x = 650; factoryUpgradeButton.y = 1700; game.addChild(factoryUpgradeButton); upgrades.push(factoryUpgradeButton); // Update displays updateCookieDisplay(); updateCpsDisplay(); // Hide upgrades if their prerequisites aren't met if (cursorLevel >= 2) { cursorUpgrade.visible = false; cursorUpgrade.purchased = true; } if (grandmaLevel >= 2) { grandmaUpgrade.visible = false; grandmaUpgrade.purchased = true; } if (cookiesPerClick >= 2) { clickUpgrade.visible = false; clickUpgrade.purchased = true; } } // Animation for automatic cookie production function createAutoCookieAnimation() { // Create a text to show auto cookies var clickText = new Text2("+" + formatNumber(getCookiesPerSecond()), { size: 40, fill: 0xFFD700 }); clickText.anchor.set(0.5, 0.5); // Random position around the cookie var angle = Math.random() * Math.PI * 2; var distance = 150 + Math.random() * 100; clickText.x = cookieObj.x + Math.cos(angle) * distance; clickText.y = cookieObj.y + Math.sin(angle) * distance; game.addChild(clickText); // Animate text upward and fade out tween(clickText, { y: clickText.y - 100, alpha: 0 }, { duration: 1500, easing: tween.easeOut, onFinish: function onFinish() { clickText.destroy(); } }); } // Initialize game initGameComponents(); // Set up automatic cookie collection var lastAutoTime = Date.now(); var autoAnimationTimer = 0; // Game update loop game.update = function () { // Automatic cookie collection (every 100ms = 10 times per second) var currentTime = Date.now(); var deltaTime = (currentTime - lastAutoTime) / 1000; // Convert to seconds if (deltaTime >= 0.1) { // 100ms // Add cookies from automatic production var cookiesEarned = getCookiesPerSecond() * deltaTime; if (cookiesEarned > 0) { cookies += cookiesEarned; updateCookieDisplay(); // Show animation occasionally autoAnimationTimer += deltaTime; if (autoAnimationTimer >= 0.5) { // Every 0.5 seconds createAutoCookieAnimation(); autoAnimationTimer = 0; } } lastAutoTime = currentTime; } // Save data periodically (every 5 seconds) if (LK.ticks % 300 === 0) { storage.cookies = cookies; storage.cursors = cursors; storage.grandmas = grandmas; storage.cursorLevel = cursorLevel; storage.grandmaLevel = grandmaLevel; storage.lastTimestamp = Date.now(); } };
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1", {
cookies: 0,
cursors: 0,
grandmas: 0,
cursorLevel: 1,
grandmaLevel: 1,
lastTimestamp: "undefined"
});
/****
* Classes
****/
var Cookie = Container.expand(function () {
var self = Container.call(this);
var cookie = self.attachAsset('cookie', {
anchorX: 0.5,
anchorY: 0.5
});
self.startScale = 1;
self.down = function (x, y, obj) {
self.isPressed = true;
self.scale.set(self.startScale * 0.95);
// Add cookie to count
var cps = getCookiesPerSecond();
cookies += cps > 0 ? cps : 1;
updateCookieDisplay();
// Create click animation
self.showClickAnimation();
// Play sound
LK.getSound('click').play();
};
self.up = function (x, y, obj) {
self.isPressed = false;
self.scale.set(self.startScale);
};
self.showClickAnimation = function () {
// Create a text to show cookies per click
var cps = getCookiesPerSecond();
var clickValue = cps > 0 ? cps : cookiesPerClick;
var clickText = new Text2("+" + formatNumber(clickValue), {
size: 80,
fill: 0xFFFFFF
});
clickText.anchor.set(0.5, 0.5);
// Random position around the click point
var randomOffset = 100;
clickText.x = Math.random() * randomOffset - randomOffset / 2;
clickText.y = -50;
self.addChild(clickText);
// Animate text upward and fade out
tween(clickText, {
y: clickText.y - 150,
alpha: 0
}, {
duration: 1000,
easing: tween.easeOut,
onFinish: function onFinish() {
clickText.destroy();
}
});
};
return self;
});
var CookieChip = Container.expand(function () {
var self = Container.call(this);
var chip = self.attachAsset('cookieChip', {
anchorX: 0.5,
anchorY: 0.5
});
return self;
});
var Factory = Container.expand(function () {
var self = Container.call(this);
var factoryGraphics = self.attachAsset('Factory', {
anchorX: 0.5,
anchorY: 0.5
});
self.timer = 30 * 60; // Initial timer for factory production in frames
self.productionAmount = 5000000; // Initial production amount
self.level = 1;
self.update = function () {
if (self.timer > 0) {
self.timer--;
} else {
cookies += self.productionAmount;
updateCookieDisplay();
// Reset all factory timers to sync them
for (var i = 0; i < factories.length; i++) {
factories[i].timer = Math.max(1, 30 - (factories[i].level - 1) * 3);
}
}
};
self.upgrade = function () {
self.level++;
self.productionAmount *= 2; // Double the production amount
self.timer = Math.max(1, 30 - (self.level - 1) * 3); // Decrease timer by 3 seconds per level
};
return self;
});
var Grandma = Container.expand(function () {
var self = Container.call(this);
var grandmaGraphics = self.attachAsset('grandma', {
anchorX: 0.5,
anchorY: 0.5
});
// List of names for grandmas
var names = ["Mary", "Jane", "Scooter", "Sharda", "Caroline"];
// Assign a random name to the grandma
self.name = names[Math.floor(Math.random() * names.length)];
// Display the name when hovered
self.interactive = true;
self.down = function () {
var nameText = new Text2(self.name, {
size: 40,
fill: 0xFFFFFF
});
nameText.anchor.set(0.5, 0.5);
nameText.x = self.x;
nameText.y = self.y - 100; // Position above the grandma
game.addChild(nameText);
// Remove the name text after a short delay
LK.setTimeout(function () {
nameText.destroy();
}, 2000);
};
return self;
});
var Producer = Container.expand(function () {
var self = Container.call(this);
self.init = function (options) {
self.type = options.type;
self.cost = options.baseCost;
self.baseCost = options.baseCost;
self.cps = options.type === 'cursor' ? 1 : options.cps;
self.baseCps = options.cps;
self.count = options.count || 0;
self.level = options.level || 1;
self.costMultiplier = options.costMultiplier || 1.15;
// Create visual
self.visual = self.attachAsset(options.type, {
anchorX: 0.5,
anchorY: 0.5,
x: 75,
y: 60
});
// Create button background
self.background = self.attachAsset('buttonBg', {
anchorX: 0.5,
anchorY: 0.5,
x: 200,
y: 60
});
// Create counts and costs text
self.countText = new Text2(self.count.toString(), {
size: 60,
fill: 0xFFFFFF
});
self.countText.anchor.set(0, 0.5);
self.countText.x = 140;
self.countText.y = 40;
self.addChild(self.countText);
self.costText = new Text2(formatNumber(self.cost), {
size: 40,
fill: 0xFFFFFF
});
self.costText.anchor.set(0, 0.5);
self.costText.x = 140;
self.costText.y = 90;
self.addChild(self.costText);
// Set interactivity
self.interactive = true;
return self;
};
self.updateDisplay = function () {
self.countText.setText(self.count.toString());
self.costText.setText(formatNumber(self.cost));
// Visual feedback on affordability
if (cookies >= self.cost) {
self.background.alpha = 1;
} else {
self.background.alpha = 0.6;
}
// Additional check for factory type
if (self.type === 'Factory') {
if (cookies >= self.cost) {
self.background.alpha = 1;
} else {
self.background.alpha = 0.3; // Make it fainter for factories
}
}
};
self.getCookiesPerSecond = function () {
return self.count * self.cps * self.level;
};
self.purchase = function () {
if (cookies >= self.cost) {
cookies -= self.cost;
self.count++;
self.cost = Math.floor(self.baseCost * Math.pow(self.costMultiplier, self.count));
if (self.type === 'cursor') {
cursors = self.count;
addCursorAnimation();
} else if (self.type === 'grandma') {
grandmas = self.count;
LK.getSound('grandma').play();
// Create a new Grandma instance and add it to the game
var newGrandma = new Grandma();
newGrandma.x = Math.random() * 2048; // Random x position
newGrandma.y = 2732 - 150; // Position at the bottom of the screen
game.addChild(newGrandma);
grandmas = self.count;
LK.getSound('grandma').play();
} else if (self.type === 'Factory') {
var newFactory = new Factory();
newFactory.x = 2048 - 100; // Position on the right edge
newFactory.y = Math.random() * 2732; // Random y position
game.addChild(newFactory);
factories.push(newFactory);
if (factories === 1) {
// Create a circle in the top right corner
var topRightCircle = LK.getAsset('cookieChip', {
anchorX: 0.5,
anchorY: 0.5
});
topRightCircle.scale.set(5); // Increase the size of the circle by 250%
topRightCircle.tint = 0x0000FF; // Change color to blue
topRightCircle.x = 2048 - topRightCircle.width - 100; // Move at least 100 pixels off the right corner
topRightCircle.y = topRightCircle.height + 100; // Move at least 100 pixels off the top corner
// Add text to the circle to show the time until factories give money
var factoryTimerText = new Text2(newFactory.timer.toString(), {
size: 40,
fill: 0xFFFFFF
});
factoryTimerText.anchor.set(0.5, 0.5);
factoryTimerText.x = topRightCircle.x;
factoryTimerText.y = topRightCircle.y;
game.addChild(factoryTimerText);
// Update the text every tick
game.update = function () {
factoryTimerText.setText(factories.length > 0 ? factories[0].timer.toString() : "0");
};
game.addChild(topRightCircle);
}
}
self.updateDisplay();
updateCookieDisplay();
updateCpsDisplay();
updateCpsDisplay();
// Play buy sound
LK.getSound('buy').play();
// Animation
tween(self.visual, {
scale: 1.3
}, {
duration: 300,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(self.visual, {
scale: 1
}, {
duration: 300,
easing: tween.easeIn
});
}
});
return true;
}
return false;
};
self.down = function (x, y, obj) {
self.purchase();
};
self.upgradeProducer = function (newLevel) {
if (newLevel > self.level) {
self.level = newLevel;
self.cps = self.baseCps * self.level;
if (self.type === 'grandma' && self.level === 2) {
self.cps *= 8; // Double the amount by 8 at level 2
}
if (self.type === 'cursor' && self.level === 2) {
self.cps = 2; // Set cursor cps to 2 at level 2
}
if (self.type === 'cursor') {
cursorLevel = self.level;
} else if (self.type === 'grandma') {
grandmaLevel = self.level;
}
updateCpsDisplay();
if (self.type === 'cursor') {
updateCpsDisplay(); // Ensure display updates when cursor level changes
}
return true;
}
return false;
};
return self;
});
var Upgrade = Container.expand(function () {
var self = Container.call(this);
self.init = function (options) {
self.type = options.type;
self.cost = options.cost;
self.level = options.level;
self.multiplier = options.multiplier || 2;
self.purchased = false;
// Create visual
self.visual = self.attachAsset('upgrade', {
anchorX: 0.5,
anchorY: 0.5,
x: 60,
y: 60
});
// Add image of what the upgrade buys to the left
self.image = self.attachAsset(self.type, {
anchorX: 0.5,
anchorY: 0.5,
x: -120,
y: 60
});
self.addChild(self.image);
// Create level and cost text
self.levelText = new Text2("Lvl " + self.level, {
size: 30,
fill: 0xFFFFFF
});
self.levelText.anchor.set(0.5, 0.5);
self.levelText.x = 60;
self.levelText.y = 30;
self.addChild(self.levelText);
self.costText = new Text2(formatNumber(self.cost), {
size: 30,
fill: 0xFFFFFF
});
self.costText.anchor.set(0.5, 0.5);
self.costText.x = 60;
self.costText.y = 90;
self.addChild(self.costText);
// Set interactivity
self.interactive = true;
return self;
};
self.updateDisplay = function () {
// Visual feedback on affordability
if (cookies >= self.cost) {
self.visual.alpha = 1;
} else {
self.visual.alpha = 0.6;
}
};
self.down = function (x, y, obj) {
if (cookies >= self.cost) {
cookies -= self.cost;
// Apply upgrade based on type
if (self.type === 'cursor') {
cursorProducer.upgradeProducer(self.level + 1);
self.level++;
self.cost *= 4;
self.levelText.setText("Lvl " + self.level);
self.costText.setText(formatNumber(self.cost));
} else if (self.type === 'grandma') {
grandmaProducer.upgradeProducer(self.level + 1);
self.level++;
self.cost *= 6;
self.levelText.setText("Lvl " + self.level);
self.costText.setText(formatNumber(self.cost));
} else if (self.type === 'Factory') {
factoryProducer.upgradeProducer(self.level + 1);
self.level++;
self.cost *= 8;
self.levelText.setText("Lvl " + self.level);
self.costText.setText(formatNumber(self.cost));
}
updateCookieDisplay();
updateCpsDisplay();
updateCpsDisplay();
// Play buy sound
LK.getSound('buy').play();
return true;
}
return false;
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x8B4513
});
/****
* Game Code
****/
function updateFactories() {
for (var i = 0; i < factories.length; i++) {
factories[i].update();
}
}
// Function to add cursor animation around the cookie
function addCursorAnimation() {
var cursorAsset = LK.getAsset('cursor', {
anchorX: 0.5,
anchorY: 0.5
});
var angle = 0;
var radius = 300; // Distance from the cookie
var centerX = cookieObj.x;
var centerY = cookieObj.y;
// Update function to animate cursor around the cookie
cursorAsset.update = function () {
angle += 0.01; // Speed of rotation
cursorAsset.x = centerX + Math.cos(angle) * radius;
cursorAsset.y = centerY + Math.sin(angle) * radius;
};
game.addChild(cursorAsset);
}
var factories = [];
var cookies = 0;
var cursors = 0;
var grandmas = 0;
var cursorLevel = 1;
var grandmaLevel = 1;
var cookiesPerClick = 1;
var lastTimestamp = Date.now();
// UI elements
var cookieDisplay;
var cpsDisplay;
var cookieObj;
var cursorProducer;
var grandmaProducer;
var factoryProducer;
var upgrades = [];
// Helper functions
function formatNumber(num) {
if (num >= 1e27) {
return (num / 1e27).toFixed(1) + "O"; // Octillions
} else if (num >= 1e24) {
return (num / 1e24).toFixed(1) + "SP"; // Septillions
} else if (num >= 1e21) {
return (num / 1e21).toFixed(1) + "SX"; // Sextillions
} else if (num >= 1e18) {
return (num / 1e18).toFixed(1) + "QT"; // Quintillions
} else if (num >= 1e15) {
return (num / 1e15).toFixed(1) + "QD"; // Quadrillions
} else if (num >= 1e12) {
return (num / 1e12).toFixed(1) + "T"; // Trillions
} else if (num >= 1e9) {
return (num / 1e9).toFixed(1) + "B"; // Billions
} else if (num >= 1e6) {
return (num / 1e6).toFixed(1) + "M"; // Millions
} else if (num >= 1e3) {
return (num / 1e3).toFixed(1) + "K"; // Thousands
}
return Math.floor(num);
}
function updateCookieDisplay() {
cookieDisplay.setText(formatNumber(cookies) + " cookies");
// Save to storage
storage.cookies = cookies;
storage.cursors = cursors;
storage.grandmas = grandmas;
storage.cursorLevel = cursorLevel;
storage.grandmaLevel = grandmaLevel;
storage.lastTimestamp = Date.now();
// Update producers affordability
cursorProducer.updateDisplay();
grandmaProducer.updateDisplay();
// Update upgrades affordability
for (var i = 0; i < upgrades.length; i++) {
if (upgrades[i].visible) {
upgrades[i].updateDisplay();
}
}
}
function updateCpsDisplay() {
var totalCps = getCookiesPerSecond();
cpsDisplay.setText(formatNumber(totalCps) + " per second");
}
function getCookiesPerSecond() {
var cursorCps = cursorProducer ? cursorProducer.count * cursorProducer.level : 0;
var grandmaCps = grandmaProducer ? (grandmaProducer.level === 2 ? 8 : 6) * Math.pow(1.5, grandmaProducer.count - 1) * grandmaProducer.count : 0;
var factoryCps = factoryProducer ? factoryProducer.count * factoryProducer.level * 5000000 / Math.max(1, 30 - (factoryProducer.level - 1) * 3) : 0;
return cursorCps + grandmaCps + factoryCps;
}
function calculateOfflineCookies() {
var now = Date.now();
var timeDiff = (now - lastTimestamp) / 1000; // convert to seconds
if (timeDiff > 0) {
var cps = getCookiesPerSecond();
var offlineCookies = cps * timeDiff;
if (offlineCookies > 0) {
cookies += offlineCookies;
// Create notification about offline cookies
if (offlineCookies >= 1) {
var offlineText = new Text2("You earned " + formatNumber(offlineCookies) + " cookies while away!", {
size: 60,
fill: 0xFFD700
});
offlineText.anchor.set(0.5, 0.5);
offlineText.x = 2048 / 2;
offlineText.y = 300;
game.addChild(offlineText);
// Fade out after a few seconds
LK.setTimeout(function () {
tween(offlineText, {
alpha: 0
}, {
duration: 1000,
onFinish: function onFinish() {
offlineText.destroy();
}
});
}, 3000);
}
}
}
lastTimestamp = now;
storage.lastTimestamp = now;
}
// Initialize game components
function initGameComponents() {
// Set background color
game.setBackgroundColor(0xFDEBD0);
// Play background music
LK.playMusic('bgmusic');
// Calculate offline earnings
calculateOfflineCookies();
// Cookie counter display
cookieDisplay = new Text2(formatNumber(cookies) + " cookies", {
size: 100,
fill: 0x4B2504
});
cookieDisplay.anchor.set(0.5, 0);
LK.gui.top.addChild(cookieDisplay);
cookieDisplay.y = 100;
// CPS display
cpsDisplay = new Text2(formatNumber(getCookiesPerSecond()) + " per second", {
size: 60,
fill: 0x5D4037
});
cpsDisplay.anchor.set(0.5, 0);
LK.gui.top.addChild(cpsDisplay);
cpsDisplay.y = 220;
// Create the cookie
cookieObj = new Cookie();
cookieObj.x = 2048 / 2;
cookieObj.y = 800;
cookieObj.scale.set(1.2);
game.addChild(cookieObj);
// Create producers
// Cursor
cursorProducer = new Producer();
cursorProducer.init({
type: 'cursor',
baseCost: 15,
cps: 0.1,
count: cursors,
level: cursorLevel
});
cursorProducer.x = 200;
cursorProducer.y = 1300;
game.addChild(cursorProducer);
// Grandma
grandmaProducer = new Producer();
grandmaProducer.init({
type: 'grandma',
baseCost: 100,
cps: 1,
count: grandmas,
level: grandmaLevel
});
grandmaProducer.x = 200;
grandmaProducer.y = 1500;
game.addChild(grandmaProducer);
// Create separate upgrade buttons for cursors and grandmas
var cursorUpgradeButton = new Upgrade();
cursorUpgradeButton.init({
type: 'cursor',
cost: 50,
level: 1,
multiplier: 1.5
});
cursorUpgradeButton.x = 650;
cursorUpgradeButton.y = 1300;
game.addChild(cursorUpgradeButton);
upgrades.push(cursorUpgradeButton);
var grandmaUpgradeButton = new Upgrade();
grandmaUpgradeButton.init({
type: 'grandma',
cost: 200,
level: 1,
multiplier: 1.5
});
grandmaUpgradeButton.x = 650;
grandmaUpgradeButton.y = 1500;
game.addChild(grandmaUpgradeButton);
upgrades.push(grandmaUpgradeButton);
// Factory
factoryProducer = new Producer();
factoryProducer.init({
type: 'Factory',
baseCost: 10000000,
cps: 0,
count: 0,
level: 1
});
factoryProducer.x = 200;
factoryProducer.y = 1700;
game.addChild(factoryProducer);
// Factory Upgrade Button
var factoryUpgradeButton = new Upgrade();
factoryUpgradeButton.init({
type: 'Factory',
cost: 50000000,
level: 1,
multiplier: 2
});
factoryUpgradeButton.x = 650;
factoryUpgradeButton.y = 1700;
game.addChild(factoryUpgradeButton);
upgrades.push(factoryUpgradeButton);
// Update displays
updateCookieDisplay();
updateCpsDisplay();
// Hide upgrades if their prerequisites aren't met
if (cursorLevel >= 2) {
cursorUpgrade.visible = false;
cursorUpgrade.purchased = true;
}
if (grandmaLevel >= 2) {
grandmaUpgrade.visible = false;
grandmaUpgrade.purchased = true;
}
if (cookiesPerClick >= 2) {
clickUpgrade.visible = false;
clickUpgrade.purchased = true;
}
}
// Animation for automatic cookie production
function createAutoCookieAnimation() {
// Create a text to show auto cookies
var clickText = new Text2("+" + formatNumber(getCookiesPerSecond()), {
size: 40,
fill: 0xFFD700
});
clickText.anchor.set(0.5, 0.5);
// Random position around the cookie
var angle = Math.random() * Math.PI * 2;
var distance = 150 + Math.random() * 100;
clickText.x = cookieObj.x + Math.cos(angle) * distance;
clickText.y = cookieObj.y + Math.sin(angle) * distance;
game.addChild(clickText);
// Animate text upward and fade out
tween(clickText, {
y: clickText.y - 100,
alpha: 0
}, {
duration: 1500,
easing: tween.easeOut,
onFinish: function onFinish() {
clickText.destroy();
}
});
}
// Initialize game
initGameComponents();
// Set up automatic cookie collection
var lastAutoTime = Date.now();
var autoAnimationTimer = 0;
// Game update loop
game.update = function () {
// Automatic cookie collection (every 100ms = 10 times per second)
var currentTime = Date.now();
var deltaTime = (currentTime - lastAutoTime) / 1000; // Convert to seconds
if (deltaTime >= 0.1) {
// 100ms
// Add cookies from automatic production
var cookiesEarned = getCookiesPerSecond() * deltaTime;
if (cookiesEarned > 0) {
cookies += cookiesEarned;
updateCookieDisplay();
// Show animation occasionally
autoAnimationTimer += deltaTime;
if (autoAnimationTimer >= 0.5) {
// Every 0.5 seconds
createAutoCookieAnimation();
autoAnimationTimer = 0;
}
}
lastAutoTime = currentTime;
}
// Save data periodically (every 5 seconds)
if (LK.ticks % 300 === 0) {
storage.cookies = cookies;
storage.cursors = cursors;
storage.grandmas = grandmas;
storage.cursorLevel = cursorLevel;
storage.grandmaLevel = grandmaLevel;
storage.lastTimestamp = Date.now();
}
};
an old grandma's face. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
A chocolate chip cookie. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
The outside of a factory in a cartoon style. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows