AI Boids Flocking - Emergent Swarm Intelligence Watch 100 birds flock together using Craig Reynolds

50 views ยท Dec 16, 2025

Create a Boids Flocking Simulation! 100 triangle-shaped birds follow 3 rules: separation, alignment,

#xelsedia#xelsedai#xelsedp5flashalpha6
๐Ÿ”€ Remix This ๐Ÿ“– View Docs โ›ถ Full Screen โ† Back to Gallery
๐Ÿ“‹ Embed Code

Copy this code to embed this sketch on your website:

<iframe src="https://p5js.ai/embed/3dac112b-61c6-452e-a0ba-45a2cdc35ecf" width="400" height="400" frameborder="0" allow="autoplay" title="AI Boids Flocking - Emergent Swarm Intelligence Watch 100 birds flock together using Craig Reynolds"></iframe>

Adjust width and height as needed. Preview embed โ†’

โ“ About This Sketch 3 questions

What visual experience does the AI Boids Flocking simulation offer?

The simulation visually showcases 100 triangle-shaped birds flocking together, creating dynamic and fluid movements that resemble natural swarming behavior.

How can users interact with the Boids Flocking simulation?

Users can interact with the sketch by moving their mouse, which is represented as a predator, influencing the flock's behavior as the boids attempt to avoid it.

What creative coding concepts are illustrated in the AI Boids Flocking sketch?

The sketch demonstrates emergent swarm intelligence through the implementation of flocking behaviors like separation, alignment, and cohesion, inspired by Craig Reynolds' Boids model.

๐Ÿ’ฌ AI Chat History 2 messages
๐Ÿ‘ค You
Create a Boids Flocking Simulation! 100 triangle-shaped birds follow 3 rules: separation, alignment, cohesion. They flock together naturally like starlings. Each boid leaves a short fading trail. Gradient colors based on velocity direction. Mouse acts as predator they avoid. Dark background. Emergent swarm intelligence!
๐Ÿค– AI
Hereโ€™s a full boids flocking sketch with:

- 100 triangle โ€œbirdsโ€
- Separation, alignment, cohesion
- Mouse as predator (they avoid it)
- Dark background with fading trails
- Gradient colors based on velocity direction (HSB hue)

Apply all three files.

---

### `index.html`

```html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Boids Flocking Simulation</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<!-- p5.js core library (v1.11.3) -->
<script src="https://cdn.jsdelivr.net/npm/p5@1.11.3/lib/p5.min.js"></script>

<!-- Your sketch -->
<script src="sketch.js"></script>
</body>
</html>
```

---

### `style.css`

```css
body {
margin: 0;
padding: 0;
overflow: hidden;
background: #000; /* dark page background */
}

canvas {
display: block;
}
```

---

### `sketch.js`

```js
// Boids flocking simulation
// p5.js reference for vectors: https://p5js.org/reference/#/p5.Vector

const NUM_BOIDS = 100;

let boids = [];

function setup() {
createCanvas(windowWidth, windowHeight);

// Use HSB so we can map heading โ†’ hue easily
colorMode(HSB, 360, 100, 100, 100);
background(0); // solid black to start

// Create initial flock
for (let i = 0; i < NUM_BOIDS; i++) {
boids.push(new Boid(random(width), random(height)));
}
}

function draw() {
// Draw a translucent background for fading trails
// (alpha = 20/100 โ†’ about 20% opaque, 80% previous frame visible)
background(0, 0, 0, 20);

// Optional: visualize predator (mouse) as a faint circle
noFill();
stroke(0, 0, 100, 30); // light, semi-transparent
strokeWeight(2);
circle(mouseX, mouseY, 80);

// Update and render boids
for (let boid of boids) {
boid.flock(boids);
boid.update();
boid.edges();
boid.show();
}
}

function windowResized() {
resizeCanvas(windowWidth, windowHeight);
background(0); // reset background on resize
}

// --------------------------------------------------------
// Boid class
// --------------------------------------------------------

class Boid {
constructor(x, y) {
this.position = createVector(x, y);

// Start with random direction & speed
const angle = random(TWO_PI);
const speed = random(1.5, 3.0);
this.velocity = p5.Vector.fromAngle(angle).mult(speed);

this.acceleration = createVector(0, 0);

this.maxSpeed = 3.0;
this.maxForce = 0.08; // max steering force

this.size = 5; // use for triangle size and edge wrapping
}

// Apply flocking behavior: separation, alignment, cohesion, predator avoidance
flock(boids) {
const alignment = this.align(boids);
const cohesion = this.cohesion(boids);
const separation = this.separation(boids);
const avoidPredator = this.fleePredator();

// Weights for each behavior
alignment.mult(1.0);
cohesion.mult(0.8);
separation.mult(1.5);
avoidPredator.mult(2.0);

this.acceleration.add(alignment);
this.acceleration.add(cohesion);
this.acceleration.add(separation);
this.acceleration.add(avoidPredator);
}

update() {
// Integrate acceleration into velocity and position
this.velocity.add(this.acceleration);
this.velocity.limit(this.maxSpeed);
this.position.add(this.velocity);

// Reset acceleration each frame
this.acceleration.mult(0);
}

// Wrap around edges for continuous space
edges() {
const margin = this.size * 2;

if (this.position.x > width + margin) this.position.x = -margin;
if (this.position.x < -margin) this.position.x = width + margin;
if (this.position.y > height + margin) this.position.y = -margin;
if (this.position.y < -margin) this.position.y = height + margin;
}

// Alignment: steer towards average heading of local flockmates
align(boids) {
const perceptionRadius = 70;
const steering = createVector(0, 0);
let total = 0;

for (let other of boids) {
const d = p5.Vector.dist(this.position, other.position);
if (other !== this && d < perceptionRadius) {
steering.add(other.velocity);
total++;
}
}

if (total > 0) {
steering.div(total);
steering.setMag(this.maxSpeed);
steering.sub(this.velocity);
steering.limit(this.maxForce);
}

return steering;
}

// Cohesion: steer towards the average position of local flockmates
cohesion(boids) {
const perceptionRadius = 70;
const steering = createVector(0, 0);
let total = 0;

for (let other of boids) {
const d = p5.Vector.dist(this.position, other.position);
if (other !== this && d < perceptionRadius) {
steering.add(other.position);
total++;
}
}

if (total > 0) {
steering.div(total);
// Steer toward that center point
steering.sub(this.position);
steering.setMag(this.maxSpeed);
steering.sub(this.velocity);
steering.limit(this.maxForce);
}

return steering;
}

// Separation: steer away from nearby flockmates to avoid crowding
separation(boids) {
const desiredSeparation = 25;
const steering = createVector(0, 0);
let total = 0;

for (let other of boids) {
const d = p5.Vector.dist(this.position, other.position);
if (other !== this && d < desiredSeparation) {
let diff = p5.Vector.sub(this.position, other.position);
// Stronger repulsion when very close
diff.div(d * d || 1); // avoid division by zero
steering.add(diff);
total++;
}
}

if (total > 0) {
steering.div(total);
steering.setMag(this.maxSpeed);
steering.sub(this.velocity);
steering.limit(this.maxForce * 1.5);
}

return steering;
}

// Predator avoidance: flee from mouse position
fleePredator() {
const predatorPos = createVector(mouseX, mouseY);
const d = p5.Vector.dist(this.position, predatorPos);
const threatRadius = 120;

if (d < threatRadius) {
let flee = p5.Vector.sub(this.position, predatorPos);
flee.setMag(this.maxSpeed);

flee.sub(this.velocity);
flee.limit(this.maxForce * 3.0);

// Stronger when closer to the predator
const scale = map(d, 0, threatRadius, 2.0, 0.3);
flee.mult(scale);

return flee;
}

return createVector(0, 0);
}

// Render the boid as a velocity-oriented triangle
show() {
const theta = this.velocity.heading();

// Map direction (-PI..PI) to hue (0..360)
const hueVal = map(theta, -PI, PI, 0, 360);

push();
translate(this.position.x, this.position.y);
rotate(theta);

// Gradient-like effect via HSB hue based on direction
fill(hueVal, 80, 100, 80); // colorful body
stroke(hueVal, 80, 100, 100); // matching outline
strokeWeight(1.3);

// Triangle pointing in direction of motion (nose to the right)
beginShape();
vertex(this.size * 2, 0); // nose
vertex(-this.size, this.size); // back bottom
vertex(-this.size, -this.size); // back top
endShape(CLOSE);

pop();
}
}
```

---

You can tweak these for different flock โ€œpersonalitiesโ€:

- Increase `separation.mult(1.5)` weight for tighter avoidance
- Change `NUM_BOIDS` for denser or sparser flocks
- Adjust `background(0, 0, 0, 20)` alpha (last value) to shorten/lengthen trails

If you want, I can add keyboard controls (e.g., toggle trails, change rule weights live) or sliders using a GUI.
๐ŸŽฌ Video Preview