import processing.opengl.*; import traer.physics.*; ParticleSystem ps; Leaf[] leaves; Vector droplets; float windSpeed; boolean windOn = false; private static final boolean TORRENT = true; int grassStems = int(random(20, 40)); void setup() { size(640, 480); smooth(); background(30, 30, 30); //frameRate(2); ps = new ParticleSystem(4.0, 1.0); leaves = new Leaf[int(random(4, 6))]; for (int i = 0; i < leaves.length; i++) { leaves[i] = new Leaf(); } droplets = new Vector(24, 24); } void draw() { /*fill(30, 60, 30, 120); noStroke(); rect(0, 0, width, height);*/ drawBackground(); ps.tick(); for (int i = 0; i < leaves.length; i++) { leaves[i].update(); } // Create some more droplets if (TORRENT) { droplets.add(new Droplet()); } else { if (random(1) > 0.8) { int n = int(random(0, 2)); for (int i = 0; i < n; i++) { droplets.add(new Droplet()); } } } Droplet d; for (int i = 0; i < droplets.size(); i++) { d = (Droplet) droplets.get(i); if (d.node.isDead()) { droplets.remove(d); } else if (d.node.position().y() > height + 24) { d.node.kill(); } else { d.update(); } } doLeafCollision(); doDropletCollision(); wind(); } void drawBackground() { //fill(30, 60, 30, 200); fill(30, 30, 30, 200); noStroke(); rect(0, 0, width, height); fill(51, 153, 0, 120); stroke(1, 90, 1, 80); strokeWeight(6); float m = width / grassStems; beginShape(); curveVertex(0, height); for (int i = 0; i < grassStems; i++) { curveVertex(i * m, height + 10); curveVertex((i + 0.5) * m, height - 100); curveVertex((i + 1) * m, height); } curveVertex(0, height); curveVertex(0, height); endShape(); fill(129, 102, 71); stroke(86, 82, 72, 60); strokeWeight(10); beginShape(); curveVertex(-20, -20); curveVertex(-20, height + 20); curveVertex(width / 21, height + 20); curveVertex(width / 19, height / 4.5); curveVertex(-20, -20); curveVertex(-20, -20); endShape(); beginShape(); curveVertex(width + 20, -20); curveVertex(width + 20, height + 20); curveVertex((width / 18) * 17, height + 20); curveVertex((width / 24) * 23, height / 6); curveVertex(width + 20, -20); curveVertex(width + 20, -20); endShape(); } void mousePressed() { windOn = !windOn; if (windOn) windSpeed = random(-1, 1); /*if (mouseButton == LEFT) { for (int i = 0; i < leaves.length; i++) { leaves[i].jiggle(); } } else if (mouseButton == RIGHT) { for (int i = 0; i < leaves.length; i++) { leaves[i].addMass(); } }*/ } void wind() { if (windOn) { for (int i = 0; i < droplets.size(); i++) { ((Droplet) droplets.get(i)).node.addVelocity(windSpeed, 0, 0); } for (int i = 0; i < leaves.length; i++) { leaves[i].wind(windSpeed); //leaves[i].jiggle(); } } } void doDropletCollision() { Droplet d1, d2; float x1, x2, y1, y2; float q; for (int i = 0; i < droplets.size(); i++) { d1 = (Droplet) droplets.get(i); if (d1.node.mass() > 4) continue; x1 = d1.node.position().x(); y1 = d1.node.position().y(); q = d1.node.mass() * 2; for (int j = i + 1; j < droplets.size(); j++) { d2 = (Droplet) droplets.get(j); if (d2.node.mass() > 4) break; x2 = d2.node.position().x(); y2 = d2.node.position().y(); if ((x1 > x2 - q) && (x1 < x2 + q) && (y1 > y2 - q) && (y1 < y2 + q)) { d2.node.setMass(d2.node.mass() + d1.node.mass()); d1.node.kill(); break; } } } } void doLeafCollision() { Droplet d; float q = 12.0; for (int a = 0; a < droplets.size(); a++) { d = (Droplet) droplets.get(a); boolean inside = false; for (int b = 0; (b < leaves.length) && (!inside); b++) { for (int c = 1; (c < leaves[b].polygon.length) && (!inside); c++) { if (leaves[b].baseX < width / 2) { inside = ((d.node.position().x() >= leaves[b].polygon[c-1].x) && (d.node.position().x() <= leaves[b].polygon[c].x)); } else { inside = ((d.node.position().x() <= leaves[b].polygon[c-1].x) && (d.node.position().x() >= leaves[b].polygon[c].x)); } inside = inside && ((d.node.position().y() >= leaves[b].polygon[c-1].y) && (d.node.position().y() <= leaves[b].polygon[c].y)); if (inside) break; } d.setOnLeaf(inside, leaves[b]); if (inside) { leaves[b].bump(d.node.mass()); break; } } //System.out.println("Droplet is " + (inside ? "ON" : "OFF") + " a leaf."); } }