Assignment 4 – Generative text output

Concept

For this project, I wanted to challenge myself and experiment with generative text output. I thought it would be interesting to create a program that builds short messages by mixing different pieces of text together. I wrote sentence templates with placeholders and then filled those placeholders with random words from lists of activities, places, events, and more. This approach makes every message different, even though they all follow a similar style. Each click shows a new message, so the text keeps changing and never feels the same. After eight messages, the conversation refreshes and starts again, so it feels like a brand-new chat every time. I also made the layout look like a chat screen, with colored message bubbles and a date at the top, so it feels like you are reading a conversation.

Highlight of the code I am proud of

The part I am most proud of is making the messages switch sides and look like a real chat conversation. As a beginner, figuring out how to alternate the chat bubbles between the left and right side was tricky, but using nextMessageIndex %2 to alternate sides worked perfectly.

// Interaction: add new message when mouse is pressed

function mousePressed() {
  if (nextMessageIndex === 0) {
    messages = [];  // clear canvas after 8 messages
  }
  let side;
  if (nextMessageIndex%2==0){ // Alternate sides
    side = 'left';
  } 
  else{
    side= 'right';
  }
  messages.push({
    text: generateMessage(),
    side: side
  });

  nextMessageIndex+=1;
  if (nextMessageIndex >= 8) { // Reset counter after 8 messages
    nextMessageIndex = 0; 
  }
}

Another thing I am proud of is the way I handled text wrapping. At first, I didn’t know how to make long messages fit inside the bubbles, but I learned how to split the text into words and build lines that stay within the bubble’s width. It made the conversation look clean and easy to read.

// Text wrapping into lines

let words = m.text.split(" ");  // Split message into words
let lines = [];
let tempLine = "";
for (let w of words) {
  
   // Check if adding word exceeds bubble width
  if (textWidth(tempLine + w + " ") < bubbleMaxWidth - 20) { 
    tempLine += w + " ";  // Add word to current line
  } else {
    lines.push(tempLine); // Save current line
    tempLine = w + " ";  // Start new line with current word
  }
}
lines.push(tempLine); // Add last line

Sketch

Click the mouse to add a new message

Reflection

While making this project, I wanted to experiment with generative text output and see how random combinations of words could create a conversation. I am proud of how the messages alternate between left and right, making it feel like a real chat, and how the text wrapping keeps the messages neat inside the bubbles. For the improvements, I would like to add more templates and word lists to make the conversations even more interesting, maybe even including images in the chat bubbles. Also, one of the improvements would be adding a typing animation to make it feel more like a real conversation, and make it mobile-friendly so it works on smaller screens.

Week 4 – Reading Reflection

In The Design of Everyday Things, Norman highlights the importance of feedback and conceptual models in making technology understandable. What struck me is his insistence that people should not have to “fight” with design in order to use it. If a product requires trial and error to figure out its basic functions, then the design has already failed. This perspective made me think about how often digital interfaces ignore human expectations and force us to adapt to them, instead of the other way around.

Something that really draws me crazy is poorly designed spaces, and while reading, I thought of examples from our campus. The automatic doors at building entrances are heavy and only open one way, which makes it difficult to get in, especially when carrying books or bags. In large study rooms, the motion-sensitive lights often turn off unexpectedly because the sensors are placed in strange spots, leaving people sitting in the dark until the lights turn back on. These everyday problems perfectly show what the author means: poor design is everywhere, and it affects our daily life in ways we often do not even notice. It makes simple tasks harder and reminds us how much thoughtful design matters.

For me, applying Norman’s principles to interactive media means designing in a way that anticipates misunderstandings before they happen. People should not feel embarrassed or incompetent because of poor interface decisions. I want to create digital experiences where the actions are transparent, the feedback is immediate, and the user feels in control. When design gets this right, it not only avoids frustration but also builds trust between people and technology.

Week 3 – Reading Reflection

Reading Chris Crawford’s chapter “What Exactly Is Interactivity?” made me rethink what I usually call “interactive.” Especially, now as I am taking 3 IM classes, and we often see the artworks and come to the term interactive, I have started to understand how truly important it is. After the reading, I realized that I often label something as interactive just because I can click or move something and it changes, but Crawford’s explanation made me see that real interactivity is much deeper than that. I really liked his comparison to conversation, it made sense that true interactivity should feel like a back-and-forth exchange where both sides “listen, think, and speak.” This idea made me reflect on my own p5 sketches and notice that, while they respond to user input, they do not necessarily feel like a conversation. They just react without much “thinking” or meaningful change based on the user’s action.

Speaking of 5p, the reading challenged me to think about how I can make my work more engaging and meaningful. I felt motivated to experiment more with giving my sketches some kind of “memory” or adaptive behavior so that the experience feels less mechanical and more like a dialogue. For me, a strongly interactive system is one where the user’s input actually matters and shapes the outcome in noticeable, sometimes unexpected ways. It should feel like the system is “paying attention” and changing its behavior based on what I do, rather than just executing a simple trigger. I think strong interaction also invites me to explore, experiment, and maybe even get surprised by the result.

After the reading, I had some ideas of how I can improve my interactivity of  p5 sketches. I could add elements that respond over time or evolve depending on how much and how often I interact. For example, instead of bubbles just appearing when I click (assignment 3 – OPP), I could make them “learn” from my clicks, maybe clustering in areas where I click often or changing colors based on patterns of interaction. I could also make my sketches remember past actions so that the experience feels continuous rather than resetting each time. I think, after this steps, it would move my work closer to what Crawford calls a real conversation between user and system.

Assignment 3 – Object-Oriented Programming

Concept

When I started thinking about how I wanted to use Object-Oriented Programming (OOP) in my project, I imagined an underwater world. I wanted to make something calm and relaxing, so I created a digital aquarium. In this scene, bubbles float gently to the surface, colorful fish swim across the canvas, and seaweed sways back and forth at the bottom of the ocean.

Each time the sketch runs, the scene looks slightly different. The bubbles start at random positions and have different sizes and speeds. The fish are given random colors and swim in different directions, and even the seaweed moves with slightly different timing. This randomness makes the project feel alive,  it never looks exactly the same twice.

I also wanted the viewer to feel like they could interact with the piece. When you click anywhere on the canvas, new bubbles appear, as if you are adding more air into the water. I think this small interaction gives the viewer the feeling that they are part of the underwater world, and they can keep changing it over time

Code I am proud of

Since this was one of my first tries using OOP, I am proud of how I used classes and arrays to keep my code neat and reusable. Instead of writing separate code for every single bubble, fish, or piece of seaweed, I made classes for each one with their own properties and methods. Then I stored all the objects in arrays and used a simple loop to update and display them. It made my code much easier to read and change, if I want to add more bubbles or fish, I just push a new object into the array and everything works automatically.

function displayBubbles() {
  for (let b of bubbleArray) {
    b.update();
    b.show();
  }
}

Also, there was some difficulties, for example, all the bubbles were moving in perfectly straight lines, which looked too mechanical. To make them look more natural, I added a sin() wave offset and a slight random angular speed so they gently drift side to side as they rise

update() {
    // Move upward and slight sideways wiggle
    this.y -= this.speed;
    this.x += sin(this.angle) * 0.5;
    this.angle += this.angleSpeed;

    // reset bubble when it leaves canvas
    if (this.y < -this.size) {
      this.y = height + this.size;
      this.x = random(width);
    }
  }

Sketch:

Click the mouse to add more bubbles

Reflection

I am proud of how this project demonstrates the use of Object-Oriented Programming (OOP), arrays, and dynamic interactivity to create a visually engaging underwater scene. I was able to organize the code cleanly, avoid repetition, and make it scalable, while arrays allowed for easy iteration and animation

Yet, I think for the future development, I could increase interactivity by having fish respond to the mouse or implement bubble popping effects, introduce more dynamic visuals such as a gradient background, diverse sea creatures, and multi-layered seaweed for depth, and incorporate physics-based movement or sound interaction to create a more immersive experience. Overall,  for me this project combines programming, aesthetics, and interactivity that explores potential of generative digital art.

Week 2 – Reading Reflection

Creative Reading:

Watching Casey Reas’ lecture changed how I think about randomness in my work. I have always enjoyed unpredictability in art, but I tended to treat it as something that just happens rather than something I could plan. Reas’ talk showed me that even small doses of chance can generate patterns that feel intentional, making uncertainty a tool rather than a problem. For example, I want to experiment with algorithms where randomness sparks new ideas without fully determining the final outcome. The idea that the computer can function both as a precise tool and a way to explore controlled unpredictability is particularly meaningful when creating interactive pieces, where audience interactions can lead to unexpected results.

One part of the presentation that stood out to me was Gerhard Richter’s quote, which both Reas and I found inspiring:

“Above all, it’s never blind chance: it’s a chance that is always planned, but also always surprising. And I need it in order to carry on, in order to eradicate my mistakes, to destroy what I’ve worked out wrong, to introduce something different and disruptive. I’m often astonished to find how much better chance is than I am.”

After hearing this quote, it made me realize that chance can improve work in ways I cannot fully plan. For me, the right balance between control and randomness depends on the goals of each project. I have found it works best when I maintain enough structure to communicate meaning while leaving space for unexpected outcomes. By setting boundaries for unpredictability, I can create work that is both deliberate and dynamic, allowing the process and the audience to reveal new directions I might not have anticipated. This perspective encourages me to trust my process more and experiment with confidence, letting systems explore themselves.

Assignment 2 – Loops

Concept:

When I first thought about how I wanted to use a loop in my assignment, I decided to create a flower with five layers of petals that move and rotate. In my code, each loop repeats the same ellipse many times while slowly rotating, forming a full circle of petals. By using five separate loops, the code creates five layers that rotate at different speeds, making the flower look alive and constantly changing. The loops make the process simple and efficient because they draw many shapes with very little code. Additionally, when the viewer clicks the mouse, the flower’s colors change, which makes the artwork more playful and interactive.

The use of loops also made it easy for me to experiment with different numbers of petals, sizes, and speeds until I found a design that felt balanced and beautiful. It helped me understand how powerful loops are in creating complex patterns and animations with very few lines of code. It also showed me how combining repetition with motion can turn simple shapes into something that feels dynamic and alive.

Highlight of the code I am proud of:

One of the most challenging and important parts of my code was creating the background. I had to figure out how to map each y-coordinate to a color gradient and make it look smooth while still matching the rotating flower layers on top. I used a for loop to go through every horizontal line of the canvas and calculate a color between color1 and color2 using lerpColor. The loop was essential as it let me blend the colors smoothly across the whole canvas. I am proud of this part because it added depth and contrast to the flower, making the petals stand out more and giving the artwork a more polished and dynamic look.

function draw() {
  // Gradient background
  for (let y = 0; y < 400; y++) {
    let color1 = color(90, 60, 140);  
    let color2 = color(150, 100, 200); 
    stroke(lerpColor(color1, color2, map(y, 0, 400, 0, 1)));
    line(0, y, 400, y);
  }

Sketch:

Click the mouse to change the colors

Reflection:

In this project, I learned how to use loops to create repeating patterns and motion in my artwork. For future improvements, I would like to experiment with adding more layers, changing rotation patterns, or incorporating transparency effects to make the visuals more dynamic. Another possible improvement is making the animation respond to additional interactions, such as mouse movement or key presses to create a more engaging experience for the viewer.

Self-portrait – Aizhan

Concept:

When I began thinking about how I wanted to represent myself in a self-portrait, the moon immediately came to mind. My name, Aizhan, means “moonsoul” in Kazakh, and I feel that the moon will be the great representation of who I am. I wanted my portrait to convey not just my physical appearance, but also my personality and identity. Before bringing the portrait to life in p5, I started with sketches on paper. These first drawings helped me organize my ideas and experiment with shapes, composition, and visual elements, allowing me to see how I could best represent myself.

One of the interactive features of the final portrait is that when viewers click on it, my eyes move from side to side. This small animation gives the portrait a sense of life and presence, making it feel as though it is observing and engaging with the viewer. Another feature is a falling star across the background. The star represents an aspect of my inner self, like a spark of energy, curiosity, or imagination that is always part of who I am.

Highlight of the code I am proud of:

The part of my project that I am most proud of is the code that makes the eyes move when the viewer clicks on the portrait and it was probably the most time consuming part. I chose this feature because it adds a sense of life and interaction to my self-portrait, making it feel like the portrait is really engaging with the viewer. The tutorials and references helped me to figure out how to add interactive elements to my portrait. They guided me through understanding on how to track time with millis() and the lerp() allowed me to make the eyes and star transitions smoother with coordinates.

function mousePressed() { 
  //eye movement and star movement when mouse clicked
  toLeft = !toLeft;      
  anim = true; s = 0; t0 = millis();

 

//pupils
fill(0);
ellipse(pupilX(L0), CY, 5, 5);   
ellipse(pupilX(R0), CY, 5, 5);  


//pupils animation
if (anim) {
  s = (millis() - t0) / 250;
  if (s >= 1) { s = 1; anim = false; }
}

function pupilX(base){
  if (anim) return lerp(toLeft ? base : base + DX, toLeft ? base + DX : base, s);
  return toLeft ? base + DX : base;
}

Sketch:

Reflection:

This was my first time creating this kind of work in p5 and adding animation, and it was really exciting to see how the commands work together to make the portrait come alive. It helped me understand the concept better and gave me new ideas for future projects. In the future, I want to make my work even more interactive and add more details. For example, instead of having just one star falling, I could have several stars falling from the top of the screen. I could also make the moon shine or glow to make the scene feel more magical.

I also would like to add some body parts. For instance, I could add hands, change the outfit, or use different shapes to represent parts of the body. I also want to experiment more with colors to make the portrait more vibrant and expressive.