ArrayList waves = new ArrayList(); ArrayList plants = new ArrayList(); ArrayList bubbles = new ArrayList(); class Bubble{ float x,y,z; Bubble(float px,float py,float pz){ x = px; y = py; z = pz; } boolean move(){ y--; x += random(-1,1); z += random(-1,1); if(y <= -100) return false; return true; } void draw(){ pm3d.add3Dline(x,y,z,x,y,z,color(0,0,255)); } } int blowing = 0; int timeToBlow = 100; void drawBox(){ color BROWN = color(128,64,0); pm3d.startLinePath(30,70,30, BROWN); pm3d.addToLinePath(60,70,30); pm3d.addToLinePath(60,70,60); pm3d.addToLinePath(30,70,60); pm3d.addToLinePath(30,70,30); pm3d.startLinePath(30,100,30, BROWN); pm3d.addToLinePath(60,100,30); pm3d.addToLinePath(60,100,60); pm3d.addToLinePath(30,100,60); pm3d.addToLinePath(30,100,30); pm3d.add3Dline(30,70,30,30,100,30,BROWN); pm3d.add3Dline(30,70,60,30,100,60,BROWN); pm3d.add3Dline(60,70,30,60,100,30,BROWN); pm3d.add3Dline(60,70,60,60,100,60,BROWN); if(blowing > 0){ pm3d.add3Dline(60,70,60,60,50,60,BROWN); pm3d.add3Dline(30,70,60,30,50,60,BROWN); pm3d.add3Dline(30,50,60,60,50,60,BROWN); blowing --; bubbles.add(new Bubble(random(30,60), 70, random(30,60))); } else { if(timeToBlow > 0){ timeToBlow--; } else { blowing = 20; timeToBlow = 20 + int(random(200,400)); } } } PoMan3D pm3d; void setup() { size(500, 500); mouseX = 250; mouseY = 250; pm3d = new PoMan3D(500, 500); strokeWeight(8); waves.add(new Wave(0,0)); waves.add(new Wave(-50, PI/2)); waves.add(new Wave(50,-PI/2)); for(int i = 0; i < 10; i++){ plants.add(new Plant()); } } float fishscale = 1; void draw() { background(200); if(mousePressed){ if(fishscale < 2.5) fishscale += .03; } else { if(fishscale > 1) fishscale -= .03; } pm3d.setScale(fishscale); pm3d.startDraw(); pm3d.rotateToMouse(); drawTank(); drawFish(); drawWaves(); for(Plant p : plants){ p.move(); p.draw(); } ArrayList bubblesToPop = new ArrayList(); for(Bubble b : bubbles){ if(!b.move()){ bubblesToPop.add(b); } b.draw(); } bubbles.removeAll(bubblesToPop); drawBox(); pm3d.endDraw(); } float fishHeight = 10; float fishAngle = 0.0; void drawFish() { fishAngle += .03; float fishFront = fishAngle + .2; float fishMid = fishAngle; float fishBack = fishAngle - .2; float frontX = 75 * cos(fishFront); float frontZ = 75 * sin(fishFront); float midX = 75 * cos(fishMid); float midZ = 75 * sin(fishMid); float backX = 75 * cos(fishBack); float backZ = 75 * sin(fishBack); color ORANGE = color(255, 128, 0); pm3d.startLinePath(backX, fishHeight, backZ, ORANGE); pm3d.addToLinePath(midX, -fishHeight, midZ); pm3d.addToLinePath(frontX, 0, frontZ); pm3d.addToLinePath(midX, fishHeight, midZ); pm3d.addToLinePath(backX, -fishHeight, backZ); } void drawTank() { color BLACK = color(0); //top box pm3d.startLinePath(-100,-100,-100,BLACK); pm3d.addToLinePath(100,-100,-100); pm3d.addToLinePath(100,-100,100); pm3d.addToLinePath(-100,-100, 100); pm3d.addToLinePath(-100,-100, -100); //bottom box pm3d.startLinePath(-100,100,-100,BLACK); pm3d.addToLinePath(100,100,-100); pm3d.addToLinePath(100,100,100); pm3d.addToLinePath(-100,100, 100); pm3d.addToLinePath(-100,100, -100); //up and down pm3d.add3Dline(-100, 100, -100, -100, -100, -100, BLACK); pm3d.add3Dline(-100, 100, 100, -100, -100, 100, BLACK); pm3d.add3Dline(100, 100, -100, 100, -100, -100, BLACK); pm3d.add3Dline(100, 100, 100, 100, -100, 100, BLACK); //diags on bottom pm3d.add3Dline(-100, 100, -100, 100, 100, 100, BLACK); pm3d.add3Dline(100, 100, -100, -100, 100, 100, BLACK); pm3d.add3Dline(0, 100, -100, 0, 100, 100, BLACK); pm3d.add3Dline(-100, 100, 0, 100, 100, 0, BLACK); } void drawWaves(){ for(Wave w : waves){ w.move(); w.draw(); } } class Wave{ float z,p; Wave(float pz, float pp){ z = pz; p = pp; } void move(){ p += .05; } void draw(){ float p2 = p + 100; if(p2 > 100) p2 -= 100; pm3d.startLinePath(-100,-100,z, color(0,0,255)); pm3d.addToLinePath(-33,-100 + 5 * sin(p),z); pm3d.addToLinePath(33,-100 - 5 * sin(p),z); pm3d.addToLinePath(100,-100,z); } } class Plant{ float x,z,a; float halfheight; float bendmod; Plant(){ float PISET = PI/8; float r = random(PISET+PI/4, PISET+PI*2); float r2 = random(80); x = r2 * cos(r); z = r2 * sin(r); a = 0;//random(PI*2); halfheight = random(60,90); bendmod = random( 15,25); } void move(){ a += .05; } void draw(){ float aa = PI/2 +sin(a)/bendmod; pm3d.startLinePath(x,100,z, color(0,255,0)); float x2 = x + cos(aa) * halfheight; float y2 = sin(aa) * halfheight; pm3d.addToLinePath(x2,100-y2,z); pm3d.addToLinePath(x,100-y2*2,z); } } /* * * * * * * * * * * * * */ class PoMan3D { private float screenCenterX, screenCenterY; private float scaler = 1.0; private float rotateX,rotateY; private ArrayList linesToDraw;// = new ArrayList(); PoMan3D(int w, int h) { screenCenterX = w / 2; screenCenterY = h / 2; } void rotateToMouse(){ rotateX = map(mouseY,0,500,PI/2,-PI/2); rotateY = map(mouseX,screenCenterX,width,0,-2*PI); } void setScale(float s){ scaler = s; } void startDraw() { linesToDraw = new ArrayList(); } void addScaledLine(scaledLine s) { for (int i = 0; i < linesToDraw.size(); i++) { scaledLine c = linesToDraw.get(i); if (s.scaleval < c.scaleval) { linesToDraw.add(i, s); return; } } linesToDraw.add(s); } void endDraw() { pushMatrix(); translate(screenCenterX, screenCenterY); for (scaledLine s : linesToDraw) { stroke(s.c); line(s.s1x, s.s1y, s.s2x, s.s2y); } popMatrix(); } private float lastX, lastY, lastZ; private color lastC; void startLinePath(float x, float y, float z, color c) { lastX = x; lastY = y; lastZ = z; lastC = c; } void addToLinePath(float x, float y, float z) { pm3d.add3Dline(lastX, lastY, lastZ, x, y, z, lastC); lastX = x; lastY = y; lastZ = z; } void add3Dline(float x1, float y1, float z1, float x2, float y2, float z2, color c) { float f1x = x1, f2x = x2, f1y = y1, f2y = y2, f1z = z1, f2z = z2; f1x = rotation1(x1, z1, rotateY); f2x = rotation1(x2, z2, rotateY); f1z = rotation2(z1, x1, rotateY); f2z = rotation2(z2, x2, rotateY); f1y = rotation1(y1, f1z, rotateX); f2y = rotation1(y2, f2z, rotateX); f1z = rotation2(f1z, y1, rotateX); f2z = rotation2(f2z, y2, rotateX); float scale1 = map(f1z, -100, 100, .8 * scaler, 1.2 * scaler); float scale2 = map(f2z, -100, 100, .8 * scaler, 1.2 * scaler); f1x *= scale1; f1y *= scale1; f2x *= scale2; f2y *= scale2; addScaledLine(new scaledLine(f1x, f1y, f2x, f2y, scale1+scale2, c)); } private float rotation1(float a, float b, float ang) { return a*cos(ang) - b * sin(ang); } private float rotation2(float a, float b, float ang) { return a*cos(ang) + b * sin(ang); } private class scaledLine { float s1x, s2x, s1y, s2y, scaleval; color c; scaledLine(float ps1x, float ps1y, float ps2x, float ps2y, float pscale, color pc) { c = pc; s1x = ps1x; s1y = ps1y; s2x = ps2x; s2y = ps2y; scaleval = pscale; } void draw() { color(c); line(s1x, s1y, s2x, s2y); } } }