Week 8: Why Water?

The Journey Back to Basics

My investigation into water-based conductivity started with a straightforward observation of the water I used to take my daily magnesium dose. It was pleasant to go back to the basic concepts of electricity and conductivity after working with Arduino extensively on a variety of intricate projects.

Why Water?

As I drank my water supplement with magnesium, the thought came to me. It was amazing to see how something so ordinary could be transformed into an interactive component. Since water is a universal solvent and necessary for life, it looked like the ideal medium for investigating conductivity in a way that relates science to everyday life.

The Magnesium Connection

Scientific Curiosity

The water that was enhanced with magnesium was not chosen at random. Being an essential component for our bodies, magnesium tells an intriguing story of how the same elements that keep us alive may energize our circuits. The water is an efficient conductor for our switch because of the Mg2+ ions in it, which greatly boost conductivity as compared to ordinary water.

Learning Through Simplicity

Despite my previous experience with Arduino projects, this exploration offered valuable insights. It reaffirmed fundamental electrical ideas that I hadn’t considered in years.reminded me that common materials can be transformed into interactive components. It also proved that sometimes the most elegant answers are the most straightforward ones 😅

Technical Growth

  • Despite being simple in theory, this assignment forced me to:
    Go over basic conductivity principles
  • When handling liquids, take safety precautions into account.
  • Design clean, efficient circuits
  • Produce reliable readings despite fluctuating conductivity.

This assignment demonstrated that going back to basics can be both humbling and instructive, demonstrating how even experienced makers can find delight and learn from simple experiments.

Demo:

 

Reading Reflection – Week 8

These readings about Don Norman’s design insights and Margaret Hamilton’s crucial contribution to Apollo’s software development have two different but related effects on me. Resilience and creative thinking are crucial for overcoming both technological and cultural obstacles, as demonstrated by Hamilton’s voyage through the unexplored field of software engineering. Hamilton was not simply coding when she took on programming problems that would have jeopardized the mission; she was also breaking new ground under extreme pressure, proving that effective software design necessitates flexibility and foresight. Her story of having to model every system before takeoff emphasizes how crucial thorough testing is, particularly in high-stakes scenarios. This strengthens my conviction that strong design principles and a proactive approach to mistake handling are essential in any technical endeavor.

The way that Norman explores emotive design, especially his assertion that “attractive things work better,” offers an alternative viewpoint. His focus on how aesthetics affect usability shows that well-designed products enhance the user experience by adding emotional appeal in addition to functionality. The success of design frequently rests in its adaptability and alignment with user context, as demonstrated by his collection of teapots, each of which has a distinct function depending on the occasion and mood. His defense of balanced design principles—where functionality, aesthetics, and usability all coexist peacefully—particularly strikes me as thought-provoking. I find myself wondering how I can apply this balance to my own work so that beauty doesn’t come at the expense of functionality or vice versa.

The combination of Norman’s holistic design approach and Hamilton’s technological rigor serves as a reminder to me that when developing any interactive system, we should give equal weight to emotional resonance and functionality. I want to apply this combined emphasis on accuracy and user empathy to my own work, not just in this course, but in general.

Midterm Project: “Cubix”

Sketch
http://165.232.166.95:5500
Concept
I decided to implement a clicker/incremental game with a unique twist, combining elements from popular titles like To The Core, Cookie Clicker, and Adventure Capitalist. The game revolves around hunting flying shapes using a cursor with an attached box (scope/aim). Players damage enemy shapes when they’re inside this box, earning resources to upgrade skills in a talent tree. The game also features levels for long-term progression and bonuses.

Game Mechanics and Achievements
The core gameplay involves killing enemies that appear on the screen using an aiming device attached to the cursor. Each enemy defeated rewards the player with experience and money. Leveling up releases resources, while money allows for upgrades in the talent tree. One of the most challenging and rewarding aspects of development was balancing the game’s economy. After extensive experimentation and research, I developed formulas that strike a balance between challenge and progression, ensuring the game is neither too easy nor too difficult. Here is the mathematical framework for the economics of the “Cubix” game.

Core Mechanics

Player Progression
The player’s power increases through two main avenues:
1. Killing mobs to gain experience and resources
2. Upgrading skills to become more effective at killing

Experience and Leveling
XP_{gained} = Base_{XP}  *  (1 + Level_{mob} * 0.1)
Where Base_{XP} is a constant value for each mob type, and Level_{mob} is the level of the mob killed.

The experience required to level up follows an exponential curve:
XP_{required} = 100 * 1.1^{Level_{player}}

This ensures that leveling becomes progressively more challenging.

Resource Generation

Resources (e.g., gold) dropped by mobs calculated similarly:
Gold_{dropped} = Base_{gold} * (1 + Level_{mob} * 0.15)

Skill Upgrades

Each skill has multiple levels, with increasing costs and effects. The cost to upgrade a skill follows this formula:
Cost_{upgrade} = Base_{cost} * 1.5^{Level_{skill}}

The effect of the skill (e.g., damage increase) is:
Effect_{skill} = Base_{effect} * (1 + Level_{skill} * 0.2)

Mob Scaling

To keep the game challenging, mob health and damage can scale with the player’s level:
Health_{mob} = Base_{health} * 1.2^{Level_{player}}
Damage_{mob} = Base_{damage} * 1.15^{Level_{player}}

A significant technical achievement is the implementation of local progress saving using localStorage. This feature required considerable effort but greatly enhances the player experience by allowing seamless continuation of gameplay across sessions.

class Storage {
    constructor() {
        this.spawnRate = [1000, 2000];
        this.spawnChances = [0.5, 0.3, 0.1];
        this.maxEnemies = 100;

        this.balance = 0;

        this.level = 0;
        this.xp = 0;

        this.damage = 20;
        this.hp = 20;
        this.regen = 1;
        this.interval = 1000;
        this.crit = 10;
        this.critChance = 0.12;
        this.armor = 0;

        this.skills = defaultSkills;

        this.scopeSize = 100;
    }

    getSkillEffect(id) {
        let skill = this.skills.find(skill => skill.id === id);
        if (skill.level === 0) {
            return 0;
        }
        return int(skill.baseEffect * (1 + skill.level * 0.2))
    }

    reset() {
        this.spawnRate = [1000, 2000];
        this.spawnChances = [0.5, 0.3, 0.1];
        this.maxEnemies = 100;

        this.balance = 0;

        this.level = 0;
        this.xp = 0;

        this.damage = 20;
        this.hp = 20;
        this.regen = 1;
        this.interval = 1000;
        this.crit = 10;
        this.critChance = 0.12;
        this.armor = 0;

        this.skills = defaultSkills;

        this.scopeSize = 100;

        this.save();
    }

    load() {
        let save = localStorage.getItem("save");
        if (!save) {
            this.save();
        } else {
            let data = JSON.parse(save);
            this.spawnRate = data.spawnRate;
            this.spawnChances = data.spawnChances;
            this.maxEnemies = data.maxEnemies;
            this.balance = data.balance;
            this.damage = data.damage;
            this.hp = data.hp;
            this.level = data.level;
            this.xp = data.xp;
            this.regen = data.regen;
            this.interval = data.interval;
            this.crit = data.crit;
            this.critChance = data.critChance;
            this.armor = data.armor;
            this.skills = data.skills;
            this.scopeSize = data.scopeSize
        }
    }

    save() {
        localStorage.setItem("save", JSON.stringify(this));
    }
}

Additionally, the game’s performance has been optimized to handle multiple moving elements without significant FPS drops, with only minor issues arising when enemy rotation was introduced (disabled for the FPS sake).

Design

Areas for Improvement and Challenges
While the project has made significant progress, there are several areas for future improvement. The settings button on the home screen is currently non-functional and needs to be implemented. Expanding the variety of enemies and introducing the ability to prestige levels are also planned enhancements that will add depth to the gameplay.

Also I encountered a significant scaling challenge when testing the game on devices with different screen sizes and resolutions. The game elements, including flying shapes, cursor box, and UI components, were not displaying consistently across various machines. To resolve this, I implemented a scaling solution using scale factor based on canvas size and baseWidth with baseHeight, that ensures optimal display across different screen sizes.

Any way one of the main challenges encountered was optimizing performance, particularly when adding rotation to the enemies. This issue highlighted the need for careful consideration of graphical elements and their impact on game performance. Moving forward, further optimization and potentially exploring alternative rendering techniques could help address these performance concerns and allow for more complex visual elements in the game.

Week 5: Midterm Report

Concept
I decided to implement a clicker/incremental game with a twist. Instead of just clicking buttons, you’ll be hunting down flying shapes, upgrade your abilities and much more. Cursor will have a box (scope/aim) attached to it, and when an enemy shape is inside this box, clicking will damage it. As you defeat enemies, you’ll earn different types of resources to upgrade your skills in a skill tree. The game will also have prestige rounds (levels), letting you to progress over the game with some bonuses. This idea didn’t come out of nowhere – it’s inspired by a bunch of incremental and clicker games I’ve played, like To The Core, Cookie Clicker, Adventure Capitalist, and others. I’m trying to take the parts I liked best from these games and mix them up into something new and fun.

Design
I’ve been sketching out ideas in Figma. So far, I’ve got designs for the skill tree and the main page. I’m still working on the game screen, but I’ve got the enemy shapes and cursor box figured out.

Main page

Skill tree and upgrades

Enemies and shooting box


I decided to keep the design simple and stick to a pixel art style. This choice not only fits the retro vibe of many clicker games but also helps keep the visuals clean and easy to understand. Plus, pixel art is pretty forgiving when you’re not an art pro, which is perfect for me. The simple style should also help with performance, which is a bonus given my worries about how smoothly everything will run.

Challenges
One big worry is how well the game will run. P5.js is great, but I’m not sure if it can handle lots of moving shapes and calculations without slowing down. I might need to cut back on some features or find ways to make the code run faster. Especially when there are many enemies on screen, or when the skill tree gets complex, the game might start to lag.

Another tricky part is balancing the difficulty. I want the game to get harder as you play, but not so hard that it’s frustrating. Finding that sweet spot will take some trial and error. It’s not just about making enemies tougher – I need to balance how fast you earn resources, how much upgrades cost, and how much stronger they make you. If I mess this up, the game could end up boring or impossible.

Designing the skill tree is also proving to be a challenge. I want it to be interesting and give players meaningful choices, but not so complicated that it’s overwhelming. Each skill needs to feel useful, and there should be different strategies players can try. But I also don’t want to end up with a situation where there’s one “best” path that makes all other choices pointless.

Risk Prevention

  • To tackle the performance issue, I’m going to start by making a simple version with just a few moving shapes. I’ll test how many I can add before the game starts to lag. This will help me figure out if I need to change my plans or look for ways to optimize the code. I’ve also started looking into ways to optimize p5.js, like using object pooling for enemies instead of creating new ones all the time.
  • For the difficulty balance, I’m planning to create a basic difficulty curve and then play-test it a bunch. I’ll probably need to tweak the numbers a lot, but starting with something I can actually play will help me see what works and what doesn’t.
  • To handle the skill tree challenge, I am planning to implement main skill class. This basic structure will let me experiment with different skills and costs without committing to a full implementation. I’ll gradually expand this as I figure out what works and what doesn’t.
  • Also I want to implement progress save functionality, I’m going to start by just saving the bare minimum – maybe just the resources and which skills are unlocked. I will probably use browser’s local storage to store this data, which should be simple to implement.

By tackling these challenges one by one, I’m hoping to reduce the risks and make steady progress on the game. It might not be perfect right away, but having something playable will make it much easier to improve over time.

Reading Reflection – Week 5

This article made me think about how computer vision is different from human vision in some important ways. Humans can easily understand the meaning and context of what we see, but computers need very specific instructions to make sense of images. The article talks about how even simple things like detecting motion or finding objects are challenging for computers. We take for granted how our brains can instantly recognize people, objects, and what’s happening in a scene. But for a computer, each of those tasks requires complex algorithms and programming.

I found it interesting how the article emphasized the importance of setting up the physical environment to help computer vision systems work better. Things like using special lighting, high-contrast backgrounds, or reflective markers can make a big difference. This shows that computer vision isn’t just about fancy software – the hardware and physical setup matter a lot too. It made me realize that artists and designers using computer vision need to think carefully about the whole system, not just the code.

The use of computer vision for tracking and surveillance in art projects raises some tricky issues. On one hand, it allows for really cool interactive experiences where the artwork can respond to people’s movements and actions. But it also means constantly watching and recording what people are doing, which could feel invasive. I wonder how artists think about the ethics of using these technologies. The Suicide Box project mentioned in the article is a good example of how computer vision can be used to gather data on sensitive topics in ways that make some people uncomfortable. Overall, I think computer vision creates exciting new possibilities for interactive art, but artists need to be thoughtful about privacy concerns and potential negative impacts of surveillance.

Week 4: Who or What is Perlin?

Concept
I have always been fascinated by ASCII art and how simple characters can create complex images. But I wanted to take it a step further. What if we could make ASCII art that moves and changes color? That is where Perlin noise comes in. By using noise to determine both the characters and their colors, we create a living, breathing ASCII landscape that is very satisfying  to watch. The idea is simple: we divide the canvas into a grid of cells. For each cell, we use Perlin noise to choose an ASCII character and a color. As time passes, the noise changes, making our ASCII world shift and flow like a colorful river of text.

Code snippet
The heart of this project is how we map noise values to both ASCII characters and colors. Here is the snippet I’m most proud of:

const noiseVal = noise(x * 0.01, y * 0.01, frameCount * 0.01);
const charIndex = floor(map(noiseVal, 0, 1, 0, density.length));
const asciiChar = density.charAt(charIndex);
const hue = map(noiseVal, 0, 1, 0, 360);
fill(hue, 100, 100);

This bit of code is doing double duty. It’s using the same noise value to pick an ASCII character and determine its color. I was able to achieve a perfect harmony/balance between the texture of the characters and their hues.

Sketch

Reflection and ideas for future improvements
I’m pretty happy with how this turned out, but there’s always room for improvement. The main issue I’m facing is performance. If I try to add more features or increase the resolution, things start to get laggy real quick.

Looking ahead, I’ve got a few ideas how I can improve this sketch:
First, I want to optimize the code. Maybe I could use a buffer to draw the ASCII characters once and then just update the colors each frame. This would cut down on the text rendering overhead. I’m also thinking about making the cell size dynamic. Imagine if the cells got smaller when you moved your mouse closer, and smaller if mouse far away. That will add more interactivity and will help to make this sketch even more dynamic. Lastly, I’d love to experiment with different noise algorithms. Perlin noise is great, but there are so many other types of noise out there. Each one could give a unique character to the ASCII landscape.

Reading Reflection – Week 4

That light switch placement in the dorm bathroom really gets on my nerves! Every time I go in there, I end up smacking the mirror instead of hitting the lights. It’s such a small thing, but it makes a big difference in how frustrating it is to use the bathroom. The switch is so close to the mirror already – why not just move it a tiny bit closer so it’s the first thing your hand hits? This seems like a perfect example of Norman’s point about the importance of mapping and natural positioning of controls. A little more thought about the user’s actions could have made this design so much more intuitive and less annoying.

The shades in the NYU New York dorms are another headache. These shades consist of multiple connected panels and have a seemingly simple string mechanism for opening and closing. However, the actual operation is far from intuitive or user-friendly. You have to pull the string sideways and then up or down, but it doesn’t always work right. Sometimes you end up doing a little dance just to open or close them. What’s more, if you try to open or close the shades too quickly, the individual panels start rotating as crazy instead of moving up or down. Why make it so complicated?

Norman’s principles could definitely be applied to interactive media design. In my other class, we’re struggling with how to show users which objects on the screen are clickable. Should we add a glow effect? An outline? Following Norman’s ideas about signifiers, we need clear visual cues to indicate interactivity. But we also don’t want to clutter up the artwork. It’s a tricky balance.

I like how Norman emphasizes the importance of feedback. With digital interfaces, it’s crucial to give users immediate confirmation that their action worked. Even a slight delay can be confusing. In our comics, we’re trying to add subtle animations or sound effects when objects are clicked. The trick is making the feedback noticeable but not distracting from the story.

Overall, the reading made me more aware of design choices all around me. I’m noticing signifiers and affordances everywhere now! It’s a good reminder that even small details can have a big impact on usability. As we create digital experiences, we need to really think through how users will interact and understand the interface. Good design isn’t just about looks – it’s about creating an intuitive experience.

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.

Reading Reflection – Week 2

I’ve always been curious about chance, ever since I was a kid thinking about fate. It made me wonder how much we can really predict in life, and how much is just random. I explored concepts like Laplace’s demon, the nature of pseudo-randomness, and even dived a little bit into quantum physics. trying to figure it out. Casey Reas’ talk at Eyeo was eye-opening for me. He showed how randomness can make art really interesting. It’s not just about throwing random stuff together, but setting up systems where chance can do cool things. This got me thinking about my own art differently. What stuck with me was how Casey uses simple rules to make complex stuff happen. It’s like he makes a playground for randomness and lets it go wild, but with some boundaries. I find this mix of control and chaos really cool.

For my sphere project after finishing it, I’m wondering how to use some of Casey’s ideas. Maybe I could make the sphere, which represent atoms, move randomly, or shift things around in unexpected ways. I’m not sure exactly what I’ll do yet, but I want to try something new. I think the right mix of randomness and control depends on what you’re making. Sometimes a bit of randomness makes things feel more real. Other times, you need more control. I usually start with a clear idea, then add some random elements to make it more interesting. Casey’s work has definitely made me want to experiment more with letting go of control and seeing what happens.