User prompt
There should be seperate upgrade buttons for grandmas and cursors
User prompt
Instead of having different 'levels', there should be an upgrade button that progressively gets bigger. The current Level 2s we have right now should be the upgrade 2s, but we can keep adding more upgrades.
User prompt
Right now, the display can only go up to billions. Add trillions (T) Quadrillions (QD) Quintillions (QT), Sextillions (SX), Septillions (SP), and Octillions (O). Also, every time you get a grandma, a new one should appear in a random place at the bottom, with a random name. Finally, a level two grandma should give you 8 times the amount of a normal grandma, so reflect that in the cps and when you get money
User prompt
Calculate the number of grandmas correctly. If you have two grandmas, it should be 9 per grandma. If you only have 1 grandma, it should be 6 per grandma. And if you have 3, it would be 12, and so on
User prompt
When you get a grandma, it should be cps = (6 * (1.5 * (# of grandmas)))
User prompt
The calculation still isn't working correctly. Each grandma, at level 1, should have a CPS of 6. So whatever the current cps is, it should be cps + 6. Also, remember the bonuses for having multiple grandmas
User prompt
For every grandma you buy, they should appear at the bottom in a random x pos
User prompt
Make sure that the CPS goes up accordingly. Grandmas give you 2 cookies normally, so if you have two cursors and one grandma, your cps would be 4
User prompt
Make it so you have to click on a grandma to see her name. Also, grandmas should give you 6 cookies a second at level 1, but they have a multiplier of 1.5. So if you have two grandmas, both grandmas would give you 9. If you have 3, all of the grandmas would give you 36. At level two, the amount doubles by 8.
User prompt
When you buy a grandma, it should appear at the bottom of the screen. Each grandma will be given 1 of 5 names. If you hover your mouse over the grandma, it will read their name. The names are: Mary, Jane, Scooter, Sharda, and Caroline
User prompt
When you upgrade to level 2, the cursors should give you +2. Also, the clicks per second and +(value) counters should update
User prompt
The clicks per second display should update as you buy more upgrades
User prompt
Every time you buy a cursor, a 'cursor' asset should start circling the cookie
User prompt
The buy clicker option should still be with the other buttons
User prompt
At the start of the game, you should start at 0 cookies and 0 clicks per second
User prompt
Make the clickers circle the cookie. Also, on level 1, each clicker should give you 1 click per second. finally, for every cursor click, the +(value) should show the amount you got, not 0
Code edit (1 edits merged)
Please save this source code
User prompt
Cookie Incremental: Tap, Cursors & Grandmas Empire
User prompt
add cursors and grandmas
Initial prompt
Make a Cookie Clicker clone
/**** * 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