Skip to content

Instantly share code, notes, and snippets.

@hughsk
Created December 27, 2011 08:40
Show Gist options
  • Save hughsk/1523069 to your computer and use it in GitHub Desktop.
Save hughsk/1523069 to your computer and use it in GitHub Desktop.
Simple Boids example in Processing
class Boid {
PVector pos;
PVector spd;
PVector acc;
Boid() { this(random(0, width), random(0, height)); }
Boid(float x, float y) { this(x, y, random(0,1), random(0,1)); }
Boid(float x, float y, float xspd, float yspd) {
pos = new PVector(x, y);
spd = new PVector(xspd, yspd);
acc = new PVector(0, 0);
}
void step(ArrayList<Boid> boids) { this.step(boids, boids.size(), new PVector(0, 0), 0); }
void step(ArrayList<Boid> boids, int boidCount, PVector totalSpeed, int t) {
// Rule 1: Separation; and
// Rule 3: Cohesion
for (int i = 0; i < boidCount; i++) {
Boid b = boids.get(i);
if (b != this) {
float distance = pos.dist(b.pos);
if (!repel(b.pos, 40, 0, distance, 0.002)) {
attract(b.pos, 150, 40, distance, 0.000024);
}
}
}
// Rule 2: Alignment
PVector alignment = totalSpeed.get();
alignment.limit(0.0001);
spd.add(alignment);
// Avoid the mouse!
PVector mpos = new PVector(mouseX, mouseY);
repel(mpos, 120, 0, pos.dist(mpos), 0.0048);
// Perlin noise wandering
PVector perlin = new PVector(
noise((pos.x+t)*0.001, (pos.y-t)*0.001)-0.5,
noise((pos.x-t)*0.001-1500, (pos.y+t)*0.001+1500)-0.5
);
perlin.mult(0.075);
spd.add(perlin);
spd.limit(4);
pos.add(spd);
spd.add(acc);
if ( pos.x > width ) { pos.x = 0; } else
if ( pos.x < 0 ) { pos.x = width; }
if ( pos.y > height ) { pos.y = 0; } else
if ( pos.y < 0 ) { pos.y = height; }
}
void render() {
ellipse(pos.x, pos.y, 5, 5);
}
boolean repel(PVector target, float maxValue, float minValue, float distance, float magnitude) {
if (distance < maxValue && distance > minValue) {
PVector subbing = target.get();
subbing.sub(this.pos);
subbing.limit((maxValue-distance)*magnitude);
spd.sub(subbing);
return true;
} else return false;
}
boolean attract(PVector target, float maxValue, float minValue, float distance, float magnitude) {
if (distance < maxValue && distance > minValue) {
PVector subbing = target.get();
subbing.sub(this.pos);
subbing.limit(distance*magnitude);
spd.add(subbing);
return true;
} else return false;
}
}
ArrayList<Boid> boids;
int boidCount = 250;
int t = 0;
PVector totalSpeed;
void setup() {
size(900, 500);
frameRate(60);
boids = new ArrayList<Boid>();
for (int i = 0; i < boidCount; i++) {
boids.add(new Boid(width/2, height/2));
}
}
void draw() {
background(0);
noStroke();
fill(155, 245, 220);
boidCount = boids.size();
totalSpeed = new PVector(0, 0);
for (int v = 0; v < boidCount; v++) {
totalSpeed.add(boids.get(v).spd);
}
totalSpeed.div(boidCount);
for (int i = 0; i < boidCount; i++) {
Boid b = boids.get(i);
b.step(boids, boidCount, totalSpeed, t);
b.render();
}
noFill();
stroke(255, 128, 128);
ellipse(mouseX, mouseY, 120, 120);
t++;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment