Object-oriented programming – Week 3

Reflection: Floating Bubbles

This artwork is inspired by the simple joy of blowing soap bubbles we used to do as kids. Just like real bubbles, the circles appear wherever you click, float around randomly, and slowly fade away or pop. I wanted each click to feel like blowing a new batch of bubbles, watching them drift and disappear. The way they change color and move in different directions makes them feel alive, conveying the playful nature of real soap bubbles.

Structure

The Circle class manages each individual bubble’s movement, opacity, and lifespan, ensuring that they appear and disappear naturally over time. Functions like setup(), draw(), and mousePressed() organize different parts of the code, keeping it easy to understand and modify.

Challenges

One issue was finding the right balance between movement and fading, so that that bubbles did not disappear too quickly while still feeling transient. Another challenge was making the interaction feel engaging, which I solved by adjusting the number of bubbles created per click and giving them different speeds and directions. Additionally, I had to optimize performance to prevent the sketch from slowing down over time, so circles are now removed once their lifespan ends.

Overall, I appreciate how this piece captures the lighthearted  beauty of soap bubbles in a digital form. To make it more realistic, I’d try to make the direction that bubbles take more random and add the effect of abrupt popping.

// Array to store circles
let circles = [];
let circleSize = 50;
let numCirclesPerClick = 5; // Number of circles generated per mouse click

function setup() {
  createCanvas(windowWidth, windowHeight);
  noFill(); // No fill for circles, only stroke
}

function draw() {
  background(20, 20, 30, 50); 
  
  // Loop through circles in reverse order 
  for (let i = circles.length - 1; i >= 0; i--) {
    circles[i].update(); 
    circles[i].display(); 
    
    // Remove circle when its lifespan reaches zero
    if (circles[i].lifespan <= 0) {
      circles.splice(i, 1);
    }
  }
}

// Circle class (individual moving and fading circles)
class Circle {
  constructor(x, y, size) {
    this.x = x;
    this.y = y;
    this.vx = random(-2, 2); // Assign random speed in x direction
    this.vy = random(-2, 2); // Assign random speed in y direction
    this.baseSize = size;
    this.size = size;
    this.opacity = random(100, 200); 
    this.growthSpeed = random(0.5, 2); 
    this.color = color(random(255), random(255), random(255)); 
    this.lifespan = 200; // Circle disappears after a set time
  }

  // Update circle properties (position, size, opacity, lifespan)
  update() {
    this.x += this.vx; 
    this.y += this.vy; 
    this.size = this.baseSize + sin(frameCount * 0.05) * 10; // Oscillating size effect
    this.opacity -= 2; 
    this.lifespan -= 2; 
  }

  // Display the objects
  display() {
    stroke(this.color);
    strokeWeight(2);
    fill(this.color.levels[0], this.color.levels[1], this.color.levels[2], this.opacity); // fading effect
    ellipse(this.x, this.y, this.size, this.size);
  }
}

// generates multiple circles at the mouse click location
function mousePressed() {
  for (let i = 0; i < numCirclesPerClick; i++) {
    circles.push(new Circle(mouseX, mouseY, circleSize));
  }
}

 

Week 3 – Reading Response

When Crawford mentions at the beginning of the chapter, “The term interactivity is overused and underunderstood” (3), it surprised me as I always believed interactivity involves physically engaging with technology and allowing them to respond to input. However, Crawford makes it clear with his definition being a “conversation,” since to him, a system isn’t truly interactive if it only delivers what it is supposed to respond; it has to listen, think and speak in a way that adapts over time. Additionally, as he asks questions, and even asked one, “Is interactivity utterly subjective?” It really made opened my perspective on what is interactivity, it suggests to me what feels interactive to one person might not feel that way to another, since it depends on their expectations and prior experiences. As a result, it made me realize that with some of my p5.js sketches and exercises, while technically reactive, it isn’t truly interactive.

With my sketches, they don’t have any aspect of interactivity, but they’re rather responsive, especially my previous assignment (for week 2 on loops), since within the sketch, hitting “Enter” would cause my sketch to go from a monochrome grayscale to random, simultaneous pops of color. With that, I aim for future projects to apply similar aspects of interactivity, rather than having them being responsive to user input.

Reading Response – Week 3

I believe that interactivity is like a conversation. It’s alive, reciprocal, and unpredictable. It thrives on an ongoing exchange where both parties listen, process, exchange ideas. Yet sometimes, we tend to mistake reaction for interaction. Imagine a fridge light turning on when you open the door – that’s a reaction. In this context, a true interaction requires intention, curiosity, and a sense of the unexpected.

When designing for interactivity, I want to create projects that thrive on engagement, not just response. In my p5.js sketches, I want to move beyond the input-output relationships and create something that listens and adapts to what the audience feeds to the “artwork”. This may mean making the visuals morph in response to prolonged interaction or rewarding users for exploration rather than just reacting to a single click. In any case, I want each person who interacts with my projects to have a unique experience.

To sum up, I think that a truly interactive system should feel like a dynamic exchange, where the user isn’t just playing with the system but within it. That’s the kind of interactivity I want to create—something more like a meaningful conversation and less like a fridge light turning on and off.

Week 3 : Generative Art

Concept and Inspiration

For this week’s assignment, I drew inspiration from spirals and circles, as symmetry has always intrigued me. The goal was to create a generative artwork, and after reading about interaction in this week’s reading, I wanted to give the viewer creative freedom over the composition. To achieve this, I incorporated keyboard controls for selecting different color gradients and allowed users to click anywhere on the canvas to generate a spiral at that point. Additionally, the canvas can be cleared to provide users with a blank canvas.


IMP : Read before creating ART
Color Scheme (click to choose) –

  • Rainbow: ‘R’ or ‘r’
  • Blues: ‘B’ or ‘b’
  • Blue-Green: ‘G’ or ‘g’
  • Pink-Purple: ‘P’ or ‘p’
  • Yellow-Orange-Red: ‘O’ or ‘o’
  • Purple-Red: ‘S’ or ‘s’
  • Clear Canvas: C or ‘c’

The biggest challenge I faced during this project was related to the creation and positioning of the spiral. I had to make sure that the circles followed the spiral’s curve closely, without leaving gaps between them. Initially, the gaps were too large, and the spiral looked disjointed. I spent a lot of time figuring out how to make the circles remain close together as they moved outward  and to ensure they were placed one after another in a way that created a continuous, tightly packed spiral.

The part I’m most proud of is the creating the spirals. Initially, my spirals weren’t very pretty, as the circles grew apart too much and it didn’t even look like a spiral. It took some time to figure out how to position the circles in a way that made the spiral look smooth and cohesive. After lots of tweaking, I managed to figure out the conditions where the circles would be placed in a way that created an organized spiral.

// Creates Spiral class, which acts as a template to print all spirals
class Spiral {
  constructor(x, y, max_radius, num_circles, color_palette) {
    this.x = x;
    this.y = y;
    this.max_radius = max_radius;
    this.num_circles = num_circles;
    this.current_circle = 0;
    this.angle_increment = 10;  // Places individual circles closer depending on value
    this.radius_increment = 0.3;  // Reduces outward distance between concentric circles of spiral depending on value
    this.color_palette = color_palette;
  }

  // creates new mini circle each time function is called in draw function
  update() {
    if (this.current_circle < this.num_circles) {
      this.current_circle += 1;
    }
  }

  // prints spiral on canvas 
  display() {
    push();
    translate(this.x, this.y);

    for (let i = 0; i < this.current_circle; i++) {
      let angle = i * this.angle_increment;
      let radius = i * this.radius_increment;
      // to control transition of colors for diff color palettes
      let gradient_factor = map(i, 0, this.num_circles, 0, 1);
      
      // defining color gradient for each transition
      let col;
      if (this.color_palette === "rainbow") {
        // Full rainbow transition
        if (gradient_factor < 0.25) {
          col = lerpColor(color(255, 0, 0), color(255, 255, 0), map(gradient_factor, 0, 0.25, 0, 1)); // Red → Yellow
        } else if (gradient_factor < 0.5) {
          col = lerpColor(color(255, 255, 0), color(0, 255, 0), map(gradient_factor, 0.25, 0.5, 0, 1)); // Yellow → Green
        } else if (gradient_factor < 0.75) {
          col = lerpColor(color(0, 255, 0), color(0, 0, 255), map(gradient_factor, 0.5, 0.75, 0, 1)); // Green → Blue
        } else {
          col = lerpColor(color(0, 0, 255), color(255, 0, 255), map(gradient_factor, 0.75, 1, 0, 1)); // Blue → Purple
        }
      } else if (this.color_palette === "blueGreen") {
        col = lerpColor(color(0, 0, 255), color(0, 255, 0), gradient_factor); // Blue → Green
      } else if (this.color_palette === "orangeRedYellow") {
        col = lerpColor(color(255, 255, 0), color(255, 0, 0), gradient_factor); // Orange → Red
      } else if (this.color_palette === "pinkPurple") {
        col = lerpColor(color(255, 105, 180), color(96, 15, 156), gradient_factor); // Pink → Purple
      } else if (this.color_palette === "purpleRed") {
        col = lerpColor(color(128, 0, 128), color(255, 69, 0), gradient_factor); // Purple → Orange → Red
      } else if (this.color_palette === "Blues") {
        col = lerpColor(color(0, 0, 139), color(0, 255, 255), gradient_factor); // Deep Blue → Cyan
      }
      
      // prints each circle with chosen color after calculating positions
      fill(col);
      noStroke();
      let x = cos(angle) * radius;
      let y = sin(angle) * radius;
      ellipse(x, y, 8);
    }

    pop();
  }
}

 

Reflections and Future Improvements
Looking back, I’m happy with how everything turned out, and I especially like that so many different variations can be generated based on user interactions from such simplicity. However, I feel there’s still room to improve the spiral’s look. I want to learn how to adjust the spacing between circles so that they grow proportionally as they move outward, filling the space more evenly. Additionally, I would love to experiment with making the spiral tighter and more closely packed. Also I want to figure out a different ending for the spiral, maybe something like it keeps growing and takes over the whole screen, since right now it just stops adding circles to the spiral.

One thing I loved was how much easier my life became using OOP. Using a class to create a template for the spirals allowed me to generate as many spirals as I wanted without much effort. It’s fascinating to see how simple code structures can support more dynamic and complex artistic ideas, and I’m excited to keep refining my approach to generative art.

Week 3- reading

A strongly interactive system is one that supports an ongoing exchange between the user and the system, rather than a simple cause-and-effect response. , Crawford emphasizes that true interactivity requires a two-way conversation where the system not only responds to user input but does so in a way that is meaningful, engaging, and adaptable. It should be responsive, intuitive, and immersive; the users should have a good feeling about their actions being effective and that the system responds organically. One of the most critical aspects of interactivity is real-time feedback. When users interact with a system, they should immediately see or feel the consequences of their actions. This could be through visual changes, such as color shifts, animations, or movement, or through sensory feedback like sound effects and vibrations. The more immediate and natural the response, the more engaging the experience becomes.

To enhance the degree of user interaction in my p5.js sketches, I’d like to further develop more dynamic and reactive elements. For example, objects could be made to react to cursor movement through changes in shape, speed, or transparency, making it more alive. Another idea could be to utilize randomness to provide variety, where each interaction results in slightly different outcomes, allowing the artwork to feel organic instead of predictable.

I am interested in the use of multi-layered interactions where, with one input from a user, a chain reaction occurs rather than a single event. For instance, the click of one element may cause another object to move, change color, or fire off another animation sequence. Incorporating this will allow for a richer experience where users can be drawn into the artwork and experiment with how they interact with it.

My long-term aim is to create interactive sketches that are alive and responsive, creating an encouragement to experiment and discover unexpected outcomes. This refinement of how the system responds to the input provided smoothes out the interaction, thus making it much more immersive and engaging rather than just a number of responses with my generative artwork.

 

Week 3- car

Concept
This will be a generative artwork of a dynamic cityscape in which cars move along a busy street; the colors of buildings will change over time. The rhythmic movement within an urban setting will be simulated using programmed randomness and structured object-oriented programming. It also lets users interact with the scene-for instance, causing the cars to crash by clicking on them. A bright yellow flash to mark the moment of collision adds engagement and surprise.

Development Process.

This project deals with the work of OOP principles on such elements as cars, buildings, and road features.Arrays are used to hold these objects and then manipulated for flexibility in animation. The cars move continuously across the screen, resetting at their edges, and the buildings keep slight variations in height and color to give it a more organic feel as if from a real city. Introduction of clickability on the cars introduces user interaction, an important aspect of making the artwork from a simple, passive, visual display into an active system. Challenges and Refinements Among these, one major problem was getting the cars to glide smoothly across the road, which kept floating above it, out of alignment with the street. Changing some positions and managing more realistic layering helped improve that aspect. The second aspect was embedding the collision effect impressively while managing the aesthetics of the overall scene. The crash effect turned out much better with just fine-tuned timing and changes in opacity of the yellow flash, not to overwhelm it.

Future Improvements
There are several possible ways to take this project even further. One could add in environmental elements such as weather effects, changing times of day, or a richer soundscape for added realism and interaction. Implementing more complex behaviors for the cars, like random stops or variable speeds, would also increase the depth of the simulation. Finally, making the user be able to reset or change the scene dynamically within the artwork will make it far more engaging and replayable.

Code im am proud of is this specially

 }

  crash() {
    this.isCrashed = true; // Car stops moving
    this.speed = 0; // Set speed to 0 for a realistic stop
  }
}

where I figured out how to make the car stop to seem like it crashed

Week 3 OOP + Reading

Being tasked with creating generative artwork using Object Oriented Programming, I thought of my intent and drew inspiration from the Perlin Noise algorithm developed by Ken Perlin. Reminiscent of my generative artwork for week 2, I decided to create polygons of a dynamic (n) sides. These sides are adjustable by the user and through rapid clicks and interaction, the number of n sides of the polygons increases. The polygons also rotate in a random manner, as my artistic intent was to not follow a specific order, rather to allow the objects to move in any manner.

 

Without the rapid clicks, the art at hand is emphasized through the Perlin Noise effect, where the movement of the mouse generates a subtle but artistically significant noise.  In the grander sense, I would replicate this generative artwork on a larger scale, a larger screen, or perhaps that its canvas doesn’t have boundaries and is projected. However, to show a simple demonstration of it this pop-up suffices.

Technical Details:

I created three classes: Star, StarryBackground, and NoisyShape. The first class is responsible for the individual stars with a glowing effect, making the artwork seem more realistic and complimenting the life that the Perlin Noise adds to the art.  StarryBackground manages this array of stars and organizes them into the background of the canvas. NoisyShape is the key class for interaction and animations in the art, where rapid clicks change the level of noise, n sides, and creates distinctions in every iteration (the canvas constantly changes and does not reset).

I highlighted this class as it was the most interesting part to me:

 

//Noisy Shape and PERLIN POLYGONS

// A dynamic, multi‑sided polygon whose vertices are perturbed by Perlin noise.
class NoisyShape {
  constructor(x, y, radius, nSides) {
    this.x = x;
    this.y = y;
    this.radius = radius;
    this.nSides = nSides;
    // Pick one of the strategic colors.
    this.col = palette[int(random(palette.length))];
    this.noiseOffset = random(1000);
    this.rotation = random(TWO_PI);
    this.rotationSpeed = random([-0.001, 0.001]);
  }
  
  update() {
    // This creates an animation that rotates the polygons after rapid clicks, creating a dynamic and randomized movement.
    this.rotation += this.rotationSpeed;
    // When rapid clicks occur, intensify effects:
    if (rapidClickTriggered) {
      this.rotation += random(-0.05, 0.05);
      this.x += random(-3, 3);
      this.y += random(-3, 3);
      this.noiseOffset += random(0, 0.02);
    }
  }

Specifically, the part that stood out to me in creating this class was the perturbation of the polygons by the Perlin Noise.

 

READING THE ART OF INTERACTIVE DESIGN

 

Upon reading the art of interactive design, the author’s use of an introductory scenario to highlight a simple instance of interaction ( a conversation ) stood out to me and helped set a conceptual basis of interaction for me. What interests me is the assertion of this conceptual basis without referring to etymological significance in meaning. I believe that the author does this so as to not subtract from the emphasis on clarity through the concise medium of the scenario. However, I would argue that a small reference to the etymology of the word ‘interact’ inter + – act inter: A latin word meaning between. act (derived from the latin word ago) : Do / Action. This would help solidify the importance of displaying how important the reciprocation is in this back and forth between two actors

The simple conversation between Gomer and Fredegund does that exactly. It shows how important the roles and actions of both actors are. Therefore, the counterarguments the author answers in the subsequent passages are dismissed on the basis of weak interaction between (where one actor does the majority of the actions, and there is no distinct reaction by the other actor). i.e reading a book, movies, the example of Greeks and Romans in viewing paintings (which is significant in the context of computed generative art).

What stands out to me and impacts me in this reading is the utilization of the definition under the author’s continuous conceptual framework, highlighting interaction as a continuum… Therefore, I transcend my opinion and thoughts on interfaces as mediums to facilitate these interactions , thinking about the possible ways of facilitating interaction with no compromise on listening, thinking, and speaking.  Therefore, I must think of the user’s perspective or I would now have another user interact with my work, whilst making my own metrics as measures of these three aspects. Additionally, there must be a consideration of the target user / audience to establish a basis for how well that person would be able to think and speak. Therefore, I feel incorrect in how vaguely I thought of this part of interaction, with the assumptions that the interaction would be highly intuitive to everyone, and that they would be able to speak easily.

Assignment 3 – Reading Response

Reading this chapter made me realize how often we misuse the word “interactive.” Before, I thought anything that let me click, tap, or control something was interactive. But Crawford argues that real interactivity is more than just pressing buttons—it’s about a meaningful exchange between the user and the system. A slideshow where I click “next” isn’t really interactive because it doesn’t respond in a thoughtful way. It just follows a script. This made me think about how many things we call interactive today—like online quizzes or simple video games—are actually just reacting, not truly engaging with the user. It kind of changed how I look at apps and games because I started noticing which ones actually respond to my choices and which ones just make me feel like they do.

One of the most interesting points Crawford makes is his comparison between interactivity and conversation. A real conversation isn’t just one person talking while the other nods—it’s about listening, responding, and adapting to what the other person says. I never really thought about technology in that way, but it makes sense. The best apps, games, or even websites feel like they “listen” to you and react in a way that makes sense, while others just follow a script no matter what you do. It made me appreciate good design more, and it also made me think about how this applies to real life. Even with people, there’s a difference between actually engaging with someone and just waiting for your turn to talk. Crawford’s ideas stuck with me because they apply to more than just interactive design—they apply to how we communicate and connect in general.

Week 3 response

Chris Crawford stresses that interactivity is fundamentally a two-way exchange, in which both the user and the system actively listen, think and respond. He defines interactivity as a cyclical process of input, processing and output, and gives as a concrete example the interaction in a conversation and its implications, distinguishing it from passive experiences such as watching television.

A strongly interactive system must give priority to verbs-what the user can do-over nouns or static elements. For example, Crawford criticizes poorly designed software that overwhelms users with visual complexity but offers little meaningful action. To improve user interaction in p5 sketches, one could focus on creating dynamic feedback loops. For example, rather than simply displaying shapes, a sketch should allow users to manipulate them through mouse or voice gestures, with immediate visual and auditory responses. Crawford also highlights the importance of clarity and simplicity: interactive systems should avoid overwhelming users with unnecessary complexity. Applying this principle, a p5 sketch could use intuitive controls, such as drag-and-drop mechanics or touch interactions, to ensure accessibility.

In addition, Crawford’s insistence on designing for the user experience suggests incorporating playful experimentation into sketches, such as allowing users to “paint” with random colors or shapes that evolve based on their inputs. These ideas are in keeping with his core philosophy: interactivity thrives on meaningful participation and responsiveness.