Week 3 – The Art of Interactive Design Ch.1

My definition of interactive was always just… I do something, and the thing does something back. A game, a movie, whatever. As long as we were both making actions, I figured that was it.

But in the chapter putting the interaction or being interactive into the frame of a conversation (listen, think, speak) made me stop and question that. It makes me wonder if the actions have to actually depend on each other. Like, the system’s reaction should be different based on what I did, not just a pre-programmed response to any action.

This makes me look at a lot of stuff we’ve made in p5.js completely differently. Most of those examples aren’t really interactive by this standard. I mean, you click the mouse and a shape appears, but it’s the same shape every single time. The code isn’t really thinking about my input, it’s just reacting. It’s a glorified light switch. True interaction needs that middle ‘think’ step, where the response is actually considered, not just triggered. That’s a way more interesting goal to aim for.

Week 3 – OOP Assignment

Hi everyone,

For this week’s work on OOP, I wanted to build on what we did last time implementing a bouncing ball with OOP. I wanted to make it kinds more interactive this time. I wanted to take a familiar p5.js example and make it more dynamic by implementing proper OOP principles, allowing the balls to not only bounce off the walls but also collide realistically with each other.

I created a `Ball` class that bundles together all the data (properties like `x`, `y`, `xspeed`, `radius`) and the functions (methods like `move()`, `display()`, `bounceWalls()`) that define what a ball is and what it can do. This makes the main `sketch.js` file much cleaner and more manageable. Instead of tracking dozens of separate variables for each ball, I can simply create an array of `Ball` objects and let each object manage its own state. And this what gave me the freedom of creating a lot of new balls whenever the mouse is clicked.

One of the most interesting parts of this project was implementing the collision detection between the balls. A simple approach where every ball checks against every other ball can lead to a glitch where they get stuck. When Ball A collides with Ball B, they reverse direction. But in the same frame, when Ball B checks against Ball A, it reverses direction *again*, undoing the bounce.

The highlight of my code is the solution to this problem in the main `draw()` loop. By using a nested loop where the inner loop starts at `j = i + 1`, I can ensure that every pair of balls is checked for collision exactly once per frame. This prevents the double-bounce glitch and is much more efficient.

Here is the snippet for the collision logic:

for (let i = 0; i < balls.length; i++) {
for (let j = i + 1; j < balls.length; j++) {
let ball1 = balls[i];
let ball2 = balls[j];
// Check the distance between the two balls
let distance = dist(ball1.x, ball1.y, ball2.x, ball2.y);
// If they overlap, trigger the collision resolution function
if (distance < ball1.radius + ball2.radius) {
resolveCollision(ball1, ball2);
}
}
}

Week 2 – video reflection

Watching this video, what struck me most was how something so structured could still feel alive. It’s strange to see code—something I usually think of as rigid—turn into movement and shape that almost feels organic. It made me wonder if maybe rules and freedom aren’t opposites after all. Maybe rules are what allow freedom to show up in the first place.

I kept thinking about how in life we spend so much time wanting total freedom, no limits, no boundaries. But when I watched these shifting patterns, I realized the boundaries are what made them beautiful. If there were no rules, it would just be noise. The art only worked because there was a balance—enough structure to hold it together, and enough randomness to make it feel alive.

That thought sat with me: maybe life is like that too. Too much control makes things rigid, too much chaos makes them meaningless. The sweet spot is somewhere in between, and it’s not something we can design perfectly—it has to come naturally.

Week 2 – art work

Turning Math into Motion: Playing with Sine and Cosine in p5.js

I’ve always liked the concept of sine and cosine waves. They’re simple functions on paper, just waves that go up and down forever. But I was wondering what would it make if it’s involved in creating virtual art. So I decided to use them to make something that looks alive on the screen.

The Concept

The artwork is based on the idea of ripples. Every click on the canvas sends out a circle that grows, but instead of being a perfect circle, it wobbles slightly — almost like the ripple is remembering where it’s been. Over time, these ripples overlap and fade, and the whole thing feels less like a diagram and more like a memory unfolding.

I think that’s what I love about it: it’s math doing what math does, but the output feels alive.

Highlights in the Code

I don’t want to break it down line by line, but a few details stood out to me while I was building this:

1. The Wavy Distortion
let offset = 15 * sin(this.t / 10);
ellipse(this.x, this.y, radius + offset);

Here, the sin() function is doing all the work. Instead of the circle growing in a boring, linear way, sin(this.t / 10) gives me a smooth back-and-forth motion between -1 and 1. Multiplying by 15 stretches that into a range of -15 to +15.

So when I add offset to the radius, the circle doesn’t stay steady. It breathes, gently expanding and shrinking as it grows. That tiny detail is what makes the ripple feel alive rather than mechanical.

2. The Colors That Shift on Their Own
stroke(
map(sin(this.t / 70), -1, 1, 100, 255),
map(cos(this.t / 25), -1, 1, 100, 255),
map(sin(this.t / 30), -1, 1, 150, 255),
180
);

At first, I hard-coded colors, but it looked flat. Then I realized I could let sine and cosine drive the colors, too.

Here’s how it works:

sin() and cos() output values between -1 and 1.

map() stretches those into ranges that make sense for color (e.g., 100–255).

Because the math is always oscillating, the stroke color is always changing — slowly shifting through different shades.

It’s not random; it’s predictably unpredictable. That’s why the transitions feel smooth instead of jarring.

3. Here is where I used loops:
function draw() {
background(10, 10, 20, 30);
for (let r of ripples) {
r.update();
r.show();
}
}

Each click I add one ripple to an array of ripples where I do the get bigger – wave distortion effect. And here I loop over them to update and show the effect.

Every ripple has its own this.t, which increases every frame. That’s what drives everything: the size, the offset wobble, the color shifts. Without t, nothing would move. With it, the math unfolds frame by frame, and the artwork comes alive.

Assignment 1: Self-Portrait

This self-portrait is my attempt to visualize what people might picture when they hear my name, focusing on two key identifiers: coding and my hair bun. I chose to create a simple, stylized sketch to capture these core components in a straightforward way. The character is drawn in a minimalist profile, with the hair bun as the main feature. To represent my passion for programming, the entire scene is set against a dark, digital background filled with binary code.

Here is the link for my sketch