Week 6 – Game Progress

 

Project concept

Last week, when I first thought of my game idea, I had almost the same concept as now, but it was originally a candy-themed game. Then I decided to make it closer to home, more customizable, and more traditional. I was trying to think about what should fall from the sky instead of candy, but I really couldn’t come up with anything at first.

Then one day, I was at my grandpa’s house, and I saw him drinking coffee with my little brother. It made me laugh because in our culture, especially in Arab families, they always tell kids not to drink soft drinks, but somehow Gahwa (Arabic coffee) is always allowed, even though it’s full of caffeine! What’s even funnier is that my grandpa used to give my little brother kahwa when he was literally a baby. He could only drink milk, but my grandpa would secretly give him kahwa without my parents knowing. In his mind, kahwa was totally fine, but soft drinks were bad.

That moment gave me the idea to make the game about Gahwa. So now, in my game, the goal is to catch the Gahwa and avoid the Pepsi , if you catch the Pepsi, the game is over. That twist made the game feel really traditional and personal to me.

I also decided to name the characters with Arab names and base them on my younger brother and sister. I really enjoyed that part because it made the game feel more meaningful and connected to my culture. Even though it’s a simple game and my technical experience isn’t that advanced yet, I really love the creative side of it. It feels fun and personal, and that’s what I enjoyed most.

What I am proud of

For my Week 6 submission, what I’m most proud of is that I made this entire game from scratch it’s my first time ever creating a full game, and that alone makes me really proud of myself. I’m also proud of how resourceful I was throughout the process. Even though the YouTube videos I found weren’t the same as my game at all, I still managed to understand their concepts and figure out how to apply them to my own project. I feel like I found really good sources that helped me learn and improve, and it showed me that I’m capable of teaching myself new things and solving problems independently.

I’m also really proud of my concept because it has a story behind it that makes it personal and meaningful. I feel like I did really well in both the creative and technical parts of the project. On the technical side, I worked hard to understand new concepts and used different sources to make my game function the way I wanted. On the creative side, it all came naturally because I was genuinely passionate about the idea. I really enjoyed bringing my story to life through the game, and that made the whole process even more special for me.

Bug

The only thing that’s bothering me about my game right now is that sometimes you lose even when the Pepsi is kind of far from the character. It doesn’t actually touch or collide with the player, but the game still ends as if it did. I think it’s because the data or hitbox isn’t directed properly to the character, so I’m planning to fix that bug. I also haven’t added any sounds yet, but I really want to, I just need to watch some tutorials first to learn how to do it correctly.

Code Highlight

This part of the code is one of the main things we learned in class, and it really became the foundation for my whole project. It basically controls what shows up on the screen depending on which stage of the game you’re in, like the home screen, instructions, character select, gameplay, or game over. This structure made everything so much easier for me because it helped organize my code and made it clear what each part should do. I started with this as my base and then kept building on it, adding more functions and features as I went along. It really helped me understand how to manage different screens in a game.

function draw() {
  background(0);
//conditions for screens 
  if (currentScreen === 'home')       drawHome();
  else if (currentScreen === 'instructions') drawInstructions();
  else if (currentScreen === 'character')    drawCharacterSelect();
  else if (currentScreen === 'game')         drawGame();
  else if (currentScreen === 'gameover')     drawGameOver();

Some Images I Used

Midterm Project: Worm vs Sanity

Concept

Food has always been something deeply emotional forme  a way to heal, connect, and recharge after long or lonely days. Whether it’s sharing a meal with friends and family or eating quietly in solitude, food always finds a way to lift the spirit. For me, food is more than just fuel; it’s comfort, joy, and sometimes even memory itself. Every dish I eat reminds me of a moment, a feeling, or a person.

But, of course, there’s another side to that relationship  those unforgettable moments when something unexpected shows up in your food: a hair, a fly, a worm, even a tiny stone. It’s disgusting, sometimes shocking, and yet  over time  it becomes something you laugh about. The idea for this project actually struck me when I once found a fly in my food. In that split second, my emotions bounced between anger, disgust, and disbelief and then, later, laughter. I realized how something so small could completely shift my mood and turn an ordinary meal into a story I’d never forget.

It also reminded me of moments with my grandmother. She used to cook for the whole family, and occasionally, there would be a stray hair in the food. Instead of getting angry, I’d turn it into a lighthearted joke so everyone could laugh. Those moments became cherished  not because the food was perfect, but because the imperfections made it real, made it ours. They were messy, human, and full of love.

Through my project, I wanted to recreate those shifting emotions  from disgust and frustration to humor and warmth. I tried to capture the entire emotional cycle we experience in those moments: the anger when something feels ruined, the creepiness of noticing something “off,” and the humor that comes when you finally laugh it off.

  • Anger is portrayed through intense, chaotic visuals  like the “deadly” appearance of the dining hall, the harsh red tones.

  • Creepiness comes through the eerie atmosphere  the bloody dining hall textures, dim lighting, and strange, almost horror-like visual style that makes you feel uneasy, the same way you feel when you find something in your food that shouldn’t be there.

  • Humor ties it all together. I added funny instructions like “Ultimate Guide to impress Worm” that turns disgust into comedy. It’s a playful reminder that these moments, while annoying, are also absurd and relatable  something we can laugh about later.

To make it more personal, I brought in imagery from NYUAD  specifically D2 and the Library, two of my favorite places on campus. They hold countless memories of food, laughter, and friendship, so I wanted to reimagine them in my project. I took photos and used ChatGPT to generate artistic, surreal versions of these spaces  blending reality and imagination. The result is an environment that feels both familiar and eerie, mirroring that strange feeling of discovering something unexpected in what you love.

Lastly, I chose to use hand gestures as one of the interaction method because I wanted the experience to feel physical and expressive, not just mechanical. In real life, our hands are what connect us to food. We cook with them, eat with them, react with them. So, using gestures like moving the left hand to go left, right hand to go right, and closing the fist to jump feels symbolically and emotionally right. It mirrors how our hands instinctively respond when we’re disgusted or startled. We pull back, push away, or clench up.

While it might not be the most conventional control scheme, that’s precisely what makes this project unique  and artistic  rather than a simple computer game. The goal wasn’t to make a polished arcade game, but to create a more embodied experience  one that makes the player aware of their own physical reactions.

 

How to Play:

At its core, the project is an interactive game centered around a simple but expressive idea: defeat the worms that are being generated from right of the screen before they reach the end of the screen on left.

Players can interact with the game in two different ways:

Keyboard controls — using the arrow keys to move and jump: → to go right, ← to go left, and ↑ to jump.

Hand gesture controls — raise your left hand to go left and raise your right hand to go right. By raise I mean make your hand visible to the camera and when u don’t want to go say left make you left hand unvisible to the sight of the camera. If you make a fist or close your finger the girl will jump.

The basic rule is simple: jump over the worms to eliminate them before they cross the screen. Players have three lives, and if they manage to survive until time >= 900 (meaning the draw function has run 900 times) with at least one life left, they win.

At first, it might feel unintuitive, but as you play, it becomes surprisingly fun and natural  like you’re physically fighting off those unwanted “guests” in your meal.

Parts I’m Proud Of

The part I’m most proud of is integrating Machine Learning into a project that’s not only technical but emotional and personal. As a Computer Science major, I’m always drawn to exploring how technology can express feeling and creativity. Implementing gesture control allowed me to bridge art and code  to make something that doesn’t just work, but feels alive.

I’m also proud of how I personalized the experience. By using NYUAD-specific places like D2 and the Library, I rooted the project in a world I know and love. It gives the game a familiar atmosphere one that other NYUAD students can relate to  while still transforming it into something strange and artistic.

Areas for Improvement 

While I’m proud of how the game turned out, there are several areas I’d like to refine. The hand gesture control, though innovative, can feel slightly clunky at first. I’d like to make it more responsive and intuitive  perhaps by training the ML model with more data or maybe using ML to detect body that can say if a person is turning left or right and the character themself move left or right.

I’d also love to expand the visual storytelling. Right now, the “bloody” D2 gives the right kind of creepiness, but I imagine adding more levels or moods maybe transitioning from a calm dining scene to a chaotic food fight as the difficulty increases.

Problems that you ran into

While building the project, I faced a few interesting technical challenges that pushed me to think creatively about how motion and input are detected and processed.

1. Detecting when the hand is closed (fist gesture):
My first major challenge was figuring out how to detect when the user’s hand is closed. I wanted the “fist” gesture to trigger a jump action, but at first, I wasn’t sure which hand landmarks to compare. Eventually, I decided to track the index fingertip (keypoint 8) and the base of the index finger (keypoint 5).

The idea was simple: if the y-coordinate of the fingertip (hand.keypoints[8].y) becomes greater than that of the finger base (hand.keypoints[5].y), it means the fingertip is lower in the camera frame  in other words, the finger is curled in, forming a fist.

I used console.log(hand.keypoints[8].y, hand.keypoints[5].y) to visualize the values and experimented by opening and closing my hand repeatedly to see when the condition triggered. This trial-and-error approach helped me fine-tune the threshold for reliable gesture recognition. It was satisfying to see the jump action respond accurately once the logic clicked.

 

 

2. Managing repeated function calls with hand gestures:
The second issue was with repeated trigger events when using gesture control. Unlike pressing a key  which calls the action just once per pressraising a hand is a continuous motion, so the detection function kept firing dozens of times per second.

For example, calling girl1.jump() or movement functions using hand gestures caused the action to repeat uncontrollably fast. To solve this, I implemented a counter-based system and used a modulus condition to limit how often the action executes. Essentially, if the function was being called too rapidly, I only allowed it to execute once every ten calls.

Similarly, I adjusted the character’s movement speed when controlled by gestures. Instead of moving by this.speed_x each frame (which made her move unrealistically fast), I scaled it down to this.speed_x * 0.005 inside the update_Ml() function. This made her movement smooth and proportional to the natural pace of a hand gesture, giving the game a more balanced and controlled feeling.

This also applied to animation strip changes by updating them every tenth frame, the animation stayed visually consistent without flickering or overloading.

 

My Sketch :

view only screen link: https://editor.p5js.org/aa11972/full/b224cudrh

 

Midterm

Inspiration

For this project, I want to create an interactive digital art piece that explores the true scale of reality by gradually zooming from large, natural environments down to microscopic and atomic levels.

Visual Elements

Flower Screen

  • Add a tree, birds, more flowers, a grass field, and the sun for a fuller composition.

  • Include animations such as swaying grass, apples falling from the tree, and birds flying across the screen to make it feel alive.

Leaf Screen

  • Add details like insects, the stem, and a more zoomed-in view of the leaf.

  • Animate insects crawling across the surface to bring a sense of realism.

Cell Screen

  • Show multiple plant cells floating in a jelly-like substance.

  • Design them to resemble real plant cells, with more detail and fluid animation.

Atom Screen

  • Illustrate atoms with orbiting ellipses that cross over each other.

  • Show the nucleus clearly, with protons and neutrons on display.

Interaction: Zoom Functionality

  • Replace the two-finger pinch with a two-hand gesture for zooming, making it more intuitive and reducing accidental zooms.

  • Add smooth zoom animations between levels instead of abrupt page changes, to create a more immersive transition.

Sound Design

  • Integrate sounds that complement each environment:

    • Flower screen: natural ambient sounds (e.g., wind, birds).

    • Leaf screen: subtle insect sounds.

    • Cell screen: soft “jelly-like” sounds.

    • Atom screen: buzzing or electrical sounds.

  • Add a “zoom-in” sound effect to enhance transitions

    (All sounds are sourced from Pixabay.com.)

Machine Learning

To enhance user interactivity, I incorporated machine learning using the ml5 library, which integrates well with p5.js and is relatively simple to implement. I set two thresholds, “close” and “far”, based on the distance of the user’s hands. These thresholds determine when the zooming action is triggered, making the interaction feel more natural and responsive.

Extra details and screenshots

I added a home page to show users the hand gestures and extra button functionalities.

Screen Recording 2025-10-07 at 00.17.22

Challenges

Coming up with creative ideas for this project was challenging, and implementing the zooming feature was especially difficult since I had never attempted it before. Getting it to work smoothly took a lot of trial and error.

This link from p5 was helpful – https://editor.p5js.org/mimimimimi/sketches/SOkckqY_r https://editor.p5js.org/Luxapodular/sketches/rk__bPdcm but also just experimenting with the ease in and out values to make the zoom as natural as possible.

// ===== TRANSITIONS =====
// initiate zoom transition between scenes
function startZoomTransition() {
  isTransitioning = true;        // flag to indicate transition is active
  transitionProgress = 0;        // reset
  
  // Play zoom sound for every transition at 50% volume (if not muted)
  if (zoomSound && !isMuted) {
    zoomSound.setVolume(0.5);
    zoomSound.play();
  }
}

// update for each frame
function updateTransition() {
  if (!isTransitioning) return;  
  
  transitionProgress += 0.03;    // increment by 3% each frame 

  //check if 100% (1)
  if (transitionProgress >= 1) {
    isTransitioning = false;     // stop transition
    transitionProgress = 0;      // reset
    currentPage = currentPage === SCENES.length - 1 ? 1 : currentPage + 1;
    playSceneSound(); // Play sound for the new scene
  }
}

// applies visual zoom effect during transitions
function applyCameraTransform() {
  // create smooth easing curve: slow start, fast middle, slow end
  const easeT = transitionProgress < 0.5
    ? 4 * transitionProgress ** 3      // first half: cubic ease-in
    : 1 - (-2 * transitionProgress + 2) ** 3 / 2;  // Second half: cubic ease-out
  
  // calculate zoom level: smoothly interpolate from 1x to 100x zoom
  const zoom = lerp(1, 100, easeT);
  
  // get the target point to zoom into for current scene
  const [x, y] = SCENES[currentPage].zoomTarget;
  
  // apply camera transformation:
  translate(x, y);     // move to zoom target point
  scale(zoom);         // apply zoom scaling
  translate(-x, -y);   // move back to keep target centered
}

final code – https://editor.p5js.org/kk4827/sketches/9CleTb6y1

Midterm Project

Inspiration

The idea for Blackhole was born from one of my all-time favorite casual games: hole.io. The core concept of “the more you eat, the more you grow” fascinated me. However, my goal was never to recreate an existing game, but to reinterpret that mechanic in an entirely different environment.

In hole.io, the objective is to have the largest area among all players, consuming the environment and other players to maintain your crown. So I though of reimagining that concept in space? What if the hole was a blackhole preying everything in its path? This became the foundation of my project; A space-themed, single-player survival game centered around growth, gravity, and chaos.

Concept

Blackhole is a single-player arcade-style game set in deep space. The player controls a blackhole that grows by consuming asteroids and powerups, while avoiding larger threats.

To bring the theme to life, I envisioned asteroids as natural “food” for the blackhole (blending the space aesthetic with the satisfying loop of consuming and expanding). To make the gameplay more dynamic, I added powerups that appear on screen at random intervals, offering temporary boosts or effects to make the experience more engaging.

The main goal is simple: survive as long as possible while growing your blackhole and collecting stars for bonus points. The longer you last, the higher your score.

Implementation

Developing Blackhole was an iterative process. I began by prioritizing functionality, ensuring the mechanics worked before focusing on visuals or audio.

Blackhole

The foundation of the game lies in the Blackhole class, responsible for handling player growth, shrinking, and interaction with other entities. For simplicity, I represented all objects (asteroids and powerups) as circles. This made collision detection intuitive and computationally efficient. Using the dist() function in p5.js, I determined when the player’s blackhole had consumed another object or collided with a threat.

Blackhole Class:

class Blackhole{
  constructor(){
    this.size=25;
    this.speed=3;
    this.x = 100;
    this.y = 100;
  }
  
  // call when eats star or expand powerup
  grow(){
    this.size *= 1.2;
  }
  
  shrink(){
    this.size *= 0.8;
  }
  
  move() {
    if (keyIsDown(UP_ARROW)) {
      // guarding against boundaries
      if (this.y - this.speed > 0){
        this.y -= this.speed;
      }
    }
    if (keyIsDown(DOWN_ARROW)) {
      // guarding against boundaries
      if (this.y + this.speed < height){
        this.y += this.speed;
      }
    }
    if (keyIsDown(RIGHT_ARROW)) {
      // guarding against boundaries
      if (this.x + this.speed < width){
        this.x += this.speed;
      }
    }
    if (keyIsDown(LEFT_ARROW)) {
      // guarding against boundaries
      if (this.x - this.speed > 0){
        this.x -= this.speed;
      } 
    }
  }
  
  display(){
    stroke('white');
    strokeWeight(2);
    fill('black');
    circle(this.x, this.y, this.size);
  }
  
  // returns boolean
  collides(obj) {
    let d = dist(this.x, this.y, obj.x, obj.y);
    return d <= this.size/2;
  }
}

Powerups and Movement

Initially, I designed the powerups to spawn randomly and stay on screen indefinitely. However, I quickly realized that this cluttered the visuals and made it hard to differentiate between background stars and powerups. Even adding a blinking effect before disappearance didn’t feel natural.

Taking inspiration from Tetris Rush, I redesigned the mechanic. Now, powerups drop from the top of the screen and disappear at the bottom, creating a natural movement cycle. This solved both visibility and clutter issues while keeping the game lively and visually coherent.

Powerup Class:

class Powerups {
  constructor(_x, _y, _type, _img) {
    this.x = _x;
    this.y = _y;
    this.type = _type;
    this.img = _img;
    this.fallSpeed = random(1, 3); // random falling speed
  }

  // to have powerups fall from up to down
  move() {
    this.y += this.fallSpeed;
    if (this.y > height) {
      this.y = height;
    }
  }

  display() {
    textSize(20);
    
    if (this.type == "fast") {
      this.size = textWidth(''); // for detecting collissions
      text('', this.x, this.y);
    } 
    else if (this.type == "freeze") {
      this.size = textWidth('❄️'); // for detecting collissions
      text('❄️', this.x, this.y);
    } 
    else if (this.type == "grow") {
      // image for grow
      push();                   
      imageMode(CENTER);
      this.size = 75; // for detecting collissions
      image(this.img, this.x, this.y, this.size, this.size)
      pop();
      
    } 
    else if (this.type == "shrink") {
      // image for shrink
      push(); 
      this.size = 40; // for detecting collissions
      imageMode(CENTER);
      image(this.img, this.x, this.y, this.size, this.size)
      pop();
      
    } 
    else if (this.type == "star") {
      this.size = textWidth('⭐️'); // for detecting collissions
      text('⭐️', this.x, this.y);
    } 
    else if (this.type == "bomb") {
      this.size = textWidth(''); // for detecting collissions
      text('', this.x, this.y);
    }
  }
}

Asteroids

For this class it was difficult preventing the asteroids from moving in predictable or repetitive patterns. To make the game feel organic and chaotic, I implemented an Asteroid class that allows each asteroid to move in random directions and change course periodically.

Each asteroid picks a random direction from a list of possible vectors including diagonal and straight-line movement and updates its velocity every few seconds. This ensures the movement feels spontaneous, mimicking the drifting, floating nature of space.

Asteroid class

class Asteroid {
  constructor(_x, _y, _img, _size) {
    this.x = _x;
    this.y = _y;
    this.img = _img
    this.size = _size;

    // separate velocities
    // this.vx = random([-1, 1]); // left or right
    // this.vy = random([-1, 1]); // up or down
    this.speed = 1.5;
    
    this.setRandomDirection();
  }

  // asteroids move in any direction randomly
  setRandomDirection() {
    let choices = [
      [1, 0],   // right
      [-1, 0],  // left
      [0, 1],   // down
      [0, -1],  // up
      [1, 1],   // diagonal down-right
      [-1, 1],  // diagonal down-left
      [1, -1],  // diagonal up-right
      [-1, -1]  // diagonal up-left
    ];

    let dir = random(choices);
    this.vx = dir[0]; // x-axis dir
    this.vy = dir[1]; // y-axis dir
  }

  move() {
    
    // every 2s change direction
    if (frameCount % 120 === 0) {
      this.setRandomDirection();
    }
    
    this.x += this.vx * this.speed;
    this.y += this.vy * this.speed;

    // Bounce off edges
    if (this.x < 0 || this.x > width)this.vx *= -1;
    if (this.y < 0 || this.y > height) this.vy *= -1;
  }
  
  display() {
    push();                   
    imageMode(CENTER);
    image(this.img, this.x, this.y, this.size, this.size);
    pop();
  }
}

Code I’m Proud of

One of the features I’m most proud of implementing is the freeze and speed-up powerups. Increasing/ Decreasing the speed the speed at collision was easy but how do I revert those changes back to their original state after a fixed duration (around 4 seconds).

I knew I could use frameCount to track time progression, but the question was where and how to integrate it efficiently without breaking the game loop. The solution came through the use of two external constants: freezeTimer and fastTimer.

Whenever the player collided with a powerup, the corresponding timer was assigned a specific value. In each frame of the game, these timers would decrement until they reached zero. Then the original state was restored.

// timers
  if (freezeTimer > 0) {
    freezeTimer--; // keep decreasing with every frame count
  } else if (fastTimer > 0) {
    player.speed = 5;
    fastTimer--; // keep decreasing with every frame count
  } else {
    // resetting speed for player and aesteroids
    player.speed = 3;
    for (let asteroid of asteroids) {
      asteroid.speed = 2;
    }
  }

Design and Visuals

For the backdrop, the choice was obvious, a starry night sky. I later replaced my simple circular asteroids with actual asteroid images to enhance immersion.

Sound design also became an important aspect. I added distinct sound cues for eating asteroids and activating powerups. Interestingly, while I was coding, the song “All the Stars” started playing and it immediately felt like the perfect fit. So I included it as background music, giving the game a cinematic atmosphere.

Instructions Screen

Game Screen

Game Over screen

Key Challenges and Solutions

  1. Resizing Mechanics
    One of the more subtle but tricky challenges I faced was maintaining a consistent visual layout across different screen sizes. A problem I faced was that whenever I would resize on the instructions or Game Over screen, it would give me an error and paint a black empty backdrop. This was because I used noLoop() to freeze the game on both the instruction screen and the Game Over screen. To solve this, I ensured that after resizing, the program would temporarily call redraw function (even when in a noLoop() state) to refresh the layout and correctly reposition all visual elements according to the new width and height.

  2. Blackhole and Asteroid size

Another major design challenge came from the scaling mechanics of the Blackhole and the Asteroids. Since the central idea of the game revolves around “eating to grow,” the player’s size could increase infinitely if left unchecked. Thereby, eventually covering the entire canvas and breaking the gameplay. Similarly, large asteroids could spawn that were nearly impossible to avoid or defeat, making the game feel unfair or chaotic.

To address this, I implemented maximum and minimum size constraints for both the Blackhole and the Asteroids. The Blackhole’s growth is now capped at a defined MAX_SIZE, preventing it from expanding beyond the playable area, while asteroids are spawned within a limited size range relative to the player’s current size. This balancing ensures that gameplay remains challenging yet visually coherent.

Potential Developments

While I’m proud of the current version of Blackhole, there’s plenty of room for evolution.

  • Improved Scoring System:
    Currently, the score depends on survival time and the number of stars collected. In the future, I’d like to integrate the player’s size into the scoring formula (though my earlier attempts caused the score to grow too rapidly to track meaningfully).

  • Explosive Powerups:
    Introducing a special powerup that destroys all asteroids within a radius could add an exciting burst element and reward risky gameplay.

  • Dynamic Difficulty:
    Over time, the game could progressively increase asteroid speed or bomb spawn rate, keeping the challenge alive as the player grows.

Midterm Project – Goalkeeper Challenge

Concept
As a kid, I admired strikers for scoring beautiful goals, but now I understand what a difficult and beautiful job goalkeepers have in saving their team. My admiration for goalkeeping grew, especially after watching the incredible 2022 World Cup Final between Argentina and France in Qatar.

In the game I’ve made, the player moves the goalkeeper’s gloves with a mouse or trackpad to save penalties. Each player starts with three lives and loses one for every goal conceded. Players can unlock new skins for their gloves. Making 10 saves in a single game unlocks the first skin, and reaching 15 saves in one session unlocks a second one.

The game also saves each player’s personal best record, allowing multiple users to compete and track their high scores. There is also a special golden ball: saving it grants an extra life (+1), but conceding a goal from it costs two lives instead of the usual one. The controls are simple: press ‘F’ for fullscreen and ‘S’ to view and select skins. There is also a hidden ‘R’ key to reset the game and clear all data.

Highlight of the code

function saveUserData() {
  let userData = {
    highScore: highScoreSaves,
    unlockedSkins: unlockedSkins
  };
  localStorage.setItem(currentUser, JSON.stringify(userData));
}

One smart technical decision I learned in my Intro to CS class was to automatically save each player’s progress and unlocked skins. This ensures that players don’t lose their scores and achievements when they close or reload the game. It definitely adds to the experience, making it feel like a real game that saves user accounts and their rewards.

if (dist(ball.x, ball.y, keeper.x, keeper.y) < keeper.size / 2) {
  saveSound.play();
  saves++;
  ball.reset();
}

Another important feature is collision detection, which I implemented using the mathematical dist() function. The method of checking for an overlap between two circles, which was also taught in my Intro to CS class, is a much easier way to calculate collisions in a simple game. When a collision is detected, the code plays the ‘save’ sound, increments the save counter, and resets the ball to its starting position. I think this approach is very simple, short, and super-efficient.

Sketch
https://editor.p5js.org/da3490/sketches/e03ZtWqpi

Reflection
I drew on my previous experience creating a Jetpack Joyride duplicate in my Intro to CS class to build this game’s features, including the login and menu pages, score tracking, user record saving, collision detection, and skins. While developing the UI took some time, it wasn’t logically difficult.

I would say that making the game adaptive to different screen sizes took the most effort. Instead of using fixed pixel values, I had to use percentages and mathematical relationships, such as width * 0.5 and height * 0.3. This approach was tricky but ensures the game looks and works properly on any device. I also added glow and glass effects to enhance the UI aesthetics. Using drawingContext and shadowBlur, I created transparent rectangles that produced a modern ‘glass’ look. While this style may be less popular now, it was a prominent trend in 2023-2024.

Future improvements
For future improvements, I would love to replicate FIFA-style penalties with a two-player mode: one player aims and shoots while the other plays as the goalkeeper.

To achieve a more realistic, front-facing perspective instead of the current view, I would need to implement 3D-like mechanics. This would involve angle calculations and scaling the ball’s size to create a sense of depth. The goalkeeper would use keyboard buttons to move in all eight directions (left, right, up, down, and diagonals) and would have a jump mechanic to make saves. For the shooter, the mouse would control the aim, while holding down the spacebar would determine the power of the shot.

MidTerm Project – Shahram Chaudhry

The Sketch

https://editor.p5js.org/sc9425/full/RnrYJ2fls

Concept Development and Final Concept

I originally imagined this project more like a game, where users would have a limited time to quickly label memories as good or bad, and discard the bad ones to “win.” The goal was simple: clean up the mental space by getting rid of what weighs us down. But as I worked on it more, especially while curating the kinds of memories to include my perspective started to shift.

I realized memories aren’t always black or white. They’re messy, layered, and often emotionally ambiguous. A single moment can carry joy and pain, nostalgia and regret. So the project evolved. Rather than forcing users to judge a memory under a timer, I wanted to create a quieter, more reflective experience,  one where the user has gentle control: to reveal, sit with, or discard memories at their own pace.

For instance, I studied abroad in Paris and found it magical: exploring the city, trying new foods, feeling independent. But I recently came across a post by someone who had a completely different experience there. They couldn’t afford daily subway rides, had to walk 6.5 kilometers to class, and got by on snacks. For them, Paris wasn’t the city of love, it was a daily struggle. That contrast stuck with me. Same place, completely different emotional weight. And that’s what Mind Palace became about: subjective memories, and giving people space to decide what they mean and what to do with them.

In terms of the UI, I think I made meaningful improvements during development. Initially, I had a simpler design with a pink color scheme, thinking it would naturally signify the brain or mind because that’s the color of the brain icon. However, when I showed it to classmates, several of them were confused about what it represented. Based on that feedback, I decided to pivot. I found an actual artistic image of a brain online that better communicated the theme, and I reduced its transparency so it wouldn’t overpower the rest of the experience. This way, the background sets the mood and context without distracting from the interactive elements.

The previous design was:


The final design:

How It Works

The Mind Palace starts with a simple instruction screen. Once the user clicks to begin, memories, represented as floating film icons (often associated with memories), gently drift across the screen. 

The user interacts using just their index finger, tracked by the webcam. Initially, I had a gesture (open palm) to reveal a memory, but after feedback in class, I realized it felt a bit unituitive. So I simplified it, now just hovering over a memory for 2 seconds reveals it. It made the interaction smoother and avoided asking users to remember too many gestures.

Once a memory is revealed and the user has had a chance to read it, they can discard it using a thumbs-down gesture. I have made sure that users can’t just hover over and directly discard a memory without it being revealed, because then users will just be discarding random memories. To make the gesture recognition more robust and avoid accidental deletion, I also made sure users had to hold the thumbs-down gesture for a second, so it wouldn’t trigger accidentally.

For resetting the experience, I originally thought about using an “OK” gesture, like saying “I’m done.” But since reset is a pretty major action, and misfires could be annoying, I decided to keep it simple: users just press the Escape key. It also felt kind of full circle, like they press a button to enter and a key to exit. I focused on keeping things intuitive and reflective. I meant to give the user space to engage with each memory calmly, without rushing.

Each memory is intentionally ambiguous. For example: “The last message I never replied to”

This could evoke very different emotions depending on the person engaging with it. For some, it might feel empowering,  a sign of setting boundaries, moving on, or finally letting go of something that no longer serves them. For others, it might bring up guilt, anxiety, or a lingering sense of “what if.” That’s the heart of the project: recognizing that memories aren’t fixed in meaning. What feels like healing to one person might feel like avoidance to another. By keeping the memories vague yet emotionally charged, I encourage reflection, allowing each user to project their own story onto them.

I’m especially proud of implementing gesture recognition. It’s something I’d seen at IM showcases before, but I didn’t think I’d be able to do it myself. Understanding hand landmarks and translating them into reliable, smooth gestures took time, but I managed to make it functional and fairly intuitive. Here’s the core gesture logic I used:

function isThumbsDown(landmarks) {
  const thumbTip = landmarks[4];
  const wrist = landmarks[0];
  return (
    thumbTip.y > wrist.y &&
    !isFingerUp(landmarks, 8) &&
    !isFingerUp(landmarks, 12) &&
    !isFingerUp(landmarks, 16) &&
    !isFingerUp(landmarks, 20)
  );
}

function isFingerUp(landmarks, tipIndex) {
  const midIndex = tipIndex - 2;
  return (landmarks[midIndex].y - landmarks[tipIndex].y) > 0.05;
}

I also made some simple but thoughtful design choices like placing the webcam feed at the top so users can always see if they’re in frame. That helped during testing and made the interaction clearer.

Challenges and Improvements

Gesture recognition was a big concern for me. It’s surprisingly tricky to get right,  too strict, and gestures feel frustrating to perform (and even to code); too loose, and false positives ruin the experience. One major challenge was simply understanding the hand landmark system, there are 21 tracked points per hand, and it took a while to learn which ones corresponded to each finger joint and how to use them meaningfully in gesture logic.

At first, I tried more complex calculations for gestures, but it quickly stopped feeling intuitive. Users had to “perform” gestures perfectly, and the experience lost its flow. Now I’ve simplified it: instead of complicated checks, I just use the thumb and index finger landmarks in straightforward ways, plus a timing delay. For example, the thumbs-down gesture only triggers if it’s held for one full second. This makes it much harder for it to fire accidentally while still keeping the interaction easy and natural for users.

Another improvement  would be adding variety,  either by generating new memory phrases dynamically or letting users add their own. Right now, the memory list is static. Adding this level of customization could make each user’s Mind Palace feel more personal. I also think sound effects tied to each gesture (reveal, discard, reset) would enhance immersion and make the interactions feel more responsive.

 



Week 6 – Midterm Project Documentation

Copy Paste To Browser For Full-screen Experience:

https://editor.p5js.org/AsmaAlMurr/full/i15QXvk3g

Overall Concept

My project, Majlis Madness, is an interactive game that introduces players to Emirati cultural traditions through play and memory.  The game is set inside a majlis, a traditional gathering space where families and friends share hospitality, food, and conversation. Instead of just learning about this culture through text, the game engages the player with a memory sequence challenge where they must remember the order in which Emirati snacks “glow” and then repeat the sequence, the player has three lives symbolized by a heart icon at the top left. The concept combines cultural storytelling and information with a fun, simple game design so that players learn something new while having an enjoyable experience.

Originally, my idea was to design the game around plants in a garden, where players would memorize the sequence of flowers. While this concept was visually appealing, it didn’t feel personal enough to me. I realized that using snacks in a majlis would be more meaningful, since it directly connects to my own cultural experiences and memories. Instead, I used its basic bones as a shell to create a better version of this game. This shift made the game feel more authentic and gave it a stronger connection to my Emirati traditions.

My Original Game Idea (Prototype):

Inspiration:

The design of Majlis Madness aims to blend visuals, sounds, and interactivity: background images depict the majlis, oud music plays in the background to create atmosphere, and traditional snacks like Vimto, laban, chips, and ice pops become the central objects of the memory challenge. This makes the project both playful and informative, highlighting how cultural spaces like the majlis combine hospitality, tradition, and fun.

On a personal level, I feel a deep connection to the majlis because it has always been at the center of family and community life for me. Growing up, it was the place where I learned the value of gathering, listening, and sharing food. By recreating it in my game, I wanted to honor this space and give players a sense of its warmth, cultural meaning, and social importance. For me, the project is not only about coding a game but also about carrying forward traditions that shaped my own experiences.

For the background of the game, I was inspired by the traditional majlis setting, with its patterned carpets, red cushions, and lanterns that create a warm, communal atmosphere. This space felt like the perfect environment to represent Emirati culture, since the majlis is where people come together to share food, stories, and hospitality. 

For the sound design, I wanted it to feel authentic and true to the spirit of the majlis. After struggling to find the right audio online, I decided to ask a few local friends for inspiration. Their suggestions helped me discover tracks that carried the warmth and cultural depth I was aiming for, which made the game atmosphere feel much more genuine. I decided to stick to the classic tradition of the oud instrument as that is what both my friends and I associate with the majlis setting .

Screenshot on whatsapp where I asked for help for selecting the sound:

Here is an image of a Oud instrument for those who have never seen one:

Soundtrack of Abu Dhabi | National Geographic

How It Works: (Game mechanics)

When the player loads the game, they first see a cover screen with a logo for the game (Majlis Madness) and two options. Pressing ‘Enter’ takes them to a welcome page that introduces the Emirati majlis and explains its cultural importance. There is also an instructions page that gives step-by-step directions on how to play. Once the player starts, they watch a glowing sequence of snacks and then try to click them back in the same order. Each correct click is rewarded with a glow effect and a positive sound, while mistakes trigger an error sound, a red X, and eventually a gameover screen. If the player completes a sequence, they level up and face a longer, more challenging sequence.

Technically, the game uses a state machine to move between phases such as “cover”, “welcome”, “instructions”, “waiting”, “show”, “play”, “win”, and “gameover”.  Images and audio files are preloaded, and the layout is made responsive so the game can adapt to fullscreen sizes.

Planning and Design

(CHAT GPT WAS USED FOR SPECIFIC ARTISTIC ELEMENTS)

Before I wrote a single line of code, I began designing the game on paper. Sketching out screens and flows helped me plan the user experience in a structured way. I connected this process with UI concepts we had learned in class, like keeping instructions simple, providing clear feedback, and creating intuitive navigation between states. Having this roadmap made the actual coding process smoother, since I already had a clear vision of how each part of the game should look and feel.

Initial Planning Sheet:

Whiteboard In Class:

For the visual elements, I combined resources from different places. I gathered some reference images from Google (like snacks and majlis items) and then used ChatGPT to generate cartoon versions of these objects, then further tweaked them on procreate. This gave the game a playful and consistent art style while still grounding it in recognizable Emirati cultural elements. I liked how this workflow let me balance authenticity with creativity, bringing everyday cultural objects into a polished, game-ready format. For assets that were more specific like the glow feature in the game I used procreate on my iPad to draw a glowy circle because that was too difficult to find on google images, so it was better to create that on my own.

I am especially proud of the way my project mixes cultural storytelling with technical interactivity. Adding atmospheric oud music, using Arabic text (“مرحبا”) alongside English, and visually highlighting Emirati snacks that most locals relate with their childhood makes the game feel culturally rich. From a technical perspective, organizing the code into states and using a class for snacks makes the project more readable and user-friendly, while still handling animation, audio, and user feedback effectively.

Code Snippet:

I am particularly proud of the code that handles snack animations and misclick feedback, because it brings the game to life and makes the experience feel way more polished. The way it checks for shaking when a player clicks the wrong snack, enlarging when a snack is chosen, and glowing during active play, adds personality to each object and makes the interactions more satisfying. I also like how the red X sign briefly appears on a misclick before moving to the gameover state, it gives the player clear feedback without being overwhelming. For me, this section shows how I was able to combine logic and creativity: not just making the game functional, but adding expressive details that make it feel engaging and fun.

// Draw snacks with active animations
  for (let i = 0; i < snacks.length; i++) {
    const shaking = wrongIndex === i && wrongShakeFrames > 0;
    const enlarging = clickedSnack === i;
    const glowOnTop = enlarging && state === "play";
    snacks[i].draw(shaking, enlarging, glowOnTop);
  }
  if (wrongShakeFrames > 0) wrongShakeFrames--;

  // when showing a misclick, display the red X sign briefly then go to gameover
  if (state === "misclick") {
    if (wrongIndex >= 0 && xImg) {
      const s = snacks[wrongIndex];
      image(xImg, s.x + s.w / 2 - 30, s.y - 40, 60, 60);
    }
    misclickHold--;
    if (misclickHold <= 0) state = "gameover";
    return;
  }

 

Debugging 🙁

Debugging turned out to be one of the most challenging but also most important/ rewarding parts of this project. There were times when I stared at the same piece of code for hours and couldn’t see what was wrong, and I realized I needed fresh eyes, either by stepping away and taking breaks or by asking someone else to look at it with me. That process often helped me notice small mistakes I had been overlooking. The class we had last week on debugging strategies ended up being way more useful than I expected for a project of this size. It gave me practical techniques, like breaking problems into smaller parts and testing sections of the code separately, which saved me a lot of time and frustration.

Me when I find the bug after looking for hours, just to realize I had spelt the word “function” wrong:

Debugging 101 : r/ProgrammerHumor

Challenges and Areas for Improvement

One of the biggest challenges I ran into was learning how to use states (this made me want to cry), since I had never worked with them before. At first, it was confusing to manage the different phases of the game and make sure each part made sense (like the cover screen, instructions, and gameplay) and  transitioned smoothly. Over time, I began to understand how states could structure the flow and make the game easier to organize. Another challenge was finding traditional Emirati audio that felt authentic and added to the mood of the majlis setting. I wanted the sound to truly capture the atmosphere, so it took extra effort to search for the right oud tracks that matched the visuals and theme of the game.

For improvements, I would like to add more cultural depth to the game, such as different levels themed around other parts of Emirati hospitality or new backgrounds showing other Emirati cultural settings. Technically, the game could also benefit from smoother animations, for example, fading glows or a more creative transition between states and more positive feedback when a player levels up. While the core mechanics and atmosphere work well, as I learned in this course there is ALWAYS room to expand our games, wether that’s in terms of storytelling or even polishing the technical aspects. Overall, I’m very happy with how this turned out.