Week 2 – Animation, Conditionals, Loops Artwork

For this weeks production assignment of creating an artwork using animation, conditionals, loops, I wanted to create a gamified artwork based on  a slice of life of my cat Piku.


Piku the Cat
This is Piku! A cat that loves showers more than anything(strangely)!

So I quickly sketched up my plan for today’s artwork which roughly looked like this-


Vision Image
I wan
ted to implement animation, conditionals, and loops to bring everything to life. I imagined:

-Window blinds that could open and close smoothly, setting the scene.

-A background with clouds and a sun, all randomly generated to make things feel dynamic. Also, day to night transition.

-Foam filling up the bathtub, to give it some depth.

-Dirt appearing on the cat, to make it interactive

-A sponge that could move around as a cursor and detect collision when it touched the dirt, making it disappear.

-Bubbles floating around animation to show that the dirt splashes are being cleaned

At first, it all sounded doable in my head. But once I started coding, I quickly realized just how many moving parts there were. Making sure the sponge actually removed the dirt was tricky. Getting the animations to feel smooth took a lot of tweaking. And sometimes, the whole thing would just break for no reason, forcing me to backtrack and figure out what went wrong.

The Part that took the longest: Collision detection!

The dirt and sponge interaction was by far the toughest challenge. At first, I thought it’d be simple—just check if the sponge touches the dirt and remove it. Spoilers- it wasnt. What Went Wrong?

-Frames: The dirt sometimes disappeared too fast or not at all because collisions were checked every frame, making it inconsistent.

-Layering: Dirt kept reappearing because new frames kept redrawing it, even after “removal.”

-Messed-up logic: I tried so many broken approaches—checking collisions wrong, deleting dirt before drawing it, and even accidentally scrubbing the whole screen at once.

The Fix

I stored dirt in an array and only removed pieces when they were properly scrubbed:

let dirtParticles = Array.from({ length: 20 }, () => ({
  x: random(width), y: random(height), scrubbed: false
}));

function draw() {
  background(220);
  let sponge = { x: mouseX, y: mouseY };

  fill(255, 204, 0);
  ellipse(sponge.x, sponge.y, 50, 30); 

  dirtParticles = dirtParticles.filter(dirt => {
    let scrubbing = dist(sponge.x, sponge.y, dirt.x, dirt.y) < 30;
    if (!scrubbing) {
      fill(139, 69, 19);
      ellipse(dirt.x, dirt.y, 15, 15);
    }
    return !scrubbing;
  });
}

And after hours and hours of googling every function ever, here’s the final result:

What I’d Do Differently

This project was a huge learning experience. If I had to do it again, I’d plan my code structure better from the start. I ran into so many issues with layers, frame updates, and collision logic, which could have been avoided if I had mapped out how each element would interact beforehand.Also, I’d put more focus on the aesthetic aspects of the project. This project forced me to dive deep into some tricky p5.js functions and concepts, including:

  • filter()
  • push() / pop()
  • frameRate() and frame-based logic
  • Arrays and Objects
  • Background Gradient
  • Animation Timing

This project had its frustrating moments, especially when things wouldn’t behave the way I expected. But in the end, seeing everything finally come together was incredibly rewarding.

Week 1: Self Portrait

Project Concept

For my first assignment, I envisioned creating a  portrait using only one shape thats minimalist yet offers visual depth. I decided that pixel art was the perfect medium for this idea since Its built out of squares yet shading features help provide the sense of depth. Its structured grid format and the ability to control each individual “pixel” felt ideal for achieving the clean aesthetic I had in mind.

Challenges Faced

While my initial plan was to use nested loops to generate the grid and automate the process, as a complete coding beginner, I encountered errors that made it difficult to implement this approach. To overcome this, I decided to hardcode each pixel manually. This allowed me to fully control the placement and colors but turned the process into a labor-intensive task. Every pixel had to be individually positioned and assigned a color, which made the project take much longer than anticipated. It obviously isn’t ideal but I gained a hands-on understanding of positioning features , drawing features.

Key Takeaways

Despite the challenges, this project turned out to be a significant learning experience. Some of the key insights I gained include:

  1. The necessity of loops and conditions: Hardcoding each pixel gave me total control, but it also highlighted how essential loops are for reducing repetitive tasks and improving efficiency in coding. When I wanted to change my background in the end, it wasn’t possible because that’d need me to hardcode everything all over again.
  2. Improved understanding of p5.js positioning: By working manually on every pixel, I developed a solid understanding of how p5.js handles positioning and coordinates, which will undoubtedly help me in future projects.
  3. Patience and problem-solving: This project tested my patience but also pushed me to find doable solutions when my initial approach didn’t work as planned.