ArrayList fishes = new ArrayList(); void setup() { size(800, 600); for(int i = 0; i < 20; i++) { Fish currentFish = new Fish(random(50, 750), random(50, 550)); currentFish.setAngle(random(0, 360)); currentFish.swimForward(); fishes.add(currentFish); } } void draw() { for(Fish fish : fishes) { fish.update(); } background(0, 119, 190); for(Fish fish : fishes) { fish.draw(); } } class Fish { private float x; private float y; private PVector position; private PVector velocity; private FishNode head; private float angle; public Fish(float x, float y) { float startingTheta = random(0, (float)(2 * Math.PI)); FishNode childNode = new FishNode(null, 7, 7, 20, 0, 0.3, startingTheta); childNode = new FishNode(childNode, 15, 15, 30, 0, 0.4, (float)(startingTheta + Math.PI / 4)); head = new FishNode(childNode, 20, 20, 0, 0, 0, 0); position = new PVector(x, y); velocity = new PVector(); this.angle = 0; } public void setAngle(float angle) { this.angle = angle; } public void swimForward() { velocity.x = -cos(radians(angle)); velocity.y = -sin(radians(angle)); } public void update() { position.add(velocity); if(position.x < 0) { position.x = 0; angle += random(-90, 90); swimForward(); } if(position.x > 800) { position.x = 800; angle += random(-90, 90); swimForward(); } if(position.y < 0) { position.y = 0; angle += random(-90, 90); swimForward(); } if(position.y > 600) { position.y = 600; angle += random(-90, 90); swimForward(); } head.update(); } public void draw() { pushMatrix(); translate(position.x, position.y); pushMatrix(); rotate(radians(angle)); head.draw(null); popMatrix(); popMatrix(); } } class FishNode { private FishNode child; public float x; public float y; private float width; private float height; private float theta; private float swimOffset; private float flopDirection; private float amplitude; public FishNode(FishNode child, float width, float height, float x, float y, float amplitude, float theta) { this.child = child; this.width = width; this.height = height; this.x = x; this.y = y; this.theta = theta; swimOffset = 0.0f; flopDirection = 1; this.amplitude = amplitude; } public void setTheta(float theta) { this.theta = theta; } public float getTheta() { return theta; } public float getSine() { return amplitude * sin(theta); } public float getX() { return x; } public float getY() { return y; } public float getHeight() { return height; } public float getWidth() { return width; } public float getTopY() { return getHeight() / 2; } public float getBottomY() { return -getHeight() / 2; } public void update() { theta += 0.1; if(child != null) { child.update(); } } public void draw(FishNode parent) { fill(0,0,0,0); strokeWeight(2); stroke(200,200,200,255); pushMatrix(); rotate(getSine()); if(parent != null) { line(0, parent.getTopY(), getX(), getTopY()); line(0, parent.getBottomY(), getX(), getBottomY()); } translate(getX(), getY()); ellipse(0, 0, width, height); if(child != null) { child.draw(this); } popMatrix(); } }