Assignment 3: Nostalgia in Bubbles

Concept:

For this artwork, I wanted to capture the childhood memory and experience of when we would go outside to play with bubbles. My aim is to be able to relay that nostalgic, hazy, dreamy feeling using soft colors and a gradient background of the sky and grass but in a blur just like the memories. I did not want it to be too complex but simple, carefree, and fun instead because that is how life was, where popping bubbles was the highlight of our day and running out of the bubble soap was our low.

If you press a key, bubbles spawn. If you mouse click, a bubble pops. I intentionally did it this way because the press of a key reminded me of when we would press on a bubble machine to blow out more bubbles, and the click of the mouse reminded me of how we would run, jump, and reach out with our hands to pop the bubbles as fast as we can before it flies too high or pops on its own.

Highlighted Code:

// "pops" the bubble
function mousePressed(){
  for (let i = bubbles.length - 1; i >= 0; i--){
    let distance = dist(mouseX, mouseY, bubbles[i].x, bubbles[i].y);
    if (distance < bubbles[i].size / 2){
      bubbles.splice(i, 1);
    }
  }
}

I am proud of this function because it creates the main interactive feature: popping the bubbles. I had to do some research in order to figure out how to get it to pop but also used previous dist() knowledge from Week 2 to calculate the distance between the mouse and the center of the bubble. The code splice() was used to remove the bubble from the array when clicked. I think I am most proud of it because it wasthe code that had the most trial and error, which I explain more in depth in the “How This Was Made?” section.

How This Was Made?

The majority of the code was made using what we learned in class. In the Bubble class, I added this.size in order to produce many different sizes of bubbles to match realistically how it is. To add to that, I also created an array of different colors that picks between them randomly  using this.color for that very same reason. I searched for a bubble color palette on Google and scrolled till I found the one that matched the vision in my head and used those colors.

For the bubbles it is just one perfect ellipse based on this.size, which is a random number between 50 and 150. The two small reflection spots are also ellipses but multiplied by + or – 0.1-0.3 to make it smaller. Though small, this is what adds dimensions and makes the bubble look like a bubble.

I let keyPressed() create a new bubble instead and mousePressed() to pop it. For keyPressed() I ran into an issue where the bubbles would almost disappear because they would go out of the canvas, so I had to subtract the radius (this.size / 2) from the width and height in order for it to bounce off immediately as it touches the canvas borders.

For the bubble popping part, I knew I needed dist() as wherever mouseX, mouseY, and the x and y values of the certain bubble[i] in the array is, but I was unsure how to have it “pop” because when I actually used bubbles.pop() it deleted the last bubble that was made regardless of where I clicked. I noticed that the previous student’s example used splice(), but she also had other variables and codes that made it confusing to understand. So, a simpler way was just searching up “bubbles popping p5.js” on google. I ended up finding an example made by someone and noticed they used splice() as well. I asked Gemini to explain how their code works and then I implemented it on my own. Their code had the distance in a separate function, so I just combined it in the same mousePressed() function because it felt unnecessary and simpler.

I did the gradient background last because initially I was just going to leave it as a plain light blue; however, I did not think it encapsulated the nostalgic, hazy, childhood memory feeling, so I thought a gradient from light blue to green would be better. It matched my bubble reference image where you see the sky above then the greenery below it. I searched for “gradient background p5.js” and found a simple example. I recognized lerpColor from a classmate’s palleteLerp() code but wanted to know more about how map works, so I looked for the reference. It learned that it converts the coordinates to numbers between 0-1 as a the percent lerpColor needs to blend c1 and c2.

Reflection:

Overall, I am pretty happy with how it turned out because I think that I achieved that nostalgic, childhood feeling I was going for. I feel like this assignment definitely helped me understand classes more and allowed me to explore new things that we have not learned. In the future, I could maybe do more with the background like having the gradient flow and move around from top to bottom like an actual hazy memory. For improvements, I also found a p5.js example where they actually installed a bubble pop sound that plays when the user “pops” a bubble, which I thought could have been a fun interaction and addition to complete the experience.

References:

Bubble reference image: https://www.pinterest.com/pin/112027111108718506/

WK13 Bouncing ball example: https://editor.p5js.org/Aya_Riad/sketches/Wky6-ythQ

Previous student example: https://editor.p5js.org/AyshaSalma/sketches/09cZh8SDk

Bubble pop example: https://editor.p5js.org/haydencarey/sketches/4Jksy0Odg

map(): https://www.geeksforgeeks.org/javascript/p5-js-map-function/

Gradient background example: https://editor.p5js.org/evebdn/sketches/O9G35ueZv

Bubble color palette: https://www.schemecolor.com/colors-of-a-soap-bubble.php

WK3 Creative Reading

In the reading by Chris Crawford, they define interaction as “a cyclic process in which two actors alternatively listen, think, and speak.” He emphasizes that there are two actors, not one, and that is the only way to define something as interactive, but I disagree with his definition. I feel like there does not have to be a back and forth and an interaction can just be something simple like the user just clicking something and something appears. For example, in my Assignment 3, I had an interaction where if the user presses a key, a bubble appears, and if you click on the bubble, it disappears. To me, that is interaction even though the p5.js system is not necessarily thinking or speaking. I would describe it as what he thinks is low interactivity.

With that, I think characteristics of a strong interactive system is, first of all and most important of all, the system responding to the user. This means that the user should have input and be able to affect the outcome. Now, what makes a strong interactive system I think should be having multiple different outcomes, so multiple user inputs. In the section about “Thinking” he was talking about communication and how when you talk with someone who is a slow thinker, the conversation is meaningless and how “Good thinking can make a conversation sparkle.” Therefore, another strong interactive system has to feel engaging, so the user feels like whatever it is they are controlling in the system matters and is worth their time.

Finally, after reading and analyzing the text, some ideas I have for improving the degree of user interaction in my p5 sketch is maybe having the bubbles make a pop sound when the user clicks it. I could also have the user decide what size and color they want so they could personalize it. I also thought of having the background move as a gradient to the direction of where the mouse hovers.

Assignment 2: Disco Dance Floor

Concept:

For this second assignment we were instructed to code an artwork using the concepts we have learned in class this second week. Initially, my concept was inspired by the atmosphere of a disco dance party where the grid of squares represent a disco ball.

 

However, when I added the diamond shape to appear based on the mouse position to represent the sparkles when light reflects off it, it reminded me of a different idea. Seeing the grid of squares, the colors changing, and an object moving using my mouse gave me a sense of deja vu and reminded me of when I used to play Club Penguin. Specifically, the night club dance floor. So, I pulled up a reference image to help me tweak a few things like changing the color scheme to match it and changing the diamond shape to appear into the closest penguin I could code that looked like a Club Penguin.

I liked this idea and direction because it allows my project to be interpreted in multiple ways and combines both my initial idea and my current one. When the mouse is not in use, it can still be portrayed as anything within the realm of dance, parties, and disco based on the perception of the viewer. This is why I kept the sizes of the square to be random even though it is static in the club penguin dance floor, I felt like it made it visually dynamic and added energy like how a real, lively dance floor is and also how disco ball patterns rapidly change as though it is spinning fast and reflecting the different colorful lights of the vibrant environment usually in parties.

Highlighted Code:

// random color + size 4 the rect/tiles
  let color = random(7);
  let size = random(35, 40);
      
      if (color < 1) {
        fill("#ffffff");
      } else if (color < 2) {
        fill("#d970ff");
      } else if (color < 3) {
        fill("#ff2e1f");
      } else if (color < 4) {
        fill("#3ef226");
      } else if (color < 5) {
        fill("#f4f830");
      } else if (color < 6) {
        fill("#3ef9ca");
      } else {
        fill("#ee9f5d");
      }

      rect(x, y, size, size);

This code assigns color a random number between 0-7 and size a random number between 35-40 and based on that it fills the rect() a certain color and width/height. I am particularly proud of it because I had previously known about the random generator code I just had to see how it worked in p5js as my knowledge was from python. Knowing now that I can set up random() to be in between a certain amount of numbers by setting the maximum amount within the parameter made it pretty easy to code the rest with simple if/elseif/else statements. So, if the random() let color to be 2 then the rect() would be filled with the color red because (color < 3) would be finally true. I liked that I was independently applying something I had learned from before rather than just following an example and seeing my vision come to life.

How This Was Made?

To create the grid of squares I used the help of Week 2.2’s classwork example for the nested loop and I just played around with the x and y values to get the squares as close as I want them to be. Then before the rect() executes, I had the random size and color if/else statements that I explained in the Highlighted Code section to fill it a random color and give it a random width and height. For the penguin part, in order to make it appear based on mouse position and within a certain part of the canvas, I used Week 2.1’s example of the && logical operators. The mouseX and mouseY part makes sure that the mouse is within the boundaries of each grid square and I used the same number (42) that I used in the nested loop in order to have matching spacing. This is what makes the penguin appear right above each tile that the mouse is hovering over. For the penguin part, It was just multiple ellipses stretched out in different widths and heights based on the body part. It took a bit as I had to keep going back and forth checking with the mouse then adjusting the x, y values but it worked out in the end.

Overall, I used the Club Penguin reference image, the random() p5js reference, Week 2.1 examples, and Week 2.2 examples.

Reflection:

I am happy with how my artwork turned out because the whole development was fun to work with. I started with a disco ball-inspired art then ended up with a mix of both that and a Club Penguin dance floor. My previous work was SpongeBob SquarePants and I really enjoy the assignments when I make them more personalized to my likings, yet still abiding by the instructions. The final artwork is more than just a visual idea, but a nostalgic memory to I am sure many people.

For future developments, I have a couple of suggestions for myself if I had more time and that would be maybe to add multiple penguins in the dance floor. I could have them placed on a certain grid when the mouse is pressed and have them change colors like how the real Club Penguin actually is. I could also have the tiles change colors when the penguin is hovering over them kind of like the penguin (user) is activating the dance floor. It would make the final piece more interactive and playful for the user, yet still preserving the main concept of the artwork.

WK2 Creative Reading

Before watching the video, I did not like the idea of disorder or randomness, as I felt like it meant going out of routine. I feel more comfortable with the expected rather than the unexpected. After hearing Casey Reas’s thoughts about how it can be used as a tool to create something that the artist may not have expected, I am more open to it and think that it can create unique outputs. It also made me realize that if I were not open to it, then I would not have been able to code my second assignment. My second assignment used the random() code to generate the different colors of the dance floor. In [27:03] he talks about Lia’s random 4×4 generative design and how the increase in deviations of pixels transitioned the design from order to chaos. This made me realize that I answered the first question, which is that I have already implemented that chaos part in my second assignment, where I have the tiles/rect() randomly change between 35 and 40, which made it visually dynamic and added energy like how a real, lively dance floor would. For the second question, I think that a balance between randomness and complete control is the best because there should be structure, but having randomness makes the final design look more unique and interesting. So, for my Assignment 2 example, if the frameRate() was high, then the dance floor tiles would be too chaotic to the point that they would not have even looked like a dance floor. Thus, having a good balance between chaos and control is best as long as the meaning of what you are trying to depict is still understood.

Assignment 1: Portrait of SpongeBob SquarePants

Concept:

For this first assignment we were instructed to code a self-portrait. Instead, I thought it would be more interesting to code a childhood favorite character: SpongeBob SquarePants. For some reason, he was the first character that came to mind when we were told that we were allowed to code anything, not necessarily ourselves. When I googled SpongeBob to use as a reference image while I coded, I was able to analyze it and think of all the different shapes I could use for each part. I broke every part down into little pieces so I could visualize the shapes it needs, which helped me code it much more efficiently.

Highlighted Code:

// 4a. eyes + lashes
  // left eye
  fill('#2f2f2d'); // eyelashes
  stroke('#2f2f2d')
  strokeWeight(1.5)
  rect(141, 102, 5, 20)
  
  fill('#2f2f2d');
  stroke('#2f2f2d')
  strokeWeight(1.5)
  rect(156.5, 100, 5, 20)

  fill('#2f2f2d');
  stroke('#2f2f2d')
  strokeWeight(1.5)
  rect(172, 102, 5, 20)
  
  fill('#ffffff'); // eyeball
  stroke('#2f2f2d')
  strokeWeight(1.5)
  ellipse(162, 147, 70, 72)

  fill('#26B9C8'); // iris
  stroke('#2f2f2d')
  strokeWeight(1.5)
  circle(165, 147, 30)

  fill('#2f2f2d'); // pupil
  stroke('#2f2f2d')
  strokeWeight(1.5)
  circle(165, 147, 15)

  fill('#ffffff'); // "reflection"
  noStroke()
  circle(163, 140, 6)

  fill('#ffffff');
  noStroke()
  circle(170, 153, 3)

  // right eye
  fill('#2f2f2d'); // eyelashes
  stroke('#2f2f2d')
  strokeWeight(1.5)
  rect(216, 102, 5, 20)
  
  fill('#2f2f2d');
  stroke('#2f2f2d')
  strokeWeight(1.5)
  rect(230.5, 100, 5, 20)

  fill('#2f2f2d');
  stroke('#2f2f2d')
  strokeWeight(1.5)
  rect(245, 102, 5, 20)
  
  fill('#ffffff'); // eyeball
  stroke('#2f2f2d')
  strokeWeight(1.5)
  ellipse(233, 147, 70, 72)

  fill('#26B9C8'); // iris
  stroke('#2f2f2d')
  strokeWeight(1.5)
  circle(230, 147, 30)

  fill('#2f2f2d'); // pupil
  stroke('#2f2f2d')
  strokeWeight(1.5)
  circle(230, 147, 15)

  fill('#ffffff'); // "reflection"
  noStroke()
  circle(228, 140, 6)

  fill('#ffffff');
  noStroke()
  circle(235, 153, 3)

This is the code I wrote for the eyes. I am most proud of it because it looks almost identical to the actual SpongeBob character. It is the first thing that stands out when I look at the code. Also, the placement of the eyes is well-positioned for the face as well as the iris, pupils, and reflection spots. On top of that, both eyes are identical with the same structure and dimension. I also really like that I added the two small white circles that serve as reflection spots. I initially was not going to do it because I did not feel like it, honestly, but I am so glad I did. Those four little white circles made all the difference, as they made it seem like it was animated and lively. It really was the cherry on top.

I think an honorable mention would be the outline of SpongeBob’s face, as anyone could have easily just done a square, but I think the curves, though it took long to code, is what made it really look like SpongeBob after the eyes.

How This Was Made?

When I started the code, I just had a yellow rectangle (almost square) and a thin white rectangle under for the shirt and a thin brown rectangle under that for the pants. After I pulled up a reference image of SpongeBob to help me code, I realized that the shape of the head was not ideal, as it is more of a square cloud with the curves. For that, I used ellipses to create different circular shapes for the natural, uneven curved face. A mistake I noticed after reaching the bottom is that due to the face code being at the start, the shirt overlapped it, so I had to rearrange the code throughout the entire process in order of the correct layering.  This happened with the lashes too, so I had to have that first before the whole eye. It also happened with the shirt, where I had to have the code for the arms first as well.

For the eyes, I used an ellipse for the eyeball because it did not look like a perfect circle based on my reference image. The iris, pupil, and reflection spots were all circles. Then for the mouth, nose, and cheeks, I used PI and TWO_PI to create the half circles. The lashes, teeth, and black belt all just needed the rectangle shape but in different positions. For the collar, I used triangles and quads for the tie, as it starts with an upside-down trapezoid and then a sharp diamond. Finally, I just used a mix of circles and ellipses as the sponge marks SpongeBob has on his face to make it more identical with the animation.

This all wouldn’t have been done without the code that prints the mouse’s X and Y because that made positioning everything much easier and took less time.

The only source I used to help me code was the p5js reference site to remind myself of the parameters of each shape, especially for the arc. It is what made me realize that I could set PI as the starting point and have it end at TWO_PI to make an upside down half-circle for the cheeks and nose. I also used the website Color Hex Color Codes and SchemeColor to get the most accurate color palette of SpongeBob SquarePants.

Reflection:

Overall, I am super proud of how my code turned out. It was better than I had expected even though I had my doubts throughout the whole process. It was a really satisfying process seeing the image come to life as I code, edit, and make changes. It was also enjoyable, as I knew what to do to achieve the results I wanted but just needed the time and patience and trust in the process.

For improvements, I would definitely have to say the smile. SpongeBob actually has a much bigger smile with a deeper and taller curved smile that reaches all the way to his cheeks. Unfortunately, I was not sure on how to do that, and that is what made the final product slightly inaccurate. I tried having the half-circle shape as the mouth and two triangles on the side of each to pull them and make them more curved, but it did not work out due to the strokes. It also looked rigid and not smooth. If I wanted to add anything in the future, it would definitely be a SpongeBob-related background with all the fun colors and shapes.