Concept
The artwork initially depicts raindrops falling onto a dark background. I thought of it as a depiction of when I am feeling down or having a bad day. However, I wanted the background to change color as the raindrops are clicked, as I wanted to depict how absorbing the beauty in the small things or interactions can reflect positively on my wellbeing and entirely change the vibe.
Implementation
// global variables let s; let gShapeArray = []; let numShapes = 10; let howmanyCircles = 10; let deletedCircles = 0; let rr = 0; let bb = 0; let gg = 0; //function for detecting the shape on mouse press function mousePressed(){ for(let i = 0; i < gShapeArray.length; i++){ gShapeArray[i].clicked(mouseX,mouseY,i); } } //class for a Shape being dropped class Droped_shape{ constructor() { this.x = random(width); this.y = 0; this.width = random(20, 50); this.speed = random(0.5,3); this.r = random(250); this.g = random(250); this.b = random(250); } //movement downwards move() { this.y += this.speed; } //how the shape is shown on screen display() { fill(this.r,this.g,this.b); stroke(255); strokeWeight(2); ellipse(this.x, this.y, this.width, this.width); this.move(); } //what happens to shape when clicked clicked(px,py,index){ let d = dist(px,py,this.x,this.y); if(d < this.width){ rr = this.r; bb = this.b; gg = this.g; //deleting object from array(destructor) gShapeArray.splice(index,1); numShapes--; } } } function setup() { createCanvas(400, 400); // creating an instance of dropped shape s = new Droped_shape(); //creating initial instances of shapes for(let i = 0; i < numShapes; i++){ gShapeArray[i] = new Droped_shape(); } } function draw() { background(rr,gg,bb); smooth(); s.display(); for(let i = 0; i < numShapes; i++){ gShapeArray[i].display(); //delete circles exiting canvas from array if(gShapeArray[i].y > height){ gShapeArray.splice(i,1); numShapes--; deletedCircles++; } } //controlling the rate and flow of dropped shape let rand = int(random(0, 100)); let rand2 = int(random(0, 100)); //randomly creating shapes over time controlled with two if loops, could have used Perlin noise for this. if(rand % 5 == 0){ if(rand2 % 3 == 0){ //adding obects to arracy (could have been done with gShapeArray.push) gShapeArray[numShapes] = new Droped_shape(); numShapes++; howmanyCircles++; } } //print to console to keep track of circles console.log(howmanyCircles,deletedCircles); }
Some interesting parts of the code were definitely the creating and and using the classes. I wanted the background to take the color of the object that has been clicked. The workaround for this was to assign the objects color (where random RGB values were given to 3 variables r, g and b) to a global variable later assigned to background when the mousePressed() function was called. This could have also been done as an array where the numbers were saved to an array and the values inside the array were later given to the background.
Also, I realized that the array just keeps on taking objects indefinitely, which significantly slowed the sketch later in run-time. The workaround for this was to delete the objects which had reached the bottom of the screen.
I had to revisit a lot of p5.js reference, sketches done during lectures and coding train videos to solidify the concepts of Object oriented Programming before I could implement a functioning class.
Sketch
Reflections
Looking back, I could have used more elegant features such as array.push(object) and Perlin noise to determine creating of objects. However, it was really cool to be able to finally give more meaning to my artwork than before. The animation still isn’t as smooth as I would like it to be, as there are very evident glitches, this maybe due to the inefficient memory use. I would have also like to implement a function to merge objects or detect collisions as this would have made the sketch look much more natural in a way that it shows the true behavior of water droplets.
Nice effect! That’s strange about the visual glitch. I suspect it’s related to line 73 in your sketch – probably when you change the variable that determines the end of the loop (numShapes) from *inside* the loop something gets out of sync. Try putting the logic to delete the shapes outside the loop. Overall the code is very good! Nice parallax kind of effect with the different speeds.