/* 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; } }