/****
* 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