endless rain var resizeCanvas = function() { var canv = Processing.getInstanceById('pjs'); canv.size(600, 600); } class Timer { int savedTime; // When Timer started int totalTime; // How long Timer should last Timer(int tempTotalTime) { totalTime = tempTotalTime; } // Starting the timer void start() { // When the timer starts it stores the current time in milliseconds. savedTime = millis(); } // The function isFinished() returns true if 5,000 ms have passed. // The work of the timer is farmed out to this method. boolean isFinished() { // Check how much time has passed int passedTime = millis()- savedTime; if (passedTime > totalTime) { return true; } else { return false; } } } class Drop { float x, y; // Variables for location of raindrop float speed; // Speed of raindrop color c; float r; // Radius of raindrop float xoff; float sizex,sizey; Drop() { float z = random (0,20); r = map(z,0,20,9,11); // All raindrops are not the same size float x1,x2,xx; x1 =random(466,557); x2 =random(606,680); // Start with a random x location xx = random(1,3); if (xx<2) {x=x1;} else {x=x2;} if ((x>465)&&(x<472)) {y = 1.2*x-300;} else {y = 0.56*x+10;} speed = map(z,0,20,0.5, 2.5); // Pick a random speed c = color(65, 90, 165); // Color xoff = noise(0.35)*2; //random angle sizex = map(z,0,20,0.4,0.8); //random size sizey = map(z,0,20,2.5,3.6); } // Move the raindrop down void move() { // Increment by speed y += speed; x -= xoff; speed += 0.1; } // Check if it hits the bottom boolean reachedBottom() { // If we go a little beyond the bottom if (y > height + r*4) { float z = random (0,20); speed = map(z,0,20,0,5,2.5); return true; } else { return false; } } // Display the raindrop void display() { //float z = random (0,20); // Display the drop fill(52,72,140,134); noStroke(); for (int i = 2; i < r; i++ ) { ellipse(x-i*sizex, y + i*sizey, i*2, i*2); } } // If the drop is caught void caught() { // Stop it from moving by setting speed equal to zero speed = 0; // Set the location to somewhere way off-screen float maybe = random(0,2); if (maybe!=0){ float x1,x2,xx; x1 =random(466,557); x2 =random(606,680); // Start with a random x location xx = random(1,3); if (xx<2) {x=x1;} else {x=x2;} if ((x>465)&&(x<472)) {y = 1.2*x-300;} else {y = 0.56*x+10;} } } } class Catcher { float r; // radius color col; // color float x, y; // location Catcher(float tempR) { r = tempR; col = color(50, 10, 10, 150); x = 0; y = 0; } void setLocation(float tempX, float tempY) { x = tempX; y = tempY; } void display() { stroke(0); fill(col); ellipse(x, y, r*2, r*2); } // A function that returns true or false based on // if the catcher intersects a raindrop boolean intersect(Drop d) { // Calculate distance float distance = dist(x, y, d.x, d.y); // Compare distance to sum of radii if (distance < r + d.r) { return true; } else { return false; } } } Catcher catcher; // One catcher object Timer timer; // One timer object Drop[] drops; // An array of drop objects int totalDrops = 0; // totalDrops PImage bkg; void setup() { size(864,876); catcher = new Catcher(32); // Create the catcher with a radius of 32 drops = new Drop[700]; // Create 1000 spots in the array timer = new Timer(300); // Create a timer that goes off every 300 milliseconds timer.start(); // Starting the timer bkg = loadImage("https://upload.wikimedia.org/wikipedia/en/d/df/Roy_Lichtenstein_Drowning_Girl.jpg"); } void draw() { image(bkg,0,0,width,height); // Set catcher location catcher.setLocation(mouseX, mouseY); // Display the catcher catcher.display(); // Check the timer if (timer.isFinished()) { // Deal with raindrops // Initialize one drop drops[totalDrops] = new Drop(); // Increment totalDrops totalDrops ++ ; // If we hit the end of the array if (totalDrops >= drops.length) { totalDrops = 0; // Start over } timer.start(); } // Move and display all drops for (int i = 0; i < totalDrops; i++ ) { drops[i].move(); drops[i].display(); if (catcher.intersect(drops[i])) { drops[i].caught(); } } }