package photoflockr;
import java.lang.Math;
public class Boid {
public var id: Integer;
public var photoModel: PhotoModel;
public var width: Number;
public var height: Number;
public var radius: Number;
public var maxforce: Number;
public var maxspeed: Number;
public var desiredseparation: Number;
package var tags: String[] = bind photoModel.tags;
package var imageUrl: String = bind photoModel.thumbUrl;
package var largeImageUrl: String = bind photoModel.photoUrl;
package var loc: Vector2D = Vector2D { x: width/2, y: height/2 }
package var vel: Vector2D;
var acc: Vector2D;
var neighborDist: Number = radius*2;
public var selected: Boolean = false on replace {
Main.flockr.reorderSprites();
}
public function selectYourself() {
selected = true;
}
public function returnToFlocking() {
selected = false;
}
function random(lo: Number, hi: Number): Number {
var res = lo + Math.random() * (hi - lo);
return res;
}
init {
acc = Vector2D {};
vel = Vector2D { x: random(-1, 1), y: random(-1, 1) };
loc = Vector2D { x: random(0, 200), y: random(0, 200) };
}
public function run(boids: Boid[], cohere: function(b1: Boid, b2: Boid): Number): Void {
if (not selected) {
flock(boids, cohere);
update();
borders();
}
}
function flock(boids: Boid[], cohere: function(b1: Boid, b2: Boid): Number): Void {
var sep: Vector2D = separate(boids);
var ali: Vector2D = align(boids);
var coh: Vector2D = cohesion(boids, cohere);
sep.mult(8.0);
ali.mult(1.0);
coh.mult(1.0);
acc.add(sep);
acc.add(ali);
acc.add(coh);
}
function update(): Void {
vel.add(acc);
vel.limit(maxspeed);
vel.updateHeading2D();
loc.add(vel);
acc.setXY(0, 0);
}
function steer(target: Vector2D, slowdown: Boolean): Vector2D {
var steer: Vector2D;
var desired = target.sub(target, loc);
var d = desired.magnitude();
if (d > 0) {
desired.normalize();
if ((slowdown) and (d > 100.0)) {
desired.mult(maxspeed*(d/100.0));
} else {
desired.mult(maxspeed);
}
steer = target.sub(desired, vel);
steer.limit(maxforce);
} else {
steer = Vector2D {};
}
return steer;
}
function borders(): Void {
if (loc.x < -radius*2) loc.x = width + radius*2;
if (loc.y < -radius*2) loc.y = height + radius*2;
if (loc.x > width + radius*2) loc.x = -radius*2;
if (loc.y > height + radius*2) loc.y = -radius*2;
}
function separate(boids: Boid[]): Vector2D {
var sum = Vector2D {};
var count = 0;
for (other in boids) {
var d = loc.distance(loc, other.loc);
if ((d > 0) and (d < desiredseparation)) {
var diff = loc.sub(loc, other.loc);
diff.normalize();
diff.div(d);
sum.add(diff);
count++;
}
}
if (count > 0) {
sum.div(count);
}
return sum;
}
function align(boids: Boid[]): Vector2D {
var sum = Vector2D {};
var count = 0;
for (other in boids) {
var d = loc.distance(loc, other.loc);
if ((d > 0) and (d < neighborDist)) {
sum.add(other.vel);
count++;
}
}
if (count > 0) {
sum.div(count);
sum.limit(maxforce);
}
return sum;
}
function cohesion(boids: Boid[], cohere: function(b1: Boid, b2: Boid): Number): Vector2D {
var neighbordist = this.neighborDist*6;
var sum = Vector2D {};
var count = 0;
for (other in boids) {
var c = cohere(this, other);
var d = loc.distance(loc, other.loc);
if ((d > 0) and (d < neighbordist*c)) {
sum.add(other.loc);
count++;
}
}
if (count > 0) {
sum.div(count);
return steer(sum, false);
}
return sum;
}
}