Assignment 2: For Art

This is my for-loop art piece: taking part of my love for geometric art and combining it with the coding techniques we were taught in class. I chose to be more abstract because my last piece was very portrait-like/ realistic and I wanted to experiment.

📋Assignment Brief

  • Use for() loops or while () loops
  • Use past learned coding techniques
  •  Make a simple work of art, inspired by old computer art magazines

💭Conceptualisation

The goal was to create dynamic geometric art, featuring rotating shapes that interact visually. The core concept revolved around three elements:

  • Rotating circles to create orbital motion
  • A radial pattern of triangles spinning collectively
  • A rotating grid of rectangles to add depth and complexity

The vision was to layer these elements while maintaining visual harmony. Early iterations included a spiral, but it was later removed to reduce clutter. The final design focused on symmetry, contrasting colors, and opposing rotational directions to create a hypnotic effect.

💻Process

I initialised the canvas, centered the coordinate system to the centre of the page, and set the angle mode to degrees for rotation control. I then created an off-axis rotating circle, positioned away from the centre. I used a for loop to distribute 10 triangles radially. Each triangle’s rotation used a fixed offset for simultaneous orbiting.

Next, I added a second circle rotating counterclockwise to create visual tension. I then implemented nested for loops to place rectangles in a grid. Each rectangle rotated with an angle for a shimmering backdrop. I used a translucent background to make a continuous motion trails.

I was the most proud of how I was able to make the grid of squares rotate and spin around. It took a lot of iteration but I was glad that I finally figured out how to make it rotate, and leave a trace.

// Additional Element: Rotating Grid of Rectangles 
  push();
    rotate(angle * 0.2);
    for (let x = -width / 2; x < width / 2; x += 80) 
    {
      for (let y = -height / 2; y < height / 2; y += 80) 
      {
        push();
          translate(x, y);
          rotate(angle);
          fill(255, 255, 0, 100);
          noStroke();
          rect(0, 0, 40, 40);
        pop();
      }
    }
  pop();

 

🚩Challenges

One significant challenge stemmed from managing coordinate transformations. Early versions of the code caused shapes to orbit erratically or appear static because rotations and translations were applied in the wrong order or without proper isolation. For instance, the triangles initially refused to spin because an outer rotate(-angle) transformation, intended to create a dynamic counter-rotation, inadvertently canceled out the individual rotations applied inside the loop.

Another challenge involved implementing opposing rotations for the two circles. Initially, both circles spun in the same direction, which diluted the intended visual contrast. Fixing this required applying rotate(-angle) to the second circle, but this also inverted its positional translation. By maintaining consistent translation distances (90 pixels) for both circles while inverting only the rotation, the symmetrical yet opposing motion was achieved.

📶Potential Improvements

We could enhance the artwork’s interactivity and visual appeal in several ways. Adding user-controlled parameters, like sliders to adjust rotation speeds or grid density, would allow viewers to interact with the piece directly. This could make the experience more engaging and personalized. Color dynamics present another exciting avenue for exploration. We might implement gradual transitions between different color schemes or incorporate noise-based gradients, creating more organic and fluid color shifts throughout the animation. These changes could significantly alter the mood and feel of the artwork.

For a more dramatic upgrade, we could venture into 3D space using p5.js’s WEBGL mode. This would add a new dimension to our geometric shapes, enabling them to orbit in layered planes or respond to perspective changes. It would transform the flat, 2D experience into a more immersive, depth-filled visual journey.

</>Source Code

GitHub Link: https://github.com/theSumeed/Assignment-2-For-Art/tree/main

Self Portrait Mohidul

 

Week 1: Self Portrait

Concept: Drawing a portrait that looks professional, wearing a suit.

 

Section I am proud of: Drawing the Suit of the Portrait.

// Draw suit
  fill(30); // Dark gray suit color
  beginShape(); // Left lapel
  vertex(140, 340);
  vertex(200, 280);
  vertex(180, 340);
  endShape(CLOSE);

New things I have learned drawing the suit:

//Vertex

Embedded sketch

Reflection: The hadest part was to start the project and aligning the dots and vertex well. So for next one, I will learn more on the coordinates system and have a paper on my hand before drawing it.

Assignment 1: Self Portrait

For my self portrait my intuition was to experiment with a style of art that is new to me. In this case I wanted to represent myself with a background of a dark star-lit sky. I always thought of the theory of existence, and as far as I know we are all representations of energy in the literal sense, with every form of life dependent on energy. Therefore, the distorted facial features are meant to blend into the background.

 

It is my first time using p5.js, and I am particularly proud of this line of code:

for (let i = 0; i < 200; i++) {
    fill(random(150, 255));
    ellipse(random(width), random(height), random(1, 4));
  }

It is a simple for loop that fills random parts of the background with stars, and I like seeing new representations of stars by repeatedly compiling the code. I tried to limit the use of functions and to instead use quadratic vectors to represent the rest of the elements of the portrait, which did bring about some difficulty. Looking forward, I will familiarize myself with the Quadratic Vector function, as well as other functions in p5.js .

Assignment 1: Portrait of Myself

This is my self-portrait, depicting me with some items of interest: two flags representing my ethnicity and nationality; gears depicting my love for engineering; and Yugioh cards showing my love for the game.

📋Assignment Brief

  • Make a self-portrait using p5.js using the online editor
  • The portrait must be entirely created using code
  • The portrait may be stylised and should be inspired by one’s character

💭Conceptualisation

I started the project by sketching elements that I identified with, things that resonated with who I am. I chose to highlight my flags, Yugioh cards, a paintbrush, and even a rough sketch of myself. I chose to use a very stylised, art style in order to play into the strengths of the software, hoping to recreate an almost vector-art look.

I then thought about features to implement. Despite not being taught any interactive elements just yet, I wanted to make my piece do something special. Hence, I made the eyes follow the user’s mouse. I achieved this through a combination of researching other people’s projects, YouTube, and Chat GPT.

💻Process

I worked on this project in chunks- isolating each component into an element that would need to be individually coded,  and then planning what tools I would need to use for it. I really enjoyed this as it taught me the thought process and planning needed for a piece like this- something completely new to me.

As I used many repeated elements, I was able to focus on creating a singular good piece and then just translate the element into the other areas it’s needed.

I felt particularly proud that I was able to code the moving eyes: I had to research how different features worked, create and effectively use variables, and had to think through logic to ensure it moved the eyes correctly. This was all iterative, I had to stop and re-try many times but was able to manage in the end.

//Eyes
 fill(256); //Set the fill colour to white
   rect(285, 375, 45, 50, 17);
   rect(370, 375, 45, 50, 17);
   rect(285, 400, 45, 25, 3);
   rect(370, 400, 45, 25, 3);
 noFill(); // Disable the fill colour

 
 // Eye variables
 let leftEyeX = 310; // Left eye X position
 let rightEyeX = 395; // Right eye X position
 let eyeY = 400; // Both eyes Y position
 let eyeSize = 40; // Size of outer eye circles
 let pupilSize = 25; // Size of pupils

 // Calculate pupil positions for both eyes
 for (let eyeX of [leftEyeX, rightEyeX]) 
 {
   let dx = mouseX - eyeX;
   let dy = mouseY - eyeY;
   let angle = atan2(dy, dx);

   // Limit pupil movement
   let maxDistance = (eyeSize - pupilSize) / 4;
   let distance = min(dist(eyeX, eyeY, mouseX, mouseY), maxDistance);

   // Calculate and draw each pupil
   let pupilX = eyeX + cos(angle) * distance;
   let pupilY = eyeY + sin(angle) * distance;

   fill(56, 16, 28); //Set the fill colour to brown
     circle(pupilX, pupilY, pupilSize);
   noFill(); // Disable the fill colour
 }

🚩Challenges

Creating the moving eyes were a tad difficult because this uses a lot of knowledge that we have not yet learned in class. However, I was able to look at past projects and use the internet to self-teach how it works. The Pakistani flag was rather tedious, too, as I had to research how to make a star shape and use another new feature. Additionally, the new coordinate system was rather strange. I had to adjust to using the downwards is positive mindset, but it became easy after I introduced a temporary mouse tracker- using the software’s mouseX and mouseY features.

📶Potential Improvements

To improve, I would use more variables so that my portrait may be scaled to whatever size the canvas is. This would allow the portrait to keep a high resolution despite being scaled up or down. Additionally, I could introduce a clicking feature, something where an element on the screen would change every time I click it. This introduces a sense of whimsy and fun that I identify with.

</>Source Code

GitHub Link: https://github.com/theSumeed/Self-Portrait

 

 

FINAL PROJECT – GOAL RUSH

CONCEPTS:

The game is a fast-paced, reaction-based experience inspired by the Speed Light Reaction Game, which I transformed into something I’m passionate about: football. The game requires players to quickly respond to an LED light by pressing the correct button. If they react correctly, they score a goal, but if they miss or press the wrong button, the ball hits a mannequin, simulating a failed attempt. The game incorporates visual and auditory feedback, a playlist of music inspired by FIFA, and a timer to create an engaging and immersive experience that challenges players’ speed and reaction time.

IM SHOW:

IMG_1736 2

IMG_1734 2

USER TESTING:

user_testing (1)

THE GAME:

the button (the control)-

the layout

the instruction page

the game play page

P5 SKETCH:

SETUP:

How does the implementation work?

The game uses Arduino and p5.js software for an interactive experience.

  1. Hardware (Arduino):
    • LED button lights serve as control, which lights up signaling which button to press to score, allowing user input.
    • Serial communication sends user responses from the Arduino to P5.js.
  2. Software (p5.js):
    • Manages game visuals, including the football, goal, and mannequins.
    • Tracks scores, missed shots, and the countdown timer.
    • Plays music and sound effects to immerse players in the experience.

INTERACTION DESIGN

  • Title Screen:
    • Features:
      • Displays the game title with an bold font.
      • Includes buttons for “Start Game”, “Instructions” and “shuffle – play/pause” for music.
    • Design Choices:
      • Used bold colors and a clean layout for clarity and visual appeal.
    • Gameplay:
      • Press the matching led button that lights up to score.
      • Correct button presses make the ball move toward the goal, simulating a successful shot.
      • Incorrect or missed presses (not pressed within 1 sec) result in the ball hitting a mannequin, simulating a failed shot.
      • Additional on-screen buttons allow players to shuffle music or play/pause background tracks.
    • Feedback: The game uses visual (ball movement) and auditory (goal or miss sounds) feedback. Background music inspired by FIFA enhances the immersive experience
  • End Screen:
    • Displays the final score and missed attempts.
    • Includes buttons to restart the game or return to the main menu

DESCRIPTION OF P5.JS CODE:

The p5.js sketch manages the visuals, sounds, and game state.

  1. Key Features:
    • Dynamic Visuals: Updates scores, displays animations for goals and misses, and tracks time.
    • Audio Feedback: Plays sound effects for scoring and missing.
    • Serial Data Handling: Receives and processes data from Arduino.
  2. Code Snippets:
    • Serial Data Handling:
function readSerial(data) {
  if (data === "BUTTON:CORRECT") {
    score++;
    // Animate football to the goal
  } else if (data === "BUTTON:WRONG") {
    missedShots++;
    // Animate football to the mannequin
  }
}
  • Music Control:
function toggleMusic() {
  if (isMusicPlaying) {
    backgroundSounds[currentTrackIndex].pause();
    isMusicPlaying = false;
  } else {
    backgroundSounds[currentTrackIndex].play();
    isMusicPlaying = true;
  }
}

DESCRIPTION OF ARDUINO CODE:

The Arduino code handles LED prompts, button detection, and serial communication with p5.js.

Key Components:

  1. LED Control:
    • LEDs light up randomly, prompting user action:
void lightUpLED(int index) {
  for (int i = 0; i < 3; i++) {
    digitalWrite(ledPins[i], (i == index) ? HIGH : LOW);
  }
}
  • LEDs turn off after a button is pressed or the timeout ends:
void turnOffLEDs() {
  for (int i = 0; i < 3; i++) {
    digitalWrite(ledPins[i], LOW);
  }
}

Button Detection:

  • Checks if the correct button is pressed:
void checkButtonPress() {
  if (targetLED != -1 && digitalRead(buttonPins[targetLED]) == LOW) {
    Serial.println("BUTTON:CORRECT");
    targetLED = -1; 
    turnOffLEDs();
  } else {
    for (int i = 0; i < 3; i++) {
      if (i != targetLED && digitalRead(buttonPins[i]) == LOW) {
        Serial.println("BUTTON:WRONG");
        targetLED = -1; 
        turnOffLEDs();
        break;
      }
    }
  }
}

Serial Communication:

  • Sends formatted data to p5.js:
void sendLEDSignal(int ledIndex) {
  Serial.print("LED:");
  Serial.println(ledIndex);
}

Listens for responses from p5.js:

if (Serial.available()) {
  String command = Serial.readStringUntil('\n');
  if (command.startsWith("LED:")) {
    targetLED = command.substring(4).toInt();
    lightUpLED(targetLED);
  }
}

COMMUNICATION BETWEEN P5 AND ARDUINO:

How It Works:

  • Arduino sends data about user responses (correct or wrong button presses) to p5.js.
  • p5.js uses this data to update the game state:
    • Correct responses move the football to the goal and increase the score.
    • Incorrect responses move the football to a mannequin and increase missed attempts.
  • p5.js also sends signals back to Arduino to light up LEDs.

Challenges Overcome:

  • Initial miscommunication due to overlapping signals was resolved by implementing a debounce delay in Arduino and validation logic in p5.js.

CHALLENGES FACED:

One major challenge was managing communication between Arduino and p5.js. Initially, multiple data packets were sent for a single button press, causing disruptions in the game. To fix this, I added a debounce delay in the Arduino code:

if (magnitudeG > impactThreshold) {
  Serial.print("BUTTON:CORRECT");
  delay(200); // Debounce to avoid multiple signals
}

This ensured only one signal was sent per button press. I also validated inputs in p5.js by processing only expected packets like "BUTTON:CORRECT", which resolved signal misinterpretations.

Another challenge was ensuring strong soldering connections for the buttons and LEDs. My first attempts were unreliable, but then I secured the connections, improving hardware stability.

WHAT IM PROUD OF:

I’m proud of successfully integrating Arduino and p5.js to create a smooth and responsive game. Features like the animated football, scoring system, and FIFA-inspired music enhanced the user experience. Solving technical issues, such as serial communication and soldering, was rewarding, as they significantly improved the gameplay experience.

FUTURE IMPROVEMENTS:

One improvement would be adding a game mode where pressing the correct button contributes to building a beat or rhythm for a song. Each correct button press would play a specific musical note or drum beat, gradually creating a complete soundtrack as the player progresses. This mode would combine the fast-paced reaction element with creativity, making the game more dynamic and engaging. By turning gameplay into a musical experience, it would appeal to a broader audience and add a unique layer of interactivity. This feature could also include different difficulty levels, where faster reactions create more complex beats, challenging players’ skills and rhythm simultaneously.

RESOURCES USED:

https://www.instructables.com/Plug-and-Play-Arcade-Buttons/

https://editor.p5js.org/jps723/sketches/Byvw1lu6Z

 

 

FINAL PROJECT- THE PUNCHING BAG

CONCEPT:

The Punching Bag Game is an interactive project that combines physical activity with a digital arcade experience. The concept revolves around using a punching bag equipped with a sensor to detect punches and display real-time scores. It’s designed to bring the excitement of a classic arcade game into a physical activity, which inspired me in the first place. The game includes features like score tracking, a fuel bar, sound effects, and a visually engaging gamescreen that responds to the user’s actions. The goal is to create an immersive experience where users can engage physically while enjoying a fun and competitive game.

user testing video

Here is where I placed the sensor on the punching bag:
THE PUNCHING BAG- sensor placment

How Does the Implementation Work?

The project integrates hardware (Arduino) and software (p5.js) to create a seamless interactive system:

Hardware (Arduino):

  • An ADXL335 accelerometer attached to the punching bag detects the magnitude of punches.
  • An arcade button starts and restarts the game.
  • The Arduino processes the sensor data and sends it to p5.js as a formatted packet.

Software (p5.js):

  • Displays the title screen, instructions, and gameplay.
  • Dynamically updates the score, best score, and fuel bar based on incoming data.
  • Plays sound effects and animates the punching bag for a realistic experience.

Description of Interaction Design

1. Title Screen

Features:

    • The game title (“The Punching Bag”) in an arcade-style font.
    • An “Instructions” button leads to a detailed instruction page.
    • A prompt directs users to press the arcade button to start the game.

Design Choices:

      •  I used bold, retro fonts and a simple overall design to mimic an actual arcade game.

2. Gameplay

  • User Interaction:
    • Players punch the bag, and the accelerometer calculates the strength.
    • Scores are displayed dynamically, increasing gradually like in classic arcade games.
    • A fuel bar at the bottom fills based on the user’s performance.
    • Sound effects play after each punch.
  • Visual Elements:
    • The punching bag vibrates after each punch, mimicking the actual punching bag
    • A restart button allows players to reset the game and try again.

3. Restart Button

  • After the game ends, users can press the restart button to reset the game and clear all scores, unlocking the ability to punch again.

Description of Arduino Code

The Arduino is responsible for detecting punches, processing the sensor data, and communicating with p5.js.

How It Works:

  1. Punch Detection:
    • The ADXL335 accelerometer calculates the acceleration magnitude of each punch.
    • If the magnitude exceeds a set threshold, it’s mapped to a score value.
  2. Data Transmission:
    • The Arduino sends a data packet in the format ,:<value> to p5.js via serial communication.
  3. Button Functionality:
    • The arcade button sends a “START” signal to p5.js to initiate gameplay.
void handleAccelerometer() {
  int xRaw = analogRead(xPin);
  int yRaw = analogRead(yPin);
  int zRaw = analogRead(zPin);

  float magnitudeG = calculateMagnitude(xRaw, yRaw, zRaw);

  if (magnitudeG > impactThreshold) {
    int punchValue = map(magnitudeG, impactThreshold, impactThreshold + 10, 0, 2000);
    Serial.print(",:");
    Serial.println(punchValue);
    delay(200);
  }
}

GITHUB

 

Description of p5.js Code

The p5.js sketch displays the visuals and processes incoming data from the Arduino to create a responsive and interactive experience.

Key Features:

  1. Dynamic Visuals:
    • Real-time updates to the score and fuel bar.
    • Vibration animation for the punching bag.
  2. Audio Feedback:
    • Plays sound effects after each punch.
  3. Serial Data Handling:
    • receives incoming data and updates the game state.
function handleSerialData(data) {
  serialBuffer += data; // Add incoming data to the buffer

  // Check for complete packets
  let startMarker = serialBuffer.indexOf("<");
  let endMarker = serialBuffer.indexOf(">");
  if (startMarker !== -1 && endMarker > startMarker) {
    let packet = serialBuffer.substring(startMarker + 1, endMarker); // Extract packet
    serialBuffer = serialBuffer.substring(endMarker + 1); // Remove processed packet

    // Process the packet
    if (packet.startsWith(",:")) {
      let scoreValue = parseInt(packet.substring(2)); // Extract score value
      if (!isNaN(scoreValue)) {
        console.log("Score received:", scoreValue);
        if (!scoreLocked) {
          score = scoreValue;
          fuel = constrain(fuel + scoreValue / 10, 0, 100);
          bestScore = max(bestScore, score);
          scoreLocked = true;
           isVibrating = true; 
        vibrationTimer = 80; 

        // Play punch sound
        if (roundEndSound.isPlaying()) {
         roundEndSound.stop(); 
        }
      roundEndSound.play(); 
        }
      }
    } else if (packet === "START") {
      gameState = "game";
    }
  }
}

 

COMMUNICATION BETWEEN ARDUINO AND P5.JS:

he communication between Arduino and p5.js is essential for the game to function properly, allowing the physical punches on the bag to reflect accurately in the digital interface. When the punching bag is hit, the ADXL335 sensor attached to it measures the force of the punch in terms of acceleration along the x, y, and z axes. The Arduino processes these raw sensor values and calculates the overall magnitude of the punch. If the punch strength exceeds a preset threshold, the Arduino sends a data packet to p5.js in the format ,:<value>, where <value> is the calculated punch strength mapped to a score range which was 2500. In addition to handling the punches, the Arduino also manages the arcade button. When the button is pressed, it sends a “START” command to p5.js. On the title screen, this command transitions the game to the gameplay state, and during gameplay, it acts as a reset function, clearing the scores and unlocking the ability to punch again. On the p5.js side, the sketch listens for incoming data through serial communication. When data is received, it first checks if it matches the  format to avoid any invalid or incomplete packets. Once validated, p5.js takes the score from the data and updates the game elements, such as the score display, fuel bar, and sound effects. To prevent multiple scores from being processed for a single punch, p5.js locks the score after the first valid data packet and ignores any further updates until the game is restarted.

CHALLENGING ASPECTS AND WHAT IM PROUD OF:
Getting the communication between Arduino and p5.js to work was one of the biggest challenges, but I got it to work in the end woohooo!. At first, the Arduino sent multiple data packets for a single punch, causing issues in p5.js, but I fixed this by adding a debounce delay and structuring the data packets. Soldering was also frustrating at first as it was my first time, and the wires kept coming loose. After several attempts, I managed to secure the connections, ensuring the sensor and button worked properly.

AREAS FOR FUTURE IMPROVEMENT:

I believe I could have maybe made the game more interactive by adding different game modes, maybe like a mode where there’s a timer and the user has to keep punching to fill up the fuel bar within that certain time. So in general, adding more features to the game would have been great.

 

IM SHOW

USER TESTIG – PROGRESS

PROGRESS:

Over the course of the project, I encountered several challenges, particularly with the hardware and data communication between the Arduino and p5.js. Initially, the score wasn’t sending correctly from the Arduino to p5.js. The issue was from the fact that the data being sent was triggered by every impact, causing the Arduino to send multiple data quickly, one after the other. This resulted in incomplete or overlapping data being received in p5.js.

To resolve this, I modified the Arduino code to send data in separate packets. It now sends only one score value per impact and ignores any other impacts until the restart button is pressed. This solution ensured that p5.js received clean and complete data, allowing the game to function as intended.

On the hardware side, securing the sensor to the punching bag was also tricky. The sensor kept shifting due to the force of punches, which required me to reattach it multiple times. I also had to redo the wiring and soldering to ensure the connections were stable and durable during testing. Another adjustment involved adding water to the punching bag base, which I had initially removed, as the bag became unstable during heavy use.

The overall p5.js sketch is now complete. It includes a functional title screen, instruction menu, and gameplay with features such as dynamic scoring, a fuel bar, and a restart button. I used an arcade font for all the text to maintain a cohesive theme, and the punching bag’s vibration and animation added a realistic touch to the game. The game also plays sound effects after each punch, adding to the immersive experience.

USER TESTING:

During user testing, the instructions were clear, and players easily understood how to start the game. However, one recurring issue was the instability of the punching bag due to the lack of water in the base. Once I added water, the problem was resolved, and users could play without interruptions.

Another key observation was the need to test the sensor with punches of varying strengths. Users with stronger punches sometimes triggered unexpected behaviors in the scoring system. This helped me fine-tune the sensitivity of the sensor, ensuring accurate calculations regardless of punch strength. I used AI assistance to determine the optimal sensitivity settings and a built-in math file in Arduino to calculate the results from the data.

Feedback from users also highlighted that the gameplay felt smooth, and they appreciated the arcade-like visual and audio elements. The scoring system and the gradual increase of the score display were well-received, as they mirrored the pacing of arcade games. Overall, the changes I implemented addressed the main issues, and the game is now ready for final polishing.

USER TESTING VIDEO

Final Project Documentation

Catch the horse: In Action

Schematic:

Circuit Design

The circuit design includes:

  • Inputs:
    • Buttons for Jump, Rock, Bird, and Choice.
    • Ultrasonic sensor for crouching detection.
  • Outputs:
    • Servo motor for mechanical horse movement.

Circuit Setup:

Concept: 

“Catch the Horse” is an interactive, physically engaging game that combines a physical mechanical horse with a virtual environment. The game revolves around a man running after a horse, dodging obstacles, and strategising to catch the runaway animal. Using Arduino for hardware control and p5.js for the game logic, the project merges physical and digital interactivity in a seamless experience.

The game is designed for a single player or multiplayer to interact with both the physical and digital world, utilising buttons, sensors, and a motor to create a truly immersive gameplay environment.

Implementation Overview

The implementation is divided into two main components:

  1. Hardware (Arduino): Controls the physical setup, including buttons for gameplay interactions, an ultrasonic sensor for crouching detection, and a motor for the mechanical horse.
  2. Software (p5.js): Manages the game logic, animations, audio feedback, and communication with the Arduino.

Interaction Design

The player interacts with the game through a combination of physical actions and button presses:

  • Jump Button: Press to make the man jump over obstacles like rocks.
  • Rock Button: Press to launch rocks as obstacles for the man.
  • Bird Button: Press to release birds, which the man must dodge.
  • Lasso Button (Choice Button): Triggers a Choice Screen where the player selects between Skill and Luck to catch the horse.
  • Crouching: The ultrasonic sensor detects when the player crouches to avoid fences.

The game starts with a running man chasing a horse. Players must navigate these challenges to achieve victory. Victory conditions include successfully throwing the lasso and either rolling a winning dice number (Luck) or capturing the horse via a precise throw (Skill).

Arduino Code

The Arduino code serves as the bridge between the physical components and the digital game. Key features include:

  • Button Mapping: Jump, Rock, Bird, and Choice buttons are connected to Arduino pins, triggering serial communication to p5.js.
  • Ultrasonic Sensor Integration: Detects crouching and sends the signal to the game.
  • Motor Control: Starts and stops the physical horse motor based on game states.

The final Arduino sketch was robust and efficient, thanks to iterative improvements. One notable challenge was integrating the button connected to pin 5 (Choice Button) to handle multiple game states effectively. Solving this required careful adjustments to both Arduino and p5.js logic.

p5.js Code

The p5.js script handles the game logic, animations, and audio. Key highlights include:

  • Game States: Playing, Choice Screen, Game Over, and Game Won states dynamically adjust gameplay.
  • Animations: The running man and birds are controlled via sprite animations, providing a polished visual experience.
  • Audio Integration: Background music tracks play during specific game states (ninja.mp3 during Playing and horse.mp3 during Game Won), enhancing immersion.
  • Obstacle Logic: Rocks and birds have cooldowns to maintain game balance.

The most challenging part was ensuring smooth communication between the Arduino and p5.js. For example, handling simultaneous button presses and sensor inputs required careful synchronisation to avoid bugs.

You can try the game here:

 

Final Project; Pengu Pounce

Pengu Pounce — IT’S OVER!

I am ECSTATIC to say that I am finally done with this project! It has certainly been a dynamic experience.

As I had proposed, I thought of incorporating one of my favorite things ever into my final project –  my love for penguins. Therefore, I decided to create a fun little game where a Penguin called Pengu, has to jump over platforms — inspired by the Doodle Jump game. 

A lot has changed since my previous User Proposal, as my idea now is fully fleshed out/ In terms of the game itself, the primary objective is for Pengu to hop on different platforms till the timer ends — the person is supposed to last sixty seconds in the game. If the penguin falls off – then they lose.

In terms of the physical implementation, this game has four buttons: Restart, Left, Right, and Jump. 

There are several challenges I faced, most of them mainly to do with the game itself rather than the arduino.

For example, I was struggling with generating the actual platforms for the penguin to jump on. After I added the special ‘disappear’ platforms, it felt like the screen was being overcrowded. In addition, sometimes, the penguin would start on a disappear platform and therefore lose the game immediately,  so I decided on a set of three  normal platforms for the penguin to jump on at the start of the game. 

I also had struggled with making the platforms disappear once the penguin moved up, and ,make new ones appear. However, my friend had taught me about a handy concat built in function and filter, and as well as the spread operator, which I actually ended up finding useful and using it here now.

<iframe src=”https://editor.p5js.org/zv2029/full/otoQ9nLsh”></iframe>

Here is a link my complete p5.js sketch: https://editor.p5js.org/zv2029/sketches/otoQ9nLsh

Here is my code for the Arduino IDE that I used: 

 

const int jumpButtonPin = 10; // Button for jump
const int leftButtonPin = 13; // Button for move left
const int rightButtonPin = 4; // Button for move right
const int restartButtonPin = 2; // Button for restart

void setup() {
  pinMode(jumpButtonPin, INPUT_PULLUP);
  pinMode(leftButtonPin, INPUT_PULLUP);
  pinMode(rightButtonPin, INPUT_PULLUP);
  pinMode(restartButtonPin, INPUT_PULLUP); 
  Serial.begin(9600);
}

void loop() {
  // Read button states
  int jumpState = digitalRead(jumpButtonPin);
  int leftState = digitalRead(leftButtonPin);
  int rightState = digitalRead(rightButtonPin);
  int restartState = digitalRead(restartButtonPin);


  if (jumpState == LOW) {
    Serial.println("JUMP");
  } else if (leftState == LOW) {
    Serial.println("LEFT");
  } else if (rightState == LOW) {
    Serial.println("RIGHT");
  } else if (restartState == LOW) {
    Serial.println("RESTART");
  } else {
    Serial.println("IDLE"); 
  }

}

Here is a video of the game being played:

 

Assignment 10: Testing Phase

Title: Testing Phase of “Catch the Horse” – Insights and Improvements

With the development of “Catch the Horse” completed, I conducted user testing to evaluate the intuitiveness, playability, and overall experience of the game. The goal of this phase was to observe how players interacted with the game, identify areas where they struggled, and determine how the gameplay mechanics could be made more intuitive and accessible.

User Testing Overview

During testing, participants were asked to engage with the game without receiving any prior instructions or guidance. The goal was to simulate the experience of a first-time player encountering the game. I recorded their interactions and noted points of confusion, questions they asked, and their overall feedback.

Observations and Findings

  1. What Users Figured Out on Their Own
    • Jump, Bird, and Rock Buttons:
      Players intuitively understood the jump mechanic and the functions of the bird and rock buttons. These actions had immediate visual feedback (e.g., the cowboy jumped, birds appeared, or rocks were thrown), which made the controls feel natural and responsive.
  2. What Needed Explanation
    • Lasso Button (Choice Button):
      Players struggled to understand how the lasso button worked. I had to explain that pressing the lasso button initiated the “Choice Screen” and that they could select between Skill or Luck to catch the horse.

      • Skill vs. Luck:
        The difference between the Skill and Luck options was unclear without explanation. Participants were unsure why they would choose one option over the other.
  • Interaction with Rocks and Birds:
    Although players understood how to use the rock and bird buttons, they were initially confused about how the cowboy was supposed to interact with these obstacles. For example, they weren’t sure if the rocks could be dodged or destroyed and if the birds required a specific action to avoid.

    What Worked Well

  • Physical Integration:
    The physical crouching mechanic, detected by the ultrasonic sensor, added an engaging and immersive element to the game. Users enjoyed the novelty of having to physically move to interact with the game.
  • Visual Feedback:
    Immediate visual feedback for the jump, bird, and rock mechanics allowed players to quickly understand these actions without explanation.
  • Game Flow and Balance:
    Cooldowns for the horse’s abilities (mud, fences, and booster) were well-received, as they maintained a fair and balanced gameplay experience.

    Lessons Learned

    • Mapping Between Controls and Gameplay:
      Intuitive mapping between controls and gameplay actions is critical. For example, the jump button and crouching were easy to grasp because the controls directly mirrored the in-game actions. However, abstract mechanics like the lasso required additional explanation due to their more complex interactions.
    • The Importance of Feedback:
      Immediate feedback helped players connect their actions to in-game effects. Enhancing feedback for less intuitive mechanics (like the lasso) will likely make the game easier to pick up.
    • Balancing Physical and Digital Gameplay:
      Players found the integration of physical actions (like crouching) and digital gameplay highly engaging. This balance between physical and virtual interaction should remain a cornerstone of the game’s design.

      Next Steps

      1. Add an Instructions Page or Tutorial:
        Include a brief tutorial or instructions page at the beginning of the game to explain the mechanics of the lasso button, Skill vs. Luck, and how to interact with obstacles like birds and rocks.
      2. Enhance In-Game Prompts:
        Add dynamic text prompts or animations during gameplay to guide players through challenging mechanics. For example:

        1. “Press J to Jump Over Rocks!”
        2. “Dodge Birds to Avoid Game Over!”

    Demonstration