xxxxxxxxxx
202
let candleCount = 0;
let litCandleCount = 0;
let mode = 'placing';
let confetti = [];
let popperLeft, popperRight;
let candles = [];
function setup() {
createCanvas(400, 400);
strokeCap(SQUARE);
frameRate(30);
textSize(24);
textAlign(CENTER);
// Define popper positions
popperLeft = { x: 50, y: height - 100 };
popperRight = { x: width - 50, y: height - 100 };
}
function draw() {
// Draw a festive background
drawBackground();
// Draw the cake
drawCake();
// Draw all candles from the array
for (let i = 0; i < candles.length; i++) {
candles[i].displayCandle();
if (mode === 'lighting' || mode === 'done') {
if (i >= candleCount - litCandleCount) {
candles[i].drawFire();
}
}
}
// Draw realistic confetti poppers
drawPoppers();
// Display confetti if any
for (let i = confetti.length - 1; i >= 0; i--) {
confetti[i].update();
confetti[i].display();
if (confetti[i].y > height) {
confetti.splice(i, 1);
}
}
}
function drawBackground() {
// Colorful gradient background
for (let i = 0; i < height; i++) {
stroke(lerpColor(color(255, 204, 128), color(255, 77, 77), i / height));
line(0, i, width, i);
}
// Add some floating bubbles for extra festivity
for (let i = 0; i < 10; i++) {
fill(255, 255, 255, 100);
noStroke();
ellipse(random(width), random(height), random(20, 50));
}
}
function drawCake() {
// Cake base
fill(153, 101, 21); // Brown color for the cake
noStroke();
rect(width * 0.2, height * 0.5, width * 0.6, height * 0.2, 20);
// Icing on the cake
fill(255, 192, 203); // Pink icing
rect(width * 0.2, height * 0.45, width * 0.6, height * 0.05, 20);
}
function drawPoppers() {
// Draw left popper (red with details)
fill(255, 0, 0); // Red base
rect(popperLeft.x - 10, popperLeft.y, 20, 40); // Cylinder shape
fill(255, 255, 0); // Yellow cap
triangle(popperLeft.x - 15, popperLeft.y, popperLeft.x + 15, popperLeft.y, popperLeft.x, popperLeft.y - 15);
fill(255, 255, 0); // Ribbons
ellipse(popperLeft.x - 15, popperLeft.y + 10, 10, 5);
ellipse(popperLeft.x + 15, popperLeft.y + 10, 10, 5);
// Draw right popper (blue with details)
fill(0, 0, 255); // Blue base
rect(popperRight.x - 10, popperRight.y, 20, 40); // Cylinder shape
fill(255, 255, 0); // Yellow cap
triangle(popperRight.x - 15, popperRight.y, popperRight.x + 15, popperRight.y, popperRight.x, popperRight.y - 15);
fill(255, 255, 0); // Ribbons
ellipse(popperRight.x - 15, popperRight.y + 10, 10, 5);
ellipse(popperRight.x + 15, popperRight.y + 10, 10, 5);
}
// Define a Candle class
class Candle {
constructor(x, y) {
this.x = x;
this.y = y;
this.lit = false; // Track if the candle is lit
}
// Display the candle on the screen
displayCandle() {
strokeWeight(8);
stroke(240, 230, 140); // Yellowish cream color
line(this.x, this.y, this.x, this.y - height * 0.1); // Shorter candle
}
// Draw the flame for a lit candle
drawFire() {
const fireRed = random(200, 255); // Flickering red and orange colors
const fireGreen = random(fireRed / 2); // Adjust green based on red
stroke(fireRed, fireGreen, 0);
fill(fireRed, fireGreen, 0);
// Create a flickering effect by varying the flame's height and width
const fireHeight = random(15, 30); // Taller flickering flame
const fireWidth = random(5, 15); // Flickering flame width
// Draw two layers of the flame for a more dynamic effect
ellipse(this.x, this.y - height * 0.1 - fireHeight * 0.5, fireWidth, fireHeight);
noStroke();
fill(fireRed, fireGreen, 100);
ellipse(this.x, this.y - height * 0.1 - fireHeight * 0.5 + 5, fireWidth * 0.5, fireHeight * 0.7);
}
}
class Confetti {
constructor(x, y) {
this.x = x;
this.y = y;
this.vx = random(-2, 2);
this.vy = random(-5, -1);
this.size = random(5, 10);
this.color = color(random(255), random(255), random(255));
}
update() {
this.x += this.vx;
this.y += this.vy;
this.vy += 0.1; // Gravity effect
}
display() {
fill(this.color);
noStroke();
ellipse(this.x, this.y, this.size);
}
}
// Add candles with mouse clicks
function mousePressed() {
if (mode === 'placing') {
if (candleCount >= 1 && mouseX > width * 0.8 && mouseY < height * 0.2) {
mode = 'lighting';
} else {
placeCandle();
}
} else if (mode === 'lighting') {
lightCandle();
}
// Check if a popper is clicked
if (dist(mouseX, mouseY, popperLeft.x, popperLeft.y) < 30) {
popConfetti(popperLeft.x, popperLeft.y);
}
if (dist(mouseX, mouseY, popperRight.x, popperRight.y) < 30) {
popConfetti(popperRight.x, popperRight.y);
}
}
function placeCandle() {
let candleX;
const candleSpacing = width * 0.6 / 8; // Evenly space candles across the cake
if (candleCount < 8) {
// Place candles on top of the cake
candleX = width * 0.2 + candleSpacing * candleCount + candleSpacing / 2;
candles.push(new Candle(candleX, height * 0.45)); // Adjust height for candles on the cake
candleCount++;
if (candleCount === 8) {
mode = 'lighting';
}
}
}
function lightCandle() {
litCandleCount++;
if (litCandleCount == candleCount) {
mode = 'done';
}
}
function popConfetti(x, y) {
for (let i = 0; i < 50; i++) {
confetti.push(new Confetti(x, y));
}
}