Step 4: Add Auto-Clickers
Now let's add a way to earn cookies automatically! Players can buy "auto-clickers" that generate cookies every second, creating an idle game mechanic.
New Variables for Upgrades
Add these new variables to track the upgrade system:
let score = 0;
let cookieSize = 150;
let floatingTexts = [];
let autoClickers = 0; // Add this
let autoClickerCost = 10; // Add this
What these do:
autoClickers- How many auto-clickers the player has purchasedautoClickerCost- Current price to buy the next auto-clicker (starts at 10)
Creating the Upgrade Button
We'll use rectangle coordinates to track our button. Add these variables:
let score = 0;
let cookieSize = 150;
let floatingTexts = [];
let autoClickers = 0;
let autoClickerCost = 10;
// Button properties
let buttonX;
let buttonY;
let buttonWidth = 200;
let buttonHeight = 60;
In setup(), calculate the button position:
function setup() {
createCanvas(800, 600);
// Position button at bottom center
buttonX = width/2 - buttonWidth/2;
buttonY = height - 120;
}
Breaking it down:
buttonX = width/2 - buttonWidth/2centers the button horizontallywidth/2is the center of the canvas- Subtract half the button width to align its left edge
buttonY = height - 120positions it near the bottom (120 pixels from bottom)
Auto-Generating Cookies
In your draw() function, add code to automatically generate cookies:
function draw() {
background(240);
// Auto-generate cookies every second
if (frameCount % 60 === 0 && autoClickers > 0) {
score += autoClickers;
}
// ... rest of your code
}
Breaking it down:
The Modulo Operator
if (frameCount % 60 === 0 && autoClickers > 0) {
score += autoClickers;
}
frameCountis a p5.js variable that counts frames since the program started%is the modulo operator - it gives the remainder after divisionframeCount % 60 === 0is true every 60 frames (once per second at 60 FPS)autoClickers > 0checks that we actually have auto-clickersscore += autoClickersadds the number of auto-clickers to the score
How modulo works:
- Frame 59:
59 % 60 = 59(not equal to 0) - Frame 60:
60 % 60 = 0✓ (trigger!) - Frame 61:
61 % 60 = 1(not equal to 0) - Frame 120:
120 % 60 = 0✓ (trigger again!)
It's like a repeating timer!
Drawing the Button
Add this to your draw() function to display the button:
function draw() {
background(240);
// Auto-generate cookies
if (frameCount % 60 === 0 && autoClickers > 0) {
score += autoClickers;
}
// ... cookie drawing and floating text code ...
// Draw upgrade button
if (score >= autoClickerCost) {
fill(50, 200, 50); // Green if affordable
} else {
fill(150); // Gray if too expensive
}
rect(buttonX, buttonY, buttonWidth, buttonHeight, 10);
// Button text
fill(255);
textSize(16);
textAlign(CENTER, CENTER);
text('Buy Auto-Clicker', width/2, buttonY + 20);
text('Cost: ' + autoClickerCost, width/2, buttonY + 40);
// Display auto-clicker count
fill(0);
textSize(20);
text('Auto-clickers: ' + autoClickers + ' (+' + autoClickers + '/sec)', width/2, 100);
// ... score display code ...
}
Breaking it down:
Conditional Button Color
if (score >= autoClickerCost) {
fill(50, 200, 50); // Green if affordable
} else {
fill(150); // Gray if too expensive
}
- Checks if player has enough points
- Green button = can buy
- Gray button = cannot afford yet
- This gives visual feedback to the player
Drawing the Button
rect(buttonX, buttonY, buttonWidth, buttonHeight, 10);
rect()draws a rectangle- Position:
buttonX, buttonY(calculated in setup) - Size:
buttonWidth, buttonHeight(200 x 60) 10is the corner radius for rounded corners
Centered Text
textAlign(CENTER, CENTER);
text('Buy Auto-Clicker', width/2, buttonY + 20);
text('Cost: ' + autoClickerCost, width/2, buttonY + 40);
textAlign(CENTER, CENTER)centers text both horizontally and verticallybuttonY + 20andbuttonY + 40position text lines inside the button
Buying Auto-Clickers
Update your mousePressed() function to handle button clicks:
function mousePressed() {
// Check if cookie is clicked
let d = dist(mouseX, mouseY, width/2, height/2);
if (d < 75) {
score++;
cookieSize = 135;
floatingTexts.push({
x: mouseX,
y: mouseY,
alpha: 255,
yOffset: 0
});
}
// Check if upgrade button is clicked
if (mouseX > buttonX && mouseX < buttonX + buttonWidth &&
mouseY > buttonY && mouseY < buttonY + buttonHeight) {
// Check if player can afford it
if (score >= autoClickerCost) {
score -= autoClickerCost; // Deduct the cost
autoClickers++; // Add one auto-clicker
autoClickerCost = Math.floor(autoClickerCost * 1.5); // Increase price
}
}
}
Breaking it down:
Button Click Detection
if (mouseX > buttonX && mouseX < buttonX + buttonWidth &&
mouseY > buttonY && mouseY < buttonY + buttonHeight) {
This checks if the mouse is inside the button rectangle:
mouseX > buttonX- mouse is to the right of left edgemouseX < buttonX + buttonWidth- mouse is to the left of right edgemouseY > buttonY- mouse is below top edgemouseY < buttonY + buttonHeight- mouse is above bottom edge- All four must be true = click is inside button
Purchase Logic
if (score >= autoClickerCost) {
score -= autoClickerCost;
autoClickers++;
autoClickerCost = Math.floor(autoClickerCost * 1.5);
}
- Check if player has enough cookies
- Subtract the cost from score
- Add one auto-clicker
- Increase the price by 50% (multiply by 1.5)
Math.floor()rounds down to whole number
Why increase the price? This is called "exponential scaling" - each upgrade gets more expensive. This creates balanced progression and prevents players from buying everything too quickly!
Complete Code
let score = 0;
let cookieSize = 150;
let floatingTexts = [];
let autoClickers = 0;
let autoClickerCost = 10;
let buttonX, buttonY;
let buttonWidth = 200;
let buttonHeight = 60;
function setup() {
createCanvas(800, 600);
buttonX = width/2 - buttonWidth/2;
buttonY = height - 120;
}
function draw() {
background(240);
// Auto-generate cookies every second
if (frameCount % 60 === 0 && autoClickers > 0) {
score += autoClickers;
}
// Cookie animation
if (cookieSize < 150) {
cookieSize += 2;
}
// Draw cookie
fill('#D2691E');
circle(width/2, height/2 - 50, cookieSize);
// Update floating texts
for (let i = floatingTexts.length - 1; i >= 0; i--) {
let txt = floatingTexts[i];
txt.yOffset += 2;
txt.alpha -= 5;
fill(50, 200, 50, txt.alpha);
textSize(24);
textAlign(CENTER);
text('+1', txt.x, txt.y - txt.yOffset);
if (txt.alpha <= 0) {
floatingTexts.splice(i, 1);
}
}
// Draw upgrade button
if (score >= autoClickerCost) {
fill(50, 200, 50);
} else {
fill(150);
}
rect(buttonX, buttonY, buttonWidth, buttonHeight, 10);
// Button text
fill(255);
textSize(16);
textAlign(CENTER, CENTER);
text('Buy Auto-Clicker', width/2, buttonY + 20);
text('Cost: ' + autoClickerCost, width/2, buttonY + 40);
// Display stats
fill(0);
textSize(32);
textAlign(CENTER);
text('Score: ' + score, width/2, 50);
textSize(20);
text('Auto-clickers: ' + autoClickers + ' (+' + autoClickers + '/sec)', width/2, 100);
}
function mousePressed() {
// Cookie click
let d = dist(mouseX, mouseY, width/2, height/2 - 50);
if (d < 75) {
score++;
cookieSize = 135;
floatingTexts.push({
x: mouseX,
y: mouseY,
alpha: 255,
yOffset: 0
});
}
// Button click
if (mouseX > buttonX && mouseX < buttonX + buttonWidth &&
mouseY > buttonY && mouseY < buttonY + buttonHeight) {
if (score >= autoClickerCost) {
score -= autoClickerCost;
autoClickers++;
autoClickerCost = Math.floor(autoClickerCost * 1.5);
}
}
}
Test It Out!
Run the game and try it:
- ✅ Click cookie until you have 10 points
- ✅ Button turns green when you can afford it
- ✅ Click button to buy first auto-clicker
- ✅ Watch score increase by 1 every second
- ✅ Notice button now costs 15 (increased by 50%)
- ✅ Buy more auto-clickers and watch cookies accumulate faster!
How the Price Scaling Works
Purchase #1: Cost = 10 × 1.5 = 15
Purchase #2: Cost = 15 × 1.5 = 22 (rounded from 22.5)
Purchase #3: Cost = 22 × 1.5 = 33
Purchase #4: Cost = 33 × 1.5 = 49 (rounded from 49.5)
Purchase #5: Cost = 49 × 1.5 = 73 (rounded from 73.5)
Each purchase gets significantly more expensive, creating balanced progression!
What You Learned
- How to use
frameCountand modulo (%) to create timed events - How to detect clicks on rectangular buttons
- How to implement conditional visual feedback (button color changes)
- How to create an upgrade system with increasing costs
- How to use
Math.floor()for integer rounding - How to balance game economy with exponential cost scaling
- How to use
textAlign(CENTER, CENTER)for perfectly centered text