/* built with Studio Sketchpad:
* https://sketchpad.cc
*
* observe the evolution of this sketch:
* https://studio.sketchpad.cc/sp/pad/view/ro.AK9M$BLEBLj/rev.9
*
* authors:
* GoToLoop
* license (unless otherwise specified):
* creative commons attribution-share alike 3.0 license.
* https://creativecommons.org/licenses/by-sa/3.0/
*/
/**
* Anthills (v2.1)
* by ArnaudM (2014/Nov/30)
* mod GoToLoop
*
* forum.processing.org/two/discussion/8380/
* issues-with-my-anthill-program
*
* studio.processingtogether.com/sp/pad/export/ro.91A3Jfnrsldhp/latest
*/
// Sketch's Global Constants:
static final int COLONIES = 5, ANTS = 20, FPS = 60;
// Sketch's Global Variables:
final Anthill[] anthills = new Anthill[COLONIES];
boolean isLooping = true;
// Sketch's User Function:
void instantiateAnthills(int ants) {
for (int i = 0; i != COLONIES; anthills[i++] = new Anthill(ants));
}
// Sketch's Callback Functions:
void setup() {
size(1280, 800, JAVA2D);
ellipseMode(CENTER);
frameRate(FPS);
smooth(4);
noStroke();
instantiateAnthills(ANTS);
}
void draw() {
background(0);
for (Anthill hill : anthills) hill.action();
}
void keyTyped() {
if (isLooping ^= true) loop();
else noLoop();
}
void mousePressed() {
if (mouseButton == LEFT) keyTyped();
else instantiateAnthills(ANTS);
}
final class Anthill {
// Class Anthill's Constants:
static final int REGION = 30, FRONTIER = 4*REGION;
// Class Anthill's Instance Variables:
final color colour = (int) random(#000000);
final PVector pos;
final Ant[] ants;
// Class Anthill's Constructor:
Anthill(int qty) {
ants = new Ant[qty];
int offset = REGION + Ant.DIAM;
int centerX = (int) random(offset, width - offset);
int centerY = (int) random(offset, height - offset);
pos = new PVector(centerX, centerY);
for (int i = 0; i != qty; ++i) {
float posX = centerX + random(-REGION, REGION);
float posY = centerY + random(-REGION, REGION);
ants[i] = new Ant(posX, posY);
}
}
// Class Anthill's Method:
void action() {
fill(colour);
for (Ant a : ants) a.action(pos);
}
}
final class Ant {
// Class Ant's Constants:
static final int DIAM = 10, FPS = 60; // FPS needed here in JS Mode!
static final float MAX_VEL = 2.0;
static final int MIN_FRAMES = FPS>>1, MAX_FRAMES = 4*FPS;
// Class Ant's Instance Variables:
final PVector pos, vel = new PVector();
int targetFrame = frameCount;
// Class Ant's Constructor:
Ant(float x, float y) {
pos = new PVector(x, y);
}
// Class Ant's Methods:
void action(PVector center) {
if (frameCount >= targetFrame) redefine(center);
update();
display();
}
void display() {
ellipse(pos.x, pos.y, DIAM, DIAM);
}
void update() {
pos.add(vel);
}
void redefine(PVector hill) {
float dx = random(-Anthill.FRONTIER, Anthill.FRONTIER);
float dy = random(-Anthill.FRONTIER, Anthill.FRONTIER);
float sp = random(MAX_VEL);
vel.set(hill);
vel.add(dx, dy, 0);
vel.sub(pos);
vel.normalize(); // setMag() not available in PJS v1.4.1.
vel.mult(sp);
int tf = round(random(MIN_FRAMES, MAX_FRAMES)/MAX_VEL);
targetFrame = frameCount + tf;
}
}