Midterm Draft 1

Concept:

For my midterm project, I decided to create a football obstacle game where the player dribbles through moving defenders to score against a moving goalkeeper. The game gets progressively harder after each goal: defenders increase in number and speed, and the goalkeeper moves faster. The player clicks to shoot when near the goal.

The aim is to design a game that is fun and interactive, combining timing, precision, and quick thinking. I will also include engaging visuals and sounds to give feedback for player actions, like kicking the ball, scoring, or colliding with defenders. This makes the game feel immersive and responsive.

Design:

The game starts with an on-screen instruction explaining the controls: the arrow keys to move, and the mouse click to shoot. Only when the player presses a key or clicks the button does the game begin. The player, defenders, goalkeeper, and the ball in the game will be represented using circles for simplicity and visual consistency. The player will be a larger colored circle that moves freely across the field in response to user input, with the ball represented as a smaller circle attached to the player while dribbling. Defenders will be smaller circles in distinct colors, moving along random paths to create challenges, while the goalkeeper will be a medium-sized circle that moves horizontally along the goal line to block shots. When the player shoots, the ball will separate from the player and travel independently toward the goal.

Classes to be used:

  • Player Class: Controls movement and shooting. Properties include position, size, and speed. Methods: Methods or functions include display(), move(), and shoot()

  • Defender Class: Moves across the field, increasing in number and speed as the game progresses. Properties include position, size, speed, and direction. Methods or functions include display() and move()

  • Goalkeeper Class: Moves left and right along the goal line. Properties include position, width, height, and speed. Methods or functions include display() and move()

  • Ball Class: Moves toward the goal when shot. Properties include position, size, speed, and moving. Methods or functions include display(), move()

Gameplay Flow:

  1. Start Screen: Displays instructions like “Use arrow keys to dribble, click to shoot, avoid defenders.”

  2. Gameplay:

    • Player moves freely around the field with the ball

    • Defenders move continuously in patterns.

    • Player avoids collisions with defenders.

    • When near the goal, clicking the mouse shoots the ball.

  3. Scoring & Difficulty:

    • Passing the goalkeeper scores +1.

    • After each goal, more defenders appear, defender speed increases, and goalkeeper speed increases slightly.

    • Player position resets for the next attempt.

  4. Restart / New Session:

    • Players can restart without refreshing the page.

    • Score and high score are displayed.

Frightening/Challenging Aspect:

The most challenging aspect of this project will likely be keeping the ball consistently attached to the player while allowing free movement around the field. Although the player and ball are conceptually separate objects, the ball must move in perfect sync with the player in all directions – up, down, left, right, and diagonally, which can be difficult to achieve smoothly. This challenge becomes even greater when combining it with collision detection against multiple defenders and a moving goalkeeper. The ball must remain attached until the player decides to shoot, at which point it detaches and moves independently toward the goal.

But this is also the most important part of the project, and implementing it correctly will help create an engaging and fun experience.

Risk Reduction:

To reduce the risk of issues with keeping the ball attached to the player, I plan to implement a step-by-step testing approach. First, I will start by coding the player and ball as separate objects and linking the ball’s position directly to the player’s coordinates with an offset, ensuring that it moves smoothly in all directions. I will test this initially without any defenders or a goalkeeper to confirm that the ball follows perfectly. Next, I will gradually add collision detection with a single defender, then multiple defenders, and finally the goalkeeper, checking at each stage that the ball remains properly aligned. Additionally, I will use simple shapes, such as circles, for all objects to simplify calculations.

Reading Reflection – Week 5

I hadn’t learned much about computer vision before reading this article, except it was about enabling computers to “see” and understand visual data. What struck me most was the irony in how computer vision compares to human vision. Computers can be unbelievably precise, catching patterns, colors, or tiny movements that a human eye might overlook. But they can also completely miss things we find easy, like recognizing a familiar face in poor lighting or spotting an object that’s just been turned around. To me, that contrast really shows how naturally flexible our own vision is, while computer vision feels much more rigid and depends on whether the physical conditions it was trained for are perfectly reproduced. I came to see how important it is to design the physical environment when working with computer vision so that the system can function more effectively – for instance, arranging lighting, colors, and contrasts to make key features easily detectable.

As I thought more about computer vision, I realized that helping a computer “see” is not just about coding; it’s also about choosing the right technique for the specific task. Methods like color tracking or motion detection can work really well, but they each have their weak spots. For instance, a color tracker could get confused if the background shares the same shade, and a motion detector could be thrown off by something moving in the background that has nothing to do with the task. It made me see how much depends on matching the method to the situation; otherwise, the results fall apart.

When it comes to interactive art, computer vision’s ability to track and even surveil people feels both fascinating and a bit worrying. Tracking can make an artwork feel alive—it follows your gestures and responds in ways that draw you in. But surveillance goes further than that. It suggests being constantly observed, maybe even recorded, without realizing it. This is where the concern for privacy creeps in. One artwork that shows this really well is Rafael Lozano-Hemmer’s Surface Tension. In this piece, a large projected human eye follows you around the room. At first, it feels playful and interactive, like the artwork is aware of you, but the longer you stay, the more uncomfortable it becomes. I guess this tension is what makes interactive art with computer vision so compelling, because it not only provides us with an engaging experience but also pushes us to reflect on the aspect of being monitored.

Assignment 4 – Data Visualization

Concept:

For this assignment, I wanted to create a data visualization that conveys information through motion and color. Initially, I tried using real-world GDP data I downloaded from Kaggle, but I ran into errors because some columns were missing values, and I wasn’t sure how to handle those gaps. So, I decided to create my own fictional CSV file with made-up GDP numbers for a larger set of countries. Each country is represented as a bouncing circle whose size reflects its GDP and whose color adds a visual layer of distinction. The animation gives the data energy and makes patterns easier to notice. I also utilized arrays and a custom class to organize the circles, dynamically managing their movement, size, and color.

Code Highlight:

One part of my code I’m proud of is how the circles move and react to the edges of the canvas. Each circle has its own speed and direction, creating a sense of individuality while still forming a cohesive scene. I also added a feature that displays the country’s name when you hover over a circle, allowing you to read the data without cluttering the visualization.

if (dist(mouseX, mouseY, this.x, this.y) < this.size / 2) {
    fill(255);
    textAlign(CENTER, CENTER);
    textSize(18);
    text(this.name, this.x, this.y - this.size / 2 - 10);
}

Embedded Sketch:

Reflections & Future Improvements:

This project taught me how to combine datasets with visual techniques to make information more intuitive. I realized that adding motion and color can turn raw numbers into an engaging experience. Hover interactions enhanced the usability, making the visualization informative without overwhelming the viewer.

For future improvements, I would like to make the visualization more interactive, perhaps allowing users to filter by region or toggle between GDP and population. I also want to experiment with color gradients or circle trails that respond to velocity, so the data becomes even more expressive. Overall, this project helped me understand how programming, animation, and data can intersect to communicate ideas creatively.

 

Reading Reflection – Week 4

Reading Norman’s chapter on how to design everyday things brought back memories of my experience with poorly designed washing machines. The majority of newer machines have vague buttons, knobs, and symbols that make even a single load of laundry complicated. Some controls are counterintuitive, with icons that are unidentifiable as any standardized symbol. Others have poorly laid-out buttons or poorly readable colors, which make discoverability nearly impossible.

These design errors are just the kind of problems Norman discusses in terms of discoverability and understanding. A washing machine should express its use naturally so that users would know what can be done, where to do it, and what the controls accomplish without regard to instructions. Norman’s principles of affordances and conceptual models are applicable here. The signifiers should refer to the possible actions on the machine, and affordances should tell us where and how to do them naturally. Poorly designed washers fail in all of these ways, keeping their users uninformed and frequently erring that would not have been done with better design.

Norman indicates that machines should be planned for human error, and I agree that anticipating mistakes is crucial in terms of usability. A properly thought-out machine should anticipate human error and guide the user instinctively through the procedure, without requiring perfect knowledge or precision. I think there is a fine line, however, between assisting users and overcompensating for every mistake. If a design strives to support as many potential errors as it can, it will end up being overcomplicated or even enable sloppy use, rather than teach or lead users to the correct way of using it. Brilliant design, in my opinion, should discourage the most common errors without shutting doors entirely on the freedom to learn from experience and make decisions, rather than trying to predict all potential errors. This equilibrium provides usability without sacrificing structure or clarity.

Reflecting on Norman’s principles, I realize how important it is to design for clear feedback in interactive media, especially in my p5.js projects. For example, if I create a sketch where clicking on shapes triggers animations or changes their color, I can’t assume that a first-time user will immediately understand what to do. To address this, I might add visual cues like hover effects, tooltips, or a brief on-screen instruction to indicate which elements are interactive and what actions will happen. Norman’s arguments remind me that good design means guiding users through interactions intuitively, so they can enjoy the experience without confusion, frustration, or guesswork. By applying this principle, I can make my projects more accessible, engaging, and user-friendly.

Reading Reflection – Week 3

Before reading The Art of Interactive Design, I used to think that once we receive a reaction from another thing, that automatically defines the concept of interactivity. When I came across the example of the Nintendo refrigerators on page 11, I immediately felt that it was an example of interactivity. Crawford, however, raised the idea of whether interactivity is subjective or a fixed concept of its absence or presence. After giving his argument careful thought, I believe that interactivity is subjective because it depends on how engaged the user is with the system. The same design might feel highly interactive to one person and mostly reactive to another, depending on how much input and attention they give. Drawing from his analysis and interpretation of interactivity in conversation, both parties must play their part to have a meaningful exchange. This is what I believe is the characteristic of a strongly interactive system: “input, process, and output from both ends must be very strong.”

Comparing that to the interactivity of a design, one user might find a design not interactive based on a low level of engagement on their part, while another user might find it highly interactive. Crawford really got me thinking when he highlighted the subtle difference between reaction and interaction. I have now realized that my p5.js sketches are mostly reactive and not interactive, since they respond to pre-programmed rules without requiring meaningful input from the user. Moving forward, I want to experiment with ways to make my sketches more interactive, such as allowing users to influence patterns, colors, or motion in real time, so the system becomes a collaborative experience rather than just a reactive one.

Week 3 – Generative Artwork

Concept:

For this assignment, I tried to recreate the random walker algorithm. I used an array to keep track of all the walkers and a class to define how each one moves and displays. The walkers choose random directions at each step, which makes the design change constantly and never looks the same twice. I also added different colors so their paths would overlap in interesting ways and fill the screen with patterns. Using loops made it easier to update and draw all the walkers at once instead of writing separate code for each.

Code Highlight

I’m really proud of how I built the step() function for my walkers. It looks simple, but it’s the heart of the project. By randomly choosing between four directions, each walker ends up moving in unpredictable ways.

step() {
    let choice = int(random(4));
    if (choice === 0) {
      this.x += 2;
    } else if (choice === 1) {
      this.x -= 2;
    } else if (choice === 2) {
      this.y += 2;
    } else {
      this.y -= 2;
    }

Embedded Sketch

Reflections & Future improvements

This project was fun because it used simple functions to create a constantly changing visual. I like that each walker moves randomly and has its own color, creating patterns that are never the same twice. The step() function is especially satisfying, since such a small piece of code drives the entire motion. Using a class to manage each walker made the code organized and easier to expand.

To improve upon my current code, I would like to include more movement variation, such as diagonal movement.  I would also like to let the user click to add more walkers or control colors, which would make the design interactive. I could also have walkers bounce off edges or wrap around the canvas for more interesting patterns.

Assignment 2 – Loops

Concept:

For this assignment, I wanted to make a design that moves and looks alive, as compared to my static design for the first assignment. I used nested loops to draw a grid of circles, and each circle changes size and color using a wave. I had to learn how to use the wave and the map functions so I could control how the circles grow and change colors, which was a little tricky at first, but really fun to figure out. The loops made it so much easier to draw many circles without writing a lot of code.

Code Highlight:

I’m really proud of how I made the circles pulse and change color using the wave and map functions. Even though it’s just a few lines of code, it completely changes how the artwork feels. Figuring out how to use the wave and map together was really challenging at first. I had to do a lot of trial and error, watch some YouTube videos, but it was satisfying to see it finally work.

let wave = sin((frameCount * 0.07) + (x + y) * 0.05); // simple wave
let size = map(wave, -1, 1, 10, spacing); // circle size changes with wave
let colorValue = map(wave, -1, 1, 50, 255); // color changes with wave
fill(colorValue, 170, 355);

 

Embedded Sketch:

Reflections & Future improvements:

This assignment was initially challenging because I had to figure out how to make the circles pulse and change color using loops and functions. I spent some time watching tutorials and testing different ideas to get the animation to look right, especially figuring out how to use the wave and map functions together. Completing this project helped me understand how to combine new concepts with what I already know, such as loops and grids, to create something that actually moves and changes on the screen.

For the future, I’d like to make it more interactive. Right now, the circles just pulse on their own, but it would be cool if the user could click or drag the mouse to change the colors or the speed of the animation.

Reading Reflection – Week 2

For me, the most significant takeaway from Casey Reas’ talk was the idea that chaos and order can coexist. Initially, I thought to myself, “This doesn’t make sense. How can two opposite ideas be used together to bring harmony and coordination? However, as I listened further to the point where he gave examples of pieces of art where randomness or chance was included to generate order and beautiful patterns in art, I was fully convinced.

Most importantly, Casey’s talk helped me realize that randomness doesn’t necessarily mean lack of control. I agree that it is essential to incorporate constraints to have control over randomness added to a piece of art. This is where I feel the optimum balance between total randomness and complete control can be achieved.  By using constraints, we can maintain intention but still have elements of unexpected and creative variations.

This understanding will be very useful to me as a learner. Although I’m not experienced in creative coding with p5.js, I plan to explore incorporating randomness into my works. For instance, I can use the random() function and set boundaries for positions and sizes so that my output is confined within a specific area, while having some variations in its properties.

Assignment 1: Self-Portrait using p5.js

Content:

In this assignment, I wanted to create a close digital representation of my favorite childhood cartoon character, SpongeBob SquarePants, using p5.js. I broke down the somewhat complex inspiration image into a sketch of simple shapes and elements such as lines, arcs, circles, squares, and rectangles. I also utilised colors and visual proportions to increase the accuracy of my representation.

Here is my inspiration image for reference:

Code Highlight:

One part of my code I am proud of is how I created the eyes. It wasn’t too complex, but I like how it challenged me to think carefully about visual placements and proportions. I had to make sure that the radii of the inner and outer eyeballs were different and balanced, which helped me practice precision in design and calculation.

//-- Eyes --
fill('white');
noStroke()
ellipse(160, 210, 70, 70);
ellipse(230, 210, 70, 70);

fill('blue');
noStroke();
ellipse(167, 213, 30, 30);
ellipse(224, 213, 30, 30);

fill(0);
ellipse(169, 213, 15, 15);
ellipse(224, 213, 15, 15);

stroke(0)
line(136, 168, 143, 179);
line(153, 163, 153, 175);
line(169, 163, 164, 175);
line(210, 165, 218, 176);
line(228, 162, 228, 174);
line(243, 162, 238, 174);

Embedded Sketch:

Reflections & Future improvements:

This was my first time using p5.js, and since I joined the class late, I initially struggled to write clean code. However, after learning and experimenting with the different functions, I found it rather interesting how basic code could be used to create visually appealing designs. I love how the assignment encouraged me to think ahead about what my portrait should look like and make precise calculations to get the perfect body parts.

If I had more time and experience with p5.js, I would:

    • Create fingers using custom or complex shapes instead of using only a filled circle.
    • Use shadow effects to create a hollow-looking mouth and a custom shape to represent the tongue (I improvised to create a different representation of the mouth from the reference image)
    • Add sponge-like ridges along the body as seen in the reference image.
    • Incorporate animation, such as making the portrait smile and wave when the mouse hovers over the canvas, by using loops and/or conditionals.
    • Reduce repetition in my code by using conditionals and loops.