xxxxxxxxxx
154
let birds = [];
const tileCount = 100;
const noiseScale = 0.03;
var noiseVector, noiseVelocity, noiseAcceleration;
let startScreen = true;
let startButton;
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 = 1;
let birdSpeed = 3;
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.8;
}
// 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);
}
function startSimulation() {
startScreen = false;
startButton.hide();
}
function draw() {
if (startScreen) {
drawStartScreen();
} else {
drawSimulation();
}
}
function drawStartScreen() {
background(252, 230, 252);
}
function drawSimulation() {
// Draw the Perlin noise-based background
background(150, 180, 255);
noiseVelocity.add(noiseAcceleration);
noiseVector.sub(noiseVelocity);
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(252, 230, 252, a);
noStroke();
rect(x, y, tileSize, tileSize);
}
}
// Draw the tree
drawTree();
// Update and display all birds
for (let bird of birds) {
bird.update();
bird.show();
}
}
function drawTree() {
push();
translate(width / 6, height); // Move tree to the left of the canvas
stroke(0);
strokeWeight(2);
randomSeed(42); // Ensures the tree remains static
branch(150);
pop();
}
function branch(length) {
line(0, 0, 0, -length);
translate(0, -length);
length *= 0.67;
if (length > 2) {
let n = floor(random(1, 5));
for (let i = 0; i < n; i++) {
let angle = random(-PI / 2, PI / 2);
push();
rotate(angle);
branch(length);
pop();
}
}
}
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.12, 0.18);
}
update() {
this.x -= this.baseSpeed; // Birds move left
if (this.x < -50) this.x = width + 50;
this.flapAngle += this.flapSpeed;
}
show() {
push();
translate(this.x, this.y);
scale(this.birdSize);
fill(0, 0, 0, 200);
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);
}
}