Week 3 – Object-Oriented Programming

Concept: I wanted to create an interactive art piece while challenging myself code-wise. I settled on a little game of popping balloons. I used class to make the circles. I also randomized colors from a set of specific colors in an array. The interactive part of the art is when a circle is clicked, it disappears, giving the popping effect.

Code: I’m specifically proud of this line of code because I used the not condition to check whether to continue growing based on a mouse click.

grow() {
    if (!this.clicked) { // Only grow if not clicked
      this.radius += this.growthRate;
      if (this.radius > this.maxRadius) {
        this.radius = this.maxRadius; // Capping the radius
      }

Problems: A problem I faced was having the circles overlap the text, hiding it from sight. Another one was needing to refresh the sketch to repeat the art. I wish I could have implemented a way that when all balloons are popped, it regenerates them by itself.

 

Reading Reflection – Week 3

Crawford argues that big ideas are elusive and hard to capture in a sentence-long definition, and I agree. However, he then proceeds to do this and limit what can be considered interactive. He argues that books, movies, and performance art are not interactive, but I beg to differ. Consider a choose-your-own-adventure movie or book; is this not regarded as interactive? One could argue that Crawford’s book was published in the early 2000s, so he might not have heard of such media. Yet those interactive forms, specifically books, were famous in the 90s.

Another example that he fails to consider is stand-up comedy. The comic interacts with the audience, listening, thinking, and speaking, all of which Crawford states are part of an interactive piece. Add to that, many of the jokes in a set come from the ability of the comic to improvise based on the audience, further proving the point that performance art is interactive. Putting that aside, I agree with him that interactivity relies on good listening, thinking, and speaking. This could be applied to p5 by implementing real-time feedback mechanisms that respond to user input—for example, having the sketch change based on whether the mouse is pressed.

Week 3 Reading Reflection

Chris Crawford’s “The Art of Interactive Design” emphasizes the importance of interactivity as more than just a simple response to input. Crawford defines true interactivity as a system’s ability to listen, think, and respond, much like a conversation. This approach highlights the need for thoughtful engagement between the user and the system, ensuring that interactions feel dynamic and meaningful. Systems that effectively apply this model create ongoing exchanges, where both user and system influence each other, ultimately making the user feel actively involved and engaged in the process.

In improving the level of interactivity in my p5.js sketches, I aim to apply these concepts by going beyond simple triggers and creating a more thoughtful, adaptive experience. Instead of a one-time action from the user generating a single response, I want the system to react dynamically, changing multiple aspects of the sketch based on continuous input. For example, rather than a simple click to trigger an animation, the user’s actions could influence multiple variables like movement, color, and object behavior, creating a more engaging and evolving experience. Crawford’s “listening, thinking, and responding” approach can help me develop sketches that offer a richer interaction and make the user feel more connected to the experience.

Week 3 – Ripple Matrix

Overall Concept

The goal of my artwork was to create a trippy, mesmerizing experience by combining a grid background with a ripple effect triggered by mouse clicks. The ripples grow from the point of the click, creating an expanding circle that contrasts with the static electricity-like grid in the background. The artwork plays with randomness in both the grid’s colors and the ripple’s growth, making each frame visually unique. By using Object-Oriented Programming (OOP), I was able to structure the code cleanly and efficiently manage multiple ripple effects simultaneously.

Code Breakdown

  1. Object-Oriented Programming with the Rippler Class
    The ripple effect is generated using a class called Rippler. Each time the user clicks on the canvas, a new ripple is instantiated at the mouse position. The class allows each ripple to grow over time, giving the illusion of waves expanding across the grid.
  2. Arrays for Storing Objects
    I used an array to store all the Rippler objects so that multiple ripples can be drawn and expanded at once. This approach also allows for scalable complexity, as the number of ripple effects grows depending on user interaction.
  3. Grid Background Functionality
    I created a function, drawgridColors(), to generate a background grid. Each square in the grid is assigned a random color from a predefined set. The randomness, combined with the small size of each square, gives the grid a look similar to static electricity.

Favorite Part of the Project

My favorite part of this project was building the background and giving it a static electricity kind of look. Although it wasn’t too difficult, the way the grid feels alive with random colors constantly changing adds a nice touch. The following snippet was key to achieving this effect:

for (let i = 0; i < height / size; i++) {
  for (let j = 0; j < width / size; j++) {
    let colorIndex = int(random(possibleColors.length)); 
    let thisColor = possibleColors[colorIndex]; 
    fill(thisColor); 
    noStroke(); 
    rect(i * size, j * size, size, size); 
  }
}

I enjoyed how simple it was to achieve this effect by filling the grid squares with random colors, yet it visually complements the dynamic ripples on top.

Inspiration and Future Improvements

My inspiration for this artwork came from the desire to create something that would be visually captivating and somewhat hypnotic, giving a trippy experience for viewers. I wanted the ripples to feel as though they were interacting with the chaotic, staticky grid background.

For future improvements, I’d love to make the project more interactive. For instance, I could implement different types of ripple effects or allow the user to control the grid colors or the ripple speed through keyboard input. This would enhance the trippiness and interactivity of the piece.

Challenges and Problem-Solving

One challenge I ran into was ensuring the grid and the ripples didn’t conflict visually, especially since both involve overlapping elements. Adjusting the grid size and ripple speed helped balance the visuals.

Another issue was managing the frame rate. I needed the grid to update slowly while allowing the ripples to grow at a faster pace. By setting a lower FrameRate  and controlling the ripple speed manually in the Rippler class, I was able to solve this.

 

 

Week 3 – Starman’s Spaceship

CONCEPT:

The idea came to me when I was listening to one of my favourite songs — David Bowie’s Starman (2012 Remastered version of course). The song is essentially about an alien, stuck in space, trying to find a community. One of the lyrics particularly inspired me to create the final vision –”There’s a starman waiting in the sky”. In terms of the project, I then imagined the screen to display bright, twinkling stars as spaceships explore the universe. Initially, I thought to just include one spaceship, but then, upon deeper reflection, I thought it would be a nice challenge for me to understand how I can generate different spaceships without adding any sort of manual commands. The alien (Starman), is us all — we’re navigating through the domain that is our life, which is reflected by the different coloured spaceships, symbolising different aliens trying to fit in. Each spaceship, represented in different colours, symbolises various aliens striving to fit into the cosmos, reflecting our own journeys through life. The different backgrounds depicts the unique journey each alien has — the stars are automatically rearranged when the user clicks the screen, to explore the journey of another alien in a spaceship.

 

VISION:

It was quite a challenge for me to be able to exactly visualise what it is I want to execute. Therefore, I came up with a simple, initial sketch to sort of understand what is supposed to be on my canvas, and perhaps what is supposed to happen. The sketch showcases two things namely: the background, and the starships. In this drawing, I drew two spaceships because at the time I had thought of displaying multiple spaceships, stationary.  However, as I began to implement the vision, I came to understand that it would look plain and it would block  the focus of the piece: the twinkling stars.

IMPLEMENTATION:

I decided to not store the starships in an array, unlike with the stars, because it did not make sense to me. The spaceships would appear and disappear one click at a time, so there was no actual reason for it to be stored in any sort of way. 

I focused on creating the spaceship first, as I wanted to see if I could make them fly. I first began by creating the class, and then manually generating them, e.g. spaceship1.show(), spaceship2.show(), for testing purposes. The spaceship was mreo tricky than generating the background for me, as I sort of struggled to understand how I can make them generate the spaceship at a certain set of coordinates without it going beyond the boundaries of the canvas. However, I then came to the realization that I can change the parameters in the this.x, and this,y, value so that they appear within the boundary, as the parameters I had them at originally were (0,600)

regenerate() {
  
  // to make the space ships a bit unqiue
  this.w = random(70, 100); 
  this.h = random(50, 70);  
  // instantiates ship at random pos
  this.x = random(50, 500);
  this.y = random(50,500); 
  
  //unqiue colours
  this.color1 = color(random(255), random(255), random(255)); //top col
  this.color2 = color(random(255), random(255), random(255)); //bottom col
}

In terms of the stars, I believe I am quite proud of my code, especially as the result of the background is quite aesthetic. I decided to create an array, so that the stars are stored into it as they are spawned, so that it is easier for them to be displayed in the draw function. I am mostly happy with my twinkle function, as I had thought long and hard about how to make it seem like it is getting brighter or dimmer. However, at the time, I was also experimenting with the opacity of the stars ellipse, to see how bright they should appear on the canvas — which then led me to the realisation that I can quite literally increase or decrease the opacity to give it the desired visual effect.

 
twinkle() {
  this.opacityChange = random(5);
  this.opacity *= this.opacityChange;
  
  // check if opacity is set below
  if (this.opacity < 50) {
    this.opacity = 50;
    this.opacityChange *= this.opacity;      
  }
  
  // check if opacity goes above
  if (this.opacity > 255) {
    this.opacity = 255;
    this.opacityChange = this.opacity;

  }
}

    

REFLECTION: 

If I were given the opportunity to further this piece, perhaps I would add another level of interactivity to the spaceships. Maybe I would make them shoot different coloured beams in any direction I am pointing at, storing them into an array, implement sound, or even some sort of rotation to add another pop of visual activity.

Reading Reflection – Week 3

In my opinion, a strongly interactive system should effectively incorporate all three aspects the author mentions in The Art of Interactive Design: listening, thinking, and speaking. I think that video games are a good example of an interactive system, hence to illustrate these characteristics, I will use a recent game I played, It Takes Two.

Regarding listening, It Takes Two, like many storytelling games, implements this by “listening” to the user’s input. In other words, the game adapts its narrative based on what the participants choose or want to experience. It Takes Two tells the story of a couple on the verge of breaking up, who are brought back together by their daughter-a very relatable story that touches on the theme of family.

The second aspect is thinking, which, in my view, is not always the best metaphor for interactivity when applied to machines. The concept of thinking is vague, and we usually associate it exclusively with humans. Despite that, I interpret “thinking” as the system’s ability to process information, or the mechanisms the designer employs to create meaning. In games, I see thinking as the game mechanics. For example, It Takes Two requires tasks to be completed by two players, which demonstrates how the system accepts input and processes it.

The last aspect is speaking. It Takes Two uses the adventure through the couple’s old possessions to retell their past, implementing “speaking” by showing how the interaction unfolds. This aspect prompts the user to react to the machine.

When discussing interactive design, I think most people tend to focus on the speaking aspect-the demonstration-more than on the other two factors. However, for an interaction to be well-executed, all three aspects need to work in harmony. I often fall into the trap of focusing solely on demonstration. In future projects, I want to focus on incorporating more meaningful interaction mechanisms and exploring how they can better convey the story.

Assignment 3 – The Alternate Universe

Concept

Imagine a universe where two planets exist on the same orbit. For many years, I’ve been working on fictional stories, and I wanted to bring one of these concepts to life using p5.js for this assignment. The idea emerged a while ago, and although it was inspired by sci-fi media, I can’t say I’m directly mimicking anyone else’s work. The concept for this project is to make the two planets move 180 degrees apart, as if they are locked in orbit, to prevent them from crashing into each other (I’m aware that real planets don’t behave like this). This is how the project began. During the planning stage, I used Adobe Photoshop to composite some images, which helped me visualize how I would approach the project.

This is the image I used to plan out how I would like the final project to look like.

The Procedure

First, I began by creating functions to generate the stars. I didn’t want the stars to move, but they needed to be positioned randomly. The following code snippet demonstrates how I randomly generated the stars and created another function to store their positions.

// Function to generate stars and store their positions, size, and color
function generateStars(numStars) {
  for (let i = 0; i < numStars; i++) {
    let x = random(0, width);  // Random x position
    let y = random(0, height);  // Random y position
    let size = random(1, 3); // Random size
    
    // Colors for stars (magenta, blue, yellow, and white)
    let colr = [color('magenta'), color('blue'), color('yellow'), color(255)];
    
    // Store each star's position, size, and color
    starPositions.push({
      x: x,
      y: y,
      size: size,
      colr: random(colr)
    });
  }
}

// Function to draw stars from stored positions
function drawStars() {
  for (let i = 0; i < starPositions.length; i++) {
    let star = starPositions[i];
    
    stroke(star.colr);  // Set color for each star
    strokeWeight(star.size); // Set size for each star
    point(star.x, star.y);   // Draw the star
  }
}

In this project, I used various functions, including one to detect comet collisions with planets and another for collisions with the sun. The comets were created using a class and stored in a dynamic array, making memory management simpler compared to other programming languages. The project involved a lot of mathematical concepts, especially for the comet class, and I drew inspiration from p5.js projects and AI-assisted planning. I experimented through trial and error to execute certain parts.

Code I’m most proud of:

The code I’m most proud of is the Planet class, which brings the entire concept to life using trigonometry. By applying cosine and sine functions to measure angles, I was able to make the planets behave as intended. This idea came from Google searches. Here’s a snippet of my Planet class:

class Planet {
  constructor(size, colr, strokecolor) {
    this.size = size;
    this.colr = color(colr);  // Fill color
    this.strokecolor = strokecolor;  // Outline color
    this.x = 0;  // X position (calculated later)
    this.y = 0;  // Y position (calculated later)
    
  }

  // Update the planet's position based on the angle and radius
  update(angle, radius) {
    this.x = width / 2 + cos(angle) * radius;  // X position
    this.y = height / 2 + sin(angle) * radius; // Y position
  }

  // Show the planet
  show() {
    stroke(this.strokecolor);  // Outline color
    strokeWeight(2)
    fill(this.colr);  // Fill color
    ellipse(this.x, this.y, this.size);  // Draw the planet
  }
}

In my draw function, I used the following code, utilizing the principles of Object Oriented Programming to bring this idea to fruition.

// Update and draw the planets
 planet1.update(angle, radius);
 planet1.show();
 
 planet2.update(angle + PI, radius);  // The PI angle ensures planets are always opposite each other
 planet2.show();
 
 // Increment the angle for continuous rotation
 angle += 0.01;

 

The Final Project:

 

Reflection:

For this project, I was a bit ambitious when I first started. I prioritized realism over functionality to give the viewer a great experience. However, I learned that this wasn’t necessary and settled for a simpler approach using Object-Oriented Programming. After reading The Art of Interactive Design, I realized my final project lacked key elements of interactivity, like even a simple mouse click. In my defense, I removed interactivity because, in the storyline, humans don’t have the power to move objects in space. However, I would improve the project by adding music, moving stars, mouse-click-generated comets, and perhaps better visuals. I faced challenges in ensuring the planets always rotated 180 degrees apart, but after solving this, I was amazed at what code can achieve. I’m excited to see what it can do with more advanced graphics in the future. For now, this is it.

 

Reading Reflection – Week 3

Chris Crawford’s explanation of interactivity as a conversation between two actors really made me think differently about interactive systems. Before reading this, I thought any program that responded to user input was “interactive.” But Crawford’s idea that true interactivity needs both sides to listen, think, and speak challenged my assumptions.

Example of the refrigerator light made me laugh, but it also got me thinking – how much “thinking” does a system need to do to be truly interactive? I started looking at apps and websites I use daily in a new light. Many of them just react to clicks without really processing or responding thoughtfully. Are they really interactive by Crawford’s definition?

I found myself agreeing with Crawford’s point that good interactivity needs both actors to do all three steps – listen, think, speak – well. Based on those ideas I think the key characteristics of a strongly interactive system are: good listening, thoughtful processing, and clear communication. Those characteristics reminded me of frustrating customer service chatbots that clearly don’t understand what I’m saying. Even if they respond quickly, the interaction feels hollow because the “listening” and “thinking” parts are weak.

This reading has me wondering how I can make my own p5 sketches more deeply interactive. Instead of just reacting to mouse clicks, how can I build in more “thinking” to create a back-and-forth with the user? Maybe I could track user behavior over time to generate more thoughtful responses. Crawford’s ideas have inspired me to push beyond surface-level interactivity in my work.

Week 3: Fireworks?

Concept
For this project, I wanted to create something that felt alive and ever-changing. I’ve always been fascinated by fireworks and how they burst into these beautiful, fleeting patterns. So, I thought, why not bring that magic to the screen? That’s how I came up with this particle system where colorful dots zoom around and then explode into tiny fragments. It’s like having a never-ending fireworks show right on your computer!  The overall concept is to create a dynamic, self-sustaining system of particles that move, expire, and regenerate. Each particle has its own lifecycle, moving across the screen before exploding into smaller particles. This creates a constantly evolving visual experience that’s mesmerizing to watch.

Code snippet
The part of the code I’m most excited about is the explosion effect. It was tricky to get right, but when it finally worked, it felt amazing. Here’s the snippet with comments:

explode() {
  this.alive = false;
  for (let i = 0; i < 20; i++) {
    // Create 20 small particles for explosion effect
    this.explosionParticles.push({
      x: this.x,
      y: this.y,
      // Random x, y velocity and random size 
      vx: random(-2, 2),
      vy: random(-2, 2),
      size: random(1, 5),
    });
  }
}

This bit of code is where the magic happens. When a particle’s time is up, it bursts into 20 smaller particles, each with its own direction and size. It’s simple, but it creates this really cool effect of explosion.

Challenges
Getting the explosion effect to look good was probably the biggest challenge. At first, the explosions looked too uniform and boring. I had to play around with the random velocities and sizes to make them more interesting. Another tricky part was managing the lifecycle of particles and their explosions. I had to be careful about when to remove particles from the system to avoid memory leaks.

Sketch

Reflection and ideas for future improvements
Reflecting on this project, I have to admit it was really challenging from the get-go. Coming up with a creative idea was a struggle, as it often is for me. I spent a lot of time just staring at a blank screen, trying to think of something interesting and visually pleasant. Even after I finally settled on the exploding particles concept, making it look good was another hurdle. At first, it just looked like a bunch of circles moving randomly around the screen – nothing special. I had to really push myself to refine the visuals and add the explosion effect to make it more engaging.

Looking ahead, I’d like to explore and create more different explosion patterns. Maybe some particles could spiral out, or form shapes like hearts or stars when they explode.

Week 3 – Fireflies with OOP

Idea

For this assignment, I was inspired by how fireflies blink synchronously in the night. At first look, it might seem like they are just flashing their light randomly, but they are actually communicating with each other through the blinking.

I thought this was very ingenious of them, so I want to replicate this into coding. My idea is having a main firefly interacting with other fireflies. Whenever the main firefly (cursor) is near any other fireflies, they will start talking (blinking!) with each other.

Implementation

To execute my idea, I use two class – one for the main firefly and one for the rest of the swarm. I use the class Swarm as a subclass of Firefly to reduce repetitive coding, using some shared variables (eg. glowing, size, x, y) and overwrite the move function for the difference in the movement between the main firefly and the swarm.

First, let’s talk about the main firefly. I took reference from delayed mouse following code by kjhollen (https://editor.p5js.org/kjhollen/sketches/rJItdyEt-). For the continuous glowing light, I increase and reduce the size of the shadow to create effects of glowing as in the code below

glowing(){ //blinking of firefly light
    //if the glow size is bigger than 40, set glow to false and decrease size
    if (this.size>40){
      this.glow = false;
    }
    
    //if size is negative, set glow to true and increase the size
    
    if (this.size < 0){
      this.glow = true;
    }
    
    if (this.glow == true){
      this.size += 1;
    }else if (this.glow == false){
      this.size -= 1; 
    } 

  }

For the Swarm, most remain similar. The main difference is the swarm only glow when the cursor is near, to which I implement this code to check the condition

blinking(){
  // blink if main firefly is within 100 distance
  let distance = ((this.x - mouseX)**2 + (this.y - mouseY)**2)**(1/2);
  
  if(distance < 100){
    this.on = true;
  }else{
    this.on = false;
  }
}

I use an array to keep track of all (40) fireflies on the screen:

let fireflies = []; //list of all fireflies
 
function setup() {
  createCanvas(400, 400);
  colorMode(HSB,360,100,100,100);
  
  let x = 50;
  let y = 50;
  
  //create 40 fireflies with random positions
  for(i= 0; i<40; i++){
    fireflies.push(new Swarm(x,y));
    x = random(300);
    y = random(300);
  }
  
}

 

Final Piece

Reflection

For this assignment, I am happy with how my vision turned out like what I imagined. The fireflies glow together creates an eye-pleasing composition and interesting piece in my opinion. However, I would like to improve on the glowing pattern – the blink still happens randomly without a clear pattern. In addition, I would also like to try different representation of fireflies to further replicate the experience.