xxxxxxxxxx
119
const tileCount = 100;
const noiseScale = 0.03;
var noiseVector;
var noiseVelocity;
var noiseAcceleration;
let birds = []; // Array to hold all bird objects
function setup() {
createCanvas(windowWidth, windowHeight);
// Initialize vectors for moving noise field
noiseVector = createVector(0, 0); // Starting position
noiseVelocity = createVector(0.03, 0); // Initial slow velocity (left to right)
noiseAcceleration = createVector(random(-0.005, 0.005), random(-0.005, 0.005)); // Small acceleration for drift
// Create the birds in the V-formation
let startX = windowWidth; // Start position for the tip of the V (rightmost)
let startY = height / 2; // Vertical center of the canvas
let size = 1; // Scale factor for bird sizes
let speed = 3; // Constant speed for all birds
for (let i = 0; i < 7; i++) {
let x = startX + i * 60; // Birds spaced horizontally to the right
let y = startY + i * 20 * (i % 2 === 0 ? 1 : -1); // Offset vertically for the V
birds.push(new Bird(x, y, size, speed)); // Removed flapOffset since wings won't flap
size *= 0.8; // Gradually decrease the size of each bird
}
}
function draw() {
// Draw the Perlin noise-based background
background(150, 180, 255); // Blue sky base
// Update the noise field
noiseVelocity.add(noiseAcceleration); // Gradually increase speed
noiseVector.sub(noiseVelocity); // Move noise field from left to right
// Move noise field slightly in all directions
noiseAcceleration.x = random(-0.0005, 0.0005);
noiseAcceleration.y = random(-0.0005, 0.0005);
let tileSize = width / tileCount; // Calculate size of tiles
for (let row = 0; row < tileCount; row++) {
for (let col = 0; col < tileCount; col++) {
let x = col * tileSize;
let y = row * tileSize;
// Calculate Perlin noise value based on noiseVector and grid position
let xnoise = noiseVector.x + col * noiseScale;
let ynoise = noiseVector.y + row * noiseScale;
let noiseValue = noise(xnoise, ynoise);
// Map noise to opacity to create cloud transparency with a value
let a = map(noiseValue, 0, 0.5, 0, 210);
fill(252, 230, 252, a); // Light pink color with alpha
// draw tiles
noStroke();
rect(x, y, tileSize, tileSize);
}
}
// Update and display all birds
for (let bird of birds) {
bird.update();
bird.show();
}
}
class Bird {
constructor(x, y, size, speed) {
this.x = x; // X position
this.y = y; // Y position
this.size = size; // Scale factor for bird size
this.speed = speed; // Speed of movement (no variation now)
this.flapAngle = 0; // Flap angle for controlling wing motion
this.flapSpeed = random(0.12, 0.18); // Random flap speed between 0.12 and 0.18
}
update() {
this.x -= this.speed; // Move left across the screen (right to left)
if (this.x < -50) this.x = width + 50; // Loop back to the right side
this.flapAngle += this.flapSpeed; // Increment flap angle at different rates for each bird
}
show() {
push();
translate(this.x, this.y);
scale(this.size); // Scale the bird
// Set a more natural color (dark gray with some transparency)
fill(0, 0, 0, 200); // Dark gray with transparency
this.drawBird(sin(this.flapAngle)); // Flap the wings with variation based on flap angle
pop();
}
drawBird(curveFactor) {
// Common wing motion factor
let wingY = map(curveFactor, -1, 1, 0, -35); // Outer tip moves lower when flapping down, less upward
let wingCurve = map(curveFactor, -1, 1, -25, -50); // More pronounced curvature when flapping down
// Left wing
beginShape();
vertex(0, 0); // Center of the bird
quadraticVertex(-25, -10, -35, wingY); // Upper arch of the left wing
quadraticVertex(-25, wingCurve, 0, 0); // Lower arch of the left wing
endShape(CLOSE);
// Right wing
beginShape();
vertex(0, 0); // Center of the bird
quadraticVertex(40, -15, 70, wingY); // Upper arch of the right wing
quadraticVertex(40, wingCurve, 0, 0); // Lower arch of the right wing
endShape(CLOSE);
}
}