xxxxxxxxxx
211
let birds = [];
const tileCount = 100;
const noiseScale = 0.03;
let noiseVector, noiseVelocity, noiseAcceleration;
let startScreen = true;
let startButton;
let windSlider;
let dayButton, nightButton;
let isDay = true;
let skyColor;
let cloudColor;
function setup() {
createCanvas(windowWidth, windowHeight);
noiseVector = createVector(0, 0);
noiseVelocity = createVector(0.03, 0);
noiseAcceleration = createVector(random(-0.005, 0.005), random(-0.005, 0.005));
// Initialize birds
let startX = windowWidth;
let startY = height / 2;
let birdSize = 0.5;
let birdSpeed = 2;
for (let i = 0; i < 7; i++) {
let x = startX + i * 60;
let y = startY + i * 20 * (i % 2 === 0 ? 1 : -1);
birds.push(new Bird(x, y, birdSize, birdSpeed));
birdSize *= 0.9;
}
// Create start button
startButton = createButton("bird watching");
startButton.position(width / 2 - 75, height / 2 - 20);
startButton.size(150, 50);
startButton.style("color", "black");
startButton.style("font-size", "15px");
startButton.mousePressed(startSimulation);
// Create wind slider (hidden initially)
windSlider = createSlider(0.5, 2, 1.2, 0.05);
windSlider.position(20, 20);
windSlider.style("width", "100px");
windSlider.hide(); // Hide the slider at the start screen
// Create day and night buttons (hidden initially)
dayButton = createButton("Day");
dayButton.position(width - 160, 20);
dayButton.size(60, 30);
dayButton.mousePressed(setDay);
dayButton.hide();
nightButton = createButton("Night");
nightButton.position(width - 90, 20);
nightButton.size(60, 30);
nightButton.mousePressed(setNight);
nightButton.hide();
// Set initial colors
skyColor = color(150, 180, 255);
cloudColor = color(252, 230, 252);
}
function startSimulation() {
startScreen = false;
startButton.hide();
windSlider.show(); // Show the slider when the simulation starts
dayButton.show();
nightButton.show();
// Set the initial state to "Day" and grey out the Day button
isDay = true;
dayButton.style("background-color", "grey");
}
function setDay() {
isDay = true;
dayButton.style("background-color", "grey"); // Grey out the "Day" button when pressed
nightButton.style("background-color", ""); // Remove the grey color from the "Night" button
}
function setNight() {
isDay = false;
nightButton.style("background-color", "grey"); // Grey out the "Night" button when pressed
dayButton.style("background-color", ""); // Remove the grey color from the "Day" button
}
function draw() {
if (startScreen) {
drawStartScreen();
} else {
drawSimulation();
drawTree(); // Draw the fractal tree on the left side
}
}
function drawStartScreen() {
background(252, 230, 252);
}
function drawSimulation() {
let windFactor = windSlider.value();
// Transition background colors
let targetSkyColor = isDay ? color(150, 180, 255) : color(0, 50, 150);
let targetCloudColor = isDay ? color(252, 230, 252) : color(115, 61, 96); // Slightly darker pink for night
skyColor = lerpColor(skyColor, targetSkyColor, 0.01);
cloudColor = lerpColor(cloudColor, targetCloudColor, 0.01);
// Draw the Perlin noise-based background
background(skyColor);
noiseVelocity.add(noiseAcceleration);
noiseVector.add(noiseVelocity.copy().mult(-windFactor)); // Adjust cloud movement based on windFactor
noiseAcceleration.x = random(-0.0005, 0.0005);
noiseAcceleration.y = random(-0.0005, 0.0005);
let tileSize = width / tileCount;
for (let row = 0; row < tileCount; row++) {
for (let col = 0; col < tileCount; col++) {
let x = col * tileSize;
let y = row * tileSize;
let xnoise = noiseVector.x + col * noiseScale;
let ynoise = noiseVector.y + row * noiseScale;
let noiseValue = noise(xnoise, ynoise);
let a = map(noiseValue, 0, 0.5, 0, 210);
fill(cloudColor.levels[0], cloudColor.levels[1], cloudColor.levels[2], a);
noStroke();
rect(x, y, tileSize, tileSize);
}
}
// Update and display all birds
for (let bird of birds) {
bird.update(windFactor);
bird.show();
}
}
class Bird {
constructor(x, y, birdSize, birdSpeed) {
this.x = x;
this.y = y;
this.birdSize = birdSize;
this.baseSpeed = birdSpeed;
this.flapAngle = 0;
this.flapSpeed = random(0.16, 0.18);
}
update(windFactor) {
this.x -= this.baseSpeed / windFactor; // Birds move left, speed affected by windFactor
if (this.x < -50) this.x = width + 50;
this.flapAngle += this.flapSpeed * windFactor; // Adjust flapping speed by windFactor
}
show() {
push();
translate(this.x, this.y);
scale(this.birdSize);
fill(0, 0, 0, 220);
this.drawBird(sin(this.flapAngle));
pop();
}
drawBird(curveFactor) {
let wingY = map(curveFactor, -1, 1, 0, -35);
let wingCurve = map(curveFactor, -1, 1, -25, -50);
beginShape();
vertex(0, 0);
quadraticVertex(-25, -10, -35, wingY);
quadraticVertex(-25, wingCurve, 0, 0);
endShape(CLOSE);
beginShape();
vertex(0, 0);
quadraticVertex(40, -15, 70, wingY);
quadraticVertex(40, wingCurve, 0, 0);
endShape(CLOSE);
}
}
function drawTree() {
let swayFactor = map(windSlider.value(), 0.5, 2, 0, 10); // Map slider value to subtle sway
stroke(77, 52, 50); // Brown color for the trunk
strokeWeight(5);
push();
translate(-500, height + 300 + sin(frameCount * 0.04) * swayFactor); // Add subtle vertical sway
branch(400);
pop();
}
function branch(len) {
if (len > 5) {
line(0, 0, 0, -len);
translate(0, -len);
push();
rotate(radians(50));
branch(len * 0.7);
pop();
push();
rotate(radians(-25));
branch(len * 0.6);
pop();
} else {
stroke(81, 130, 83); // Green color for the leaves
ellipse(0, 0, 5, 5);
}
}