Created
December 27, 2011 08:40
-
-
Save hughsk/1523069 to your computer and use it in GitHub Desktop.
Simple Boids example in Processing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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