Final project proposal

For my final project I propose to transform the conventional game ‘The Mole’ by incorporating force sensors into an Arduino setup. My goal is to enhance gameplay by introducing a tangible, hands-on interaction using force-sensitive sensors. I envision players engaging with a physical setup, detecting and responding to varying force levels to navigate through game challenges. By fusing classic gameplay with sensor technology, I aim to create an immersive and innovative gaming experience that redefines interaction in gaming environments. This project represents my aspiration to merge traditional entertainment with modern tech, offering players a novel way to engage with ‘The Mole.

I am excited

week 11- reading reflectiom – design meets disability

This book about the collaboration between the Eameses and their creation of leg splints for veterans is a profound exploration of how design transcends its conventional boundaries. What’s truly fascinating is their approach—they didn’t just aim for practicality in their design; they sought to blend functionality with aesthetic appeal.

What’s really interesting is how deeply they considered the human aspect. The Eameses didn’t limit their focus to the technicalities; they delved into the emotional and experiential dimensions of their design. They wanted these splints to not only serve their purpose but also uplift the users’ spirits, ensuring comfort and a sense of dignity.

Their emphasis on inclusive design is remarkable. They didn’t want these splints to be exclusive; they envisioned them as tools accessible to all, irrespective of abilities. It’s a profound statement about the importance of ensuring good design is available universally.

The core message resonating here is that design isn’t just about appearances; it’s about functionality and the impact it has on people’s lives. The Eameses’ venture with these leg splints is a testament to how empathetic design can significantly enhance lives and contribute to a more equitable and inclusive society.

Series Connection

overview:

In this assignment, I worked with Fady John to achieve the three exercises in class

Exercise 1:

p5 js

let left = 0;

function setup() {
  createCanvas(400, 400);
}

function draw() {
  background(220);
  fill("red");
  ellipse(left, 50, 50, 50);
}

function keyPressed() {
  if (key == " ") {
    // important to have in order to start the serial connection!!
    setUpSerial();
  }
}

function readSerial(data) {
  left = map(data, 0, 1023, 0, 400);
}

Arduino:

//// Arduino Code
/*

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);

}

void loop() {
  // put your main code here, to run repeatedly:
  int sensor = analogRead(A0);
  delay(5);
  Serial.println(sensor);

}

*/

Exercise 2:

P5 js

let brightnessSlider;
let brightnessValue = 0;

function setup() {
  createCanvas(400, 200);

  // Create a brightness slider
  brightnessSlider = createSlider(0, 255, 128);
  brightnessSlider.position(width/2-50, height/2);
  brightnessSlider.style('width', '100px');
}

function draw() {
  background(255);

  // Get the brightness value from the slider
  brightnessValue = brightnessSlider.value();
}

function keyPressed() {
  if (key == " ") {
    // important to have in order to start the serial connection!!
    setUpSerial();
  }
}

function readSerial(data) {
  console.log(data);
    let dataToSend = brightnessValue + ", \n";
    writeSerial(dataToSend);  
}

Arduino:

///Arduino COde
/*

const int ledPin = 9;  // Digital output pin for the LED

void setup() {
  pinMode(ledPin, OUTPUT);

  // Start serial communication
  Serial.begin(9600);
}

void loop() {
  Serial.println("sensor");
  // Check if data is available from p5.js
  if (Serial.available() > 0) {
    // Read the brightness value from p5.js
    int brightness = Serial.parseInt();

    // Map the received value to the LED brightness range
    brightness = constrain(brightness, 0, 255);

    // Set the LED brightness
    analogWrite(ledPin, brightness);
  }
}

*/

Exercise 3:

P5 js

let velocity;
let gravity;
let position;
let acceleration;
let wind;
let drag = 0.99;
let mass = 50;
let led = 0;

function setup() {
  createCanvas(640, 360);
  noFill();
  position = createVector(width/2, 0);
  velocity = createVector(0,0);
  acceleration = createVector(0,0);
  gravity = createVector(0, 0.5*mass);
  wind = createVector(0,0);
}

function draw() {
  background(255);
  applyForce(wind);
  applyForce(gravity);
  velocity.add(acceleration);
  velocity.mult(drag);
  position.add(velocity);
  acceleration.mult(0);
  ellipse(position.x,position.y,mass,mass);
  if (position.y > height-mass/2) {
      velocity.y *= -0.9;  // A little dampening when hitting the bottom
      position.y = height-mass/2;
  }
  if(position.y == height-mass/2 && (velocity.y > 0.5 || velocity.y < -0.5)){ 
    led = 1;
  }else{
    led = 0;
  }
}

function applyForce(force){
  // Newton's 2nd law: F = M * A
  // or A = F / M
  let f = p5.Vector.div(force, mass);
  acceleration.add(f);
}

function keyPressed(){
  if (key == "n") {
    // important to have in order to start the serial connection!!
    setUpSerial();
  }
  if (key==' '){
    mass=random(15, 80);
    position.y=-mass;
    velocity.mult(0);
  }
}

function readSerial(data) {

  if (data != null) {
    // make sure there is actually a message
    // split the message
    wind.x = data;

    //////////////////////////////////
    //SEND TO ARDUINO HERE (handshake)
    //////////////////////////////////
    let sendToArduino = led + "\n";
    writeSerial(sendToArduino);
  }
}

Arduino:

///Arduino COde

/*

int ledPin = 9;

void setup() {
  // Start serial communication so we can send data
  // over the USB connection to our p5js sketch
  Serial.begin(9600);
  pinMode(ledPin, OUTPUT);
}

void loop() {
  int sensor = analogRead(A0);
  int wind = map(sensor, 0, 1023, -2, 2);
  Serial.println(wind);
  delay(10);
  if (Serial.available() > 0) {
    // Read the brightness value from p5.js
    int touch = Serial.parseInt();
    // Set the LED brightness
    digitalWrite(ledPin, touch);
  }
}
*/

BOUNCING BALL VIDEO

exercise3 week11

Noctune Noir Week 10

Group Members: Batool Al Tameemi, Arshiya Khattak

Concept: For this project, we knew we wanted to implement something piano-esque, i.e. pressing buttons and implementing different sounds. Essentially, it is a simple Arduino circuit that uses three buttons and a buzzer, playing a note every time a button is pressed. However, we wanted to make the concept a little more fun, so we decided to add a photocell (it was also a cool way to add more notes than just 3). When the photocell is uncovered, the buttons play higher frequency notes (A flat, G, and F) and when it’s covered, it plays lower frequency sounds (D, C, and B). The idea is in daylight the keys play more upbeat-sounding tones, while at night they make more sombre-sounding noises.

Video & Implementation

 

TinkerCad Diagram:

The code for this project was relatively straightforward. The frequency equivalent in Arduino for the notes were taken from this article.

int buzzPin = 8;
int keyOne = A1;
int keyTwo = A2;
int keyThree = A5;
int lightPin = A0;
int brightness = 0;
int keyOneState, keyTwoState, keyThreeState;

int flexOneValue;

void setup() {
  Serial.begin(9600);
}

void loop() {
  brightness = analogRead(lightPin);
  keyOneState = digitalRead(keyOne);
  keyTwoState = digitalRead(keyTwo);
  keyThreeState = digitalRead(keyThree);
  Serial.println(brightness);
  if (brightness < 45) {
    if (keyOneState == HIGH) {
      // tone(buzzPin, 262);
      playTone(587); //D flat
    } else if (keyTwoState == HIGH) {
      playTone(523); //C
    } else if (keyThreeState == HIGH) {
      playTone(494);
    }
  } else {
    if (keyOneState == HIGH) {
      // tone(buzzPin, 1000, 400);
      playTone(831); //A
    } else if (keyTwoState == HIGH) {
      playTone(784); //G
    } else if (keyThreeState == HIGH) {
      playTone(698);
    }
  }
}


void playTone(int frequency) {
  int duration = 200;
  tone(buzzPin, frequency, duration);
  delay(duration);
  noTone(buzzPin);
}

Future Highlights and Improvements

One thing that we both thought would be cool to implement on a longer form of this project would be to have different levels of brightness play different notes, rather than just having two states. It would also be cool to incorporate different forms of input, such as the flex sensor (we tried to use it but it was a bit buggy so we scrapped the idea).

Reading reflection week 10

A breif Rant on the Future of interactive media

The reading on future interfaces was mind-blowing! It was like someone suddenly turned on a light in a room I’d been sitting in for ages, and suddenly, everything made sense in a completely new way.

The author of this reflection, wow, they had been in the thick of designing future interfaces. Real prototypes, not just concepts. That’s a level of hands-on experience few people get. It’s like being backstage at a magic show and seeing how the tricks are really done.

Their beef with the video wasn’t about nitpicking interactions but about the vision itself. It wasn’t bold enough, not enough of a leap from the mess we’re dealing with in the present. And I get that! Visions should inspire, not just be a ho-hum “yeah, that’ll do” kind of thing.

But what really hit me was the talk about our hands. Hands are amazing! I mean, we use them constantly, but do we ever really think about how intricate they are? They’re like the Swiss Army knives of our bodies. Feeling things, manipulating objects—our hands are our interface with the world.

The idea of “Pictures Under Glass” really got to me. It’s like we’re willingly giving up the richness of touch for the sake of a fancy visual. The comparison to tying shoelaces with closed eyes hit home. We’re prioritizing sight over touch, but in reality, touch is the real MVP in how we interact with things.

The rant about the gestures we use with our fingers blew my mind. The fact that we switch between different grips without even thinking about it—opening a jar, for instance—showed how intuitive our interactions really are. Our hands are built for a three-dimensional world, for manipulating objects in ways that no other creature can. It’s like a superpower we take for granted every day!

And the call to action at the end was so powerful. The future isn’t predetermined; it’s a choice. It’s up to us to push for better interfaces, ones that harness the full potential of what our bodies can do. Why settle for a single finger when we have this incredible body that can do so much more?

What do I think about the Follow up

It’s like the author just dropped a knowledge bomb and left me reeling with thoughts and arguments ricocheting around my head.

The responses they received were a mix of understanding and misconceptions. The author wasn’t seeking to solve the problem outright; they wanted to spark curiosity and inspire researchers to delve into unexplored territories. The idea was to lay down the issue and hope it would catch the eye of the right people who could initiate the necessary research. That’s a pretty bold move!

The analogy about technology evolution using Kodak’s camera was spot on. The iPad, like the black-and-white camera, is groundbreaking, but it’s clear something’s missing. The push should be towards a dynamic tactile medium, not just a flat, glassy screen with minimal haptic feedback.

Their take on voice interfaces was refreshing. While acknowledging the importance of voice, especially for certain tasks, they stressed the limitations when it comes to creation and deep understanding. Explorable environments, where you can physically manipulate things, seem like the real deal.

The exploration of gestural interfaces was intriguing. From discrete abstract gestures to waving hands in the air, each had its pros and cons, but none seemed to fully harness the potential of our hands and bodies in a three-dimensional world.

The part about brain interfaces hit hard. Why are we trying to bypass our bodies altogether? It’s like saying our bodies are inadequate for the digital age. It’s a bold reminder to adapt technology to suit our natural capabilities rather than forcing ourselves to adapt to it.

The quote about fingertips and their importance for development resonated deeply. It’s like saying if we don’t use certain faculties, we lose them. The comparison to limiting literature to Dr. Seuss for adults is both humorous and thought-provoking.

And the clever redirect about the length of the rant with the book recommendation at the end was a nice touch!

Digital and Analog

Concept:

So I was thinking of how I could make something creative enough to pass this assignment vibes check so I thought of photocell ( which is digital) and a Tactile push button ( which is analog ) to light up my cute little car,

You know how it is when you’re driving in the dark – you need those headlights on, and when you want to change lanes, you’ve gotta give a signal. That’s exactly what I wanted to mimic.

So, when it gets dark, my little car’s headlights kick in with the help of two LEDs, and if I want to switch lanes, I just press that button, and the LEDs start blinking to signal my lane change. Cool, right.

Materials I used:
  1. Arduino board (e.g., Arduino Uno)
  2. 2 LEDs (green)
  3. 2 x 220-ohm resistors (for current limiting)
  4. Tactile push-button switch
  5. Photocell (Light-dependent resistor, LDR)
  6. 10k-ohm resistor (for voltage divider)
  7. Breadboard and jumper wires
Video:

Connectivity:

if its not THAT clear from the pic:

  • I connected a jumper wire from the ground (GND) rail on the breadboard to the GND (ground) pin on the Arduino.
  • I then connected a jumper wire from the 5V rail on the breadboard to the 5V pin on the Arduino.
  • I then connect another jumper wire from the 5V rail on the breadboard to the row where the side of the photocell connected to 5V is placed.
  • Finally I used a jumper wire to connect the other side of the photocell to the same row as the 10k-ohm resistor’s other end.
Code:
const int led1Pin = 8;           // Define a constant integer variable for the pin of the first LED.
const int led2Pin = 9;           // Define a constant integer variable for the pin of the second LED.
const int buttonPin = 2;         // Define a constant integer variable for the pin of the tactile button.
const int photocellPin = A0;     // Define a constant integer variable for the pin of the photocell sensor.

int led1State = LOW;              // Initialize an integer variable to store the state of the first LED as LOW.
int led2State = LOW;              // Initialize an integer variable to store the state of the second LED as LOW.
int buttonState = LOW;            // Initialize an integer variable to store the state of the tactile button as LOW.
int lastButtonState = LOW;        // Initialize an integer variable to store the previous state of the button as LOW.
int lightValue = 0;               // Initialize an integer variable to store the light reading from the photocell.
int threshold = 500;              // Set a threshold value for the light reading. You can adjust this value based on your environment.

void setup() {
  pinMode(led1Pin, OUTPUT);        // Set the pin of the first LED as an OUTPUT.
  pinMode(led2Pin, OUTPUT);        // Set the pin of the second LED as an OUTPUT.
  pinMode(buttonPin, INPUT_PULLUP); // Set the pin of the tactile button as an INPUT with internal pull-up resistor.
  pinMode(photocellPin, INPUT);    // Set the pin of the photocell sensor as an INPUT.
}

void loop() {
  lightValue = analogRead(photocellPin); // Read the analog value from the photocell sensor.

  // Check the photocell value to determine whether it's dark or light.
  if (lightValue < threshold) {
    // It's dark, turn both LEDs on.
    digitalWrite(led1Pin, HIGH); // Turn on the first LED.
    digitalWrite(led2Pin, HIGH); // Turn on the second LED.
  } else {
    // It's light, turn both LEDs off.
    digitalWrite(led1Pin, LOW);  // Turn off the first LED.
    digitalWrite(led2Pin, LOW);  // Turn off the second LED.
  }

  buttonState = digitalRead(buttonPin); // Read the state of the tactile button.

  if (buttonState != lastButtonState) {
    if (buttonState == LOW) {
      // Button pressed, toggle LED states based on previous states.
      if (led1State == LOW && led2State == LOW) {
        led1State = HIGH;
      } else if (led1State == HIGH && led2State == LOW) {
        led2State = HIGH;
        led1State = LOW;
      } else {
        led2State = LOW;
      }

      digitalWrite(led1Pin, led1State); // Set the state of the first LED.
      digitalWrite(led2Pin, led2State); // Set the state of the second LED.
    }
    delay(50); // Introduce a debounce delay to prevent rapid button presses.
  }
  lastButtonState = buttonState; // Store the current button state for comparison in the next loop iteration.
}

 

reflection:

This might not have been a supper Idea, However I faced a little creativity block this week that took me a hard time to set a side

reading reflection on week 9

Physical Computing’s Greatest Hits (and misses)

What made this reading very interesting for me is that It’s all about those recurring themes in physical computing classes, and I must say, I have a soft spot for them. There’s something truly special about the way they offer a playground for creativity and innovation.

What really tickles my fancy is how Tigoe encourages us not to view these recurring themes as stale or unoriginal. Instead, he invites us to look at them as blank canvases ready for our artistic interpretation. It’s like he’s saying, “Hey, don’t shy away from these themes – they’re your chance to shine!”

Now, when we talk about themes like “Theremin-like instruments” and “Gloves,” I can’t help but get excited. I mean, who wouldn’t love the idea of creating music simply by waving their hands around? It’s not just cool; it’s a testament to the magic of human-computer interaction. And those dance pads inspired by Dance Dance Revolution? They’re pure nostalgia and joy wrapped up in a project. It’s like turning your favorite pastime into an interactive art form.

But it’s not all about play; there’s an element of challenge too. Tigoe talks about how we can add meaning to these themes by creating a physical form and context that turns simple gestures into something meaningful. That’s where the artistry comes in. It’s about infusing technology with a touch of human emotion.

And let’s not forget “LED Fetishism.” I mean, who can resist the allure of those blinking LEDs? It’s like a canvas waiting to be painted with light. The possibilities are endless, and it’s a guilty pleasure for tech enthusiasts like me. You can turn a simple LED into a work of art if you let your creativity run wild.

In the grand scheme of things, this article is a reminder that technology can be a tool for self-expression and creativity. It’s a canvas, and these recurring themes are like a familiar backdrop that sets the stage for our innovation. So, what’s not to like about that? It’s an invitation to turn everyday actions into interactive adventures, and I’m all in for that kind of excitement!

Making Interactive Art: Set the Stage, Then Shut Up and Listen

When I read this piece, it’s like a little reminder that sometimes, as artists, we tend to over-explain our creations. We put our hearts and souls into our work, and it’s only natural to want to guide others in understanding it. However, this article argues that in interactive art, there’s a beauty in leaving room for interpretation.

You see, interactive art isn’t just about creating a statement; it’s about sparking a conversation. It’s about building a stage where the audience becomes the actors. The artist sets the scene, provides the props, but then steps back and lets the audience take the spotlight.

It’s a bit like a director working with actors. You can’t tell an actor exactly how to feel or what to do to convey a particular emotion authentically. You can guide them, suggest intentions, but the true interpretation and expression come from within them. The same goes for interactive art. You design the environment, you set the stage, but you don’t need to hand-hold the audience through every step.

Instead, you offer them the basic context, suggest sequences through placement, and then let them explore. It’s like a silent invitation, a conversation between the art and the viewer. What you’ve created becomes a canvas for their emotions and thoughts.

And it’s not a one-way street. As the audience interacts with your work, they become part of this ongoing dialogue. Their reactions, their understanding, their misunderstandings – it’s all part of the artistic conversation. Some may be moved emotionally, while others might not immediately grasp the message. Some may even inspire and teach others about the work.

It’s a dynamic process, much like a performance. The audience becomes an integral part of your creation, shaping it with their responses. In a way, the art isn’t truly complete until the audience has added their unique layer to it.

Week 8- Unusual switch

  • Your concept

The unusual switch idea for my switch is an inspiration from the interaction between a football net and a ball. In this concept, the switch activates whenever the ball makes contact with the football net. To bring this idea to life, I utilized a combination of materials and components, including:

LED lights
Cardboard
Resistor
Wire
Clips
Metal plate
Aluminum foil
Duct tape
Breadboard
Arduino board
Batteries

By combining these elements, I was able to create a responsive and innovative switch design that engages users through the playful interaction between the ball and the net, triggering the LED lights to illuminate upon impact.

  • Embedded pics and videos

  • Reflection and ideas for future work or improvements

I’m really happy with how my Unusual circuit turned out. I like that it has a fun football theme and it was a creative project that I worked on, and I’m excited about what I’ve learned with Arduino, which is super cool. When I think about what I could do next, I’m thinking of making the circuit even more interactive and trying out other sports themes in my projects also maybe i can add a recorded sound of like someone saying GOOALL! when the ball hits the net.

Week 8 reading reflection ( both in the same post )

Emotions & Attractive by Donald A.Norman

The reading about three teapots is incredibly inspiring and thought-provoking. It goes beyond a simple story about teapots and delves into the profound world of human emotions and how they influence the design and usability of everyday objects.

What’s truly inspiring is the notion that design is a delicate dance between beauty, functionality, and user satisfaction. The three teapots exemplify this concept, teaching us that an object can be beautifully designed, functional, and a source of pleasure simultaneously. It’s a reminder that design should not be limited to either aesthetics or usability; it’s about achieving a harmonious balance.

The concept of “affect” introduced in the reading is particularly eye-opening. It showcases how our emotional state can dramatically alter the way we approach tasks and interact with products. Negative affect narrows our focus, enhancing concentration, while positive affect encourages creativity but also increases distractibility. This revelation challenges our traditional understanding of how emotions influence our behavior.

The most striking and, indeed, inspirational revelation is the idea that attractive things work better. This contradicts the common belief that aesthetics are secondary to usability. It suggests that, in our pursuit of enhancing functionality, we should not neglect the importance of creating products that are visually appealing and emotionally engaging.

In a world where we often prioritize utilitarian aspects, this reading encourages us to look beyond the surface. It teaches us that true beauty in design encompasses both form and function. The lesson is clear: we should aim to create products that not only serve their purpose but also bring joy and delight to our lives. This reflection challenges us to think differently about the objects we use daily and to strive for a world where everything we interact with is not only usable but also a source of inspiration and pleasure.

Her Code Got Humans on the Moon

What’s really interesting in this reading is the incredible journey of Margaret Hamilton. She was a woman who, in the 1960s, went against the norm. Back then, women weren’t usually encouraged to do high-tech jobs. But Margaret, with her math degree, got a job as a programmer at MIT. Her original plan was to support her husband’s law studies for three years and then get her own math degree.

But things changed when the Apollo space program came into play. Instead of following her original plan, Margaret stayed at MIT and led a big engineering project. She was among the very few women in that era to do this kind of work. What’s striking is that she brought her 4-year-old daughter, Lauren, to the lab on weekends and evenings. While her daughter slept, Margaret was busy writing code that would be used in the Apollo mission.

People were surprised by her dedication. They’d ask her, “How can you leave your daughter to work?” But Margaret loved her unique job. She enjoyed the camaraderie and the challenges of it. She felt like “one of the guys.” What’s intriguing is that, at that time, nobody really knew what software was. It was like the “Wild West” of technology. There were no courses or training programs for it. But Margaret and her team were pioneering the field as they wrote the code for the world’s first portable computer used in the Apollo program.

What’s also fascinating is that when the Apollo project began, software wasn’t a big deal. It wasn’t even mentioned in the mission’s engineering requirements. But as the project progressed, it became clear that software was essential. Margaret became responsible for the onboard flight software on the Apollo computers. The pressure was intense. She even rushed back to the lab after a late-night party once to fix a piece of flawed code. She worried about making headlines for a mission failure.

In the mid-1960s, more than 400 people were working on Apollo’s software. Software became a key part of winning the race to the moon. But it did more than that. Thanks to Margaret and her team, they set the stage for the software industry we know today, worth billions of dollars.

The process of programming back then was completely different from what we have today. They punched holes in stacks of cards, and these cards were processed on a massive computer. Everything had to be simulated before the actual mission.

Apollo missions carried two special computers: one in the lunar module and another in the command module. These computers were unique. They were designed by MIT engineers and were among the first to use integrated circuits instead of transistors. The computer was responsible for many critical tasks, even though it had very limited memory and computation speed compared to today’s standards.

One particularly intense moment was during the Apollo 11 mission, just before landing on the moon. There was a “documentation error,” and the computer started giving error messages. But thanks to Margaret’s technical arguments, the computer focused on the most crucial task—landing safely on the moon.

Another intriguing detail is how Margaret’s daughter, Lauren, once caused an error during a simulation. This led to changes in the documentation to prevent similar errors. It shows that even in highly technical fields, human elements and foresight play a role.

In the end, what’s most captivating about this reading is Margaret Hamilton’s exceptional journey. She not only helped land humans on the moon but also played a crucial role in shaping the software industry. Her story is a reminder that one person’s determination and innovation can have a significant impact on history.

CATSAWAY- Midterm Project

  • some images:

  • concept of my project

As a student at NYUAD, I really love our campus cat, Caramel. She makes being here even better. I enjoy graphic design, and it’s fun for me to draw. I’m also getting into coding, and I want to learn more about it. So, I had this idea for a project I call “Catsaway.” It’s a game inspired by Caramel. In the game, she can fly around the campus without crashing into the pointy palm tree corners. Instead, she gracefully glides through the soft palm leaves. To make her fly, you just press the spacebar. It’s a way to enjoy a little adventure through our campus. This project lets me combine my love for art and my interest in coding, turning my fondness for Caramel into a fun game.

My Game starts with my landing page that have 2 options either to start the game directly or taking you into the instructions page.

  • how my project works and what parts you’re proud of (e.g. good technical decisions, good game design)

I’m happy with how I brought Caramel to life in the game. Players get to control Caramel as she gracefully flies around our campus, avoiding obstacles like pointy palm trees. I’ve also made sure the game feels like NYUAD by adding familiar buildings and fluffy clouds.

I’m proud of the technical choices I made. The game has different parts, like the start page and instructions, to make it easy to play. I even added sound effects, like a cheerful jump sound when Caramel takes off. Players can restart the game or go back to the start page with simple key presses.

  • Some areas for improvement and problems that you ran into (resolved or otherwise)

During the development of my project, I encountered a few challenges and areas for improvement. One major issue I faced was optimizing the game’s performance. As the game got more complex with added elements, like the buildings and clouds, I noticed some slowdowns. I had to spend time fine-tuning the code to make sure the game runs smoothly, especially on lower-end devices. This was a valuable lesson in optimizing game design.

I had to work on enhancing the game’s instructions. I realized that players might need clearer guidance on how to play, so I made improvements to ensure that the instructions are more user-friendly.

Another challenge was making sure that the game’s look and feel truly capture the essence of NYUAD and Caramel. It required some iterations to get the graphics just right and create that immersive atmosphere.

While these challenges arose during development, I’m happy to say that I addressed them, resulting in a game I’m proud to share. The process of tackling these issues taught me valuable lessons in game development and design.

  • Future plans:
  • Play on Phones: Right now, you can play the game on a computer P5.js, but it would be great to play it on your phone or tablet. I need to make sure it works well on all kinds of devices.
  • High Score List: Having a list that shows who has the highest scores can make the game competitive. People will want to beat each other’s scores and share their achievements.
  • Listening to Players: I’ll pay attention to what players say and try to make the game better based on their ideas. They’re the ones playing it, so their feedback is important.
  • Making Money: If I want to earn money from the game, I can think about ways like letting people buy things in the game or showing ads. But I’ll be careful not to make the game annoying with too many ads 🙂

My own checklist of the requirements:

  • At least one shape

The background was coded the exact same way as the first-ever assignment, The NYUAD building, clouds, highline, and trees. I’ve used plenty of shapes  

  • At least one image

The Cat is an imported image sketched by Hand using Procreate.  as well as the NYUAD logo 

  • At least one sound

When the cat is flying the moment you hit on the Up Arrow you will hear a jumping sound

  • At least one on-screen text

The Score and the final score is a screen on text 

  • Object Oriented Programming

The game is entirely made using OOP

  • The experience must start with a screen giving instructions and wait for user input (button / key / mouse / etc.) before starting

The landing page has 2 options either wait for the user input to click on the space bar to start playing immediately or press on the letter “i” (stands for instructions) to access the instructions page.

  • After the experience is completed, there must be a way to start a new session (without restarting the sketch)

Again there are 2 options either to press on the space bar to replay or press on the letter B (stands for begin) to take you to the landing page again

Code:

let pipes = []; // An array to store information about the pipes in the game.
let score = 0; // Keep track of the player's score.
let gameOver = false; // A flag to check if the game is over.
let backgroundImage; // Not used in the code, possibly intended for a background image.
let backgroundX = 0; // The horizontal position of the background image.
let gameStarted = false; // Indicates whether the game has started.
let speed = 10; // The speed of the game elements, adjustable.
let gameState = 'landing'; // Tracks the current state of the game.

function preload() {
  // Loading images and sounds used in the game.
  // backgroundImage = loadImage('11.png');
  landing = loadImage('Catsaway(1).png');
  instruction = loadImage('instructions.png');
  caramel = loadImage("caramel.PNG");
  palm1 = loadImage("palm2-1.PNG");
  palm2 = loadImage("palm2 -2.PNG");
  ending = loadImage("score2.png");
  NYUAD = loadImage("NYUAD.png");
  
  // Load the jump sound
  jumpSound = loadSound('sfx_point.mp3');
  // hitSound = loadSound('sfx_hit.mp3');
}

function setup() {
// Set up the initial canvas for the game and create a bird object.
  createCanvas(800, 450);
  bird = new Bird(); 
}

function draw() {

  if (gameState === 'game') {
    // Code for the game state
    // Drawing buildings, clouds, and other elements on the canvas
    // Pipes are also created, and the game logic is implemented
    background(156,207,216,255);
    fill(207,207,207,255);
    rect(150,150, 500, 300);
    ellipse(400,150, 490, 100)
    
    // strokes for the building 
   fill(169, 169, 169)
    rect(150, 220, 500, 10);
    rect(150, 235, 500, 10);
    rect(150, 250, 500, 10);
    rect(150, 265, 500, 10);
    rect(150, 280, 500, 10);
    rect(150, 295, 500, 10);
    // rect(200, 220, 10, 100);
    rect(260, 220, 10, 100);
    rect(320, 220, 10, 100);
    rect(380, 220, 10, 100);
    rect(440, 220, 10, 100);
    rect(500, 220, 10, 100);

    
    image(NYUAD, 55, 0);
    fill(171,109,51,255);
    rect(150, 300, 510, 100);
    
    
    fill(121,68,19,255);
    rect(150, 310, 500, 5);
    rect(150, 317, 500, 5);
    rect(150, 324, 500, 5);
    rect(150, 331, 500, 5);
    
    rect(150, 390, 500, 20);
    

    
    // the 2 buildings
    fill(115,115,115,255);
    noStroke();
    square(0, 250, 200);
    square(600, 250, 200);
    
    // windows 
    fill(207,207,207,255);
    rect(20,260, 40, 50)
    rect(70,260, 40, 50)
    rect(120, 260, 40, 50)
    rect(640, 260, 40, 50)
    rect(690, 260, 40, 50)
    rect(740, 260, 40, 50)
  
        noStroke();
    fill(255);
    // First Cloud
    ellipse(200, 100, 80, 60);
    ellipse(240, 100, 100, 80);
    ellipse(290, 100, 80, 60);
    ellipse(220, 80, 70, 50);
    ellipse(260, 80, 90, 70);

    // Second Cloud
    ellipse(400, 80, 60, 40);
    ellipse(440, 80, 80, 60);
    ellipse(490, 80, 60, 40);
    ellipse(420, 60, 50, 30);
    ellipse(460, 60, 70, 50);

    // Third Cloud
    ellipse(600, 120, 90, 70);
    ellipse(640, 120, 110, 90);
    ellipse(690, 120, 90, 70);
    ellipse(630, 100, 80, 60);
    ellipse(670, 100, 100, 80);
    
    ellipse(0, 80, 60, 40);
    ellipse(40, 80, 80, 60);
    ellipse(90, 100, 60, 40);
    ellipse(140, 150, 50, 30);
    
    fill(15,138,70,255);
    ellipse(100, 420, 90, 70);
    ellipse(60, 450, 90, 70);
    ellipse(140, 420, 110, 90);
    ellipse(190, 420, 90, 70);
    ellipse(130, 500, 80, 60);
    ellipse(170, 500, 100, 80);
    
    ellipse(600, 420, 90, 70);
    ellipse(640, 420, 110, 90);
    ellipse(690, 420, 90, 70);
    ellipse(630, 500, 80, 60);
    ellipse(670, 500, 100, 80);
    
    
    fill(0,166,81,255);
    ellipse(0, 420, 90, 70);
    ellipse(40, 420, 110, 90);
    ellipse(90, 420, 90, 70);
    ellipse(30, 500, 80, 60);
    ellipse(70, 500, 100, 80);
    ellipse(670, 420, 90, 70);
    ellipse(700, 420, 110, 90);
    ellipse(740, 420, 90, 70);
    ellipse(750, 500, 80, 60);
    ellipse(760, 500, 100, 80);
    
    if (!gameOver) {
      bird.update();
      bird.show();
      for (let i = pipes.length - 1; i >= 0; i--) {
        pipes[i].show();
        pipes[i].update();
        if (pipes[i].hits(bird)) {
          gameOver = true;
        }
        if (pipes[i].offscreen()) {
          pipes.splice(i, 1);
        }
      }
      if (frameCount % 15 === 0) {
        pipes.push(new Pipe());
      }
      textSize(32);
      fill(255);
      text(score, 100, 30);
      for (let i = pipes.length - 1; i >= 0; i--) {
        if (pipes[i].pass(bird)) {
          score++;
        }
      }
    } else {
      image(ending, 0, 0, width, height);
      textSize(64);
      fill(255, 0, 0);
      text("", 200, height / 2 - 32);
      textSize(50);
      fill(0);
      text("" + score, 450, height / 2);
      // Provide a restart option

      // Check for restart key press
      if (keyIsDown(32)) { // SPACE key
        restart();
      } else if (keyIsDown(66)) { // 'B' key
        gameState = 'landing';
      }
    }
  } else if (gameState === 'landing') {
    
    // Code for the landing screen state
    // Displays the landing image and checks for keypress to start the game
    background(0);
    image(landing, 0, 0, width, height);
    textSize(32);
    fill(255);
    textAlign(CENTER, CENTER);
    text("", width / 2, height / 2);
    // Check for start key press (SPACE key) or 'i' key press for instructions
    if (keyIsDown(32)) { // SPACE key
      startGame();
    } else if (keyIsDown(73)) { // 'i' key
      gameState = 'instruction';
    }
  } else if (gameState === 'instruction') {
    // Code for the instruction screen state
    // Displays instructions and checks for keypress to start the game
    background(0);
    image(instruction, 0, 0, width, height);
    textSize(32);
    fill(255);
    textAlign(CENTER, CENTER);
    if (keyIsDown(32)) { // Check for SPACE key press
      startGame();
    }
  }
}

function startGame() {
  // Function to start the game
  // Resets game variables and sets the game state to 'game'
  gameState = 'game';
  gameStarted = true;
  bird = new Bird();
  pipes = [];
  score = 0;
  gameOver = false;
}

function restart() {
  // Function to restart the game
  // Calls the startGame function to reset the game
  startGame();
}

function keyPressed() {
    // When the UP_ARROW key is pressed, the bird jumps (if the game is not over)
    // Plays a jump sound when the bird jumps
  if (keyIsDown(UP_ARROW) && !gameOver && gameState === 'game') {
    bird.jump();
    jumpSound.play();
  }
}

function restartGame() {
  bird = new Bird();
  pipes = [];
  score = 0;
  gameOver = false;
}

class Bird {
  // Bird class to handle bird-related functionality
  constructor() {
    this.y = height / 2;
    this.x = 64;
    this.gravity = 0.6;
    this.lift = -15;
    this.velocity = 0;
  }

  show() {
    noFill();
    ellipse(this.x, this.y, 32, 32);
    image(caramel, this.x - 70, this.y - 30, 150, 90);
  }

  update() {
    this.velocity += this.gravity;
    this.velocity *= 0.9;
    this.y += this.velocity;
    if (this.y > height) {
      this.y = height;
      this.velocity = 0;
    }
    if (this.y < 0) {
      this.y = 0;
      this.velocity = 0;
    }
  }

  jump() {
    this.velocity += this.lift;
  }
}

class Pipe {
  // Pipe class to handle pipe-related functionality
  constructor() {
    this.top = random(height / 2.5);
    this.bottom = random(height / 2);
    this.x = width;
    this.w = 20;
    this.speed = speed; // Adjust the speed here as well
    this.highlight = false;
  }

  show() {
    fill(106, 69, 46, 255);
    if (this.highlight) {
      fill(106, 69, 46, 255);
      noStroke();
    }
    rect(this.x - 8, 0, this.w + 6, this.top);
    rect(this.x, height - this.bottom, this.w + 2, this.bottom);
    const palmX = this.x - 82;
    const palmYTop = this.top - 250;
    const palmYBottom = height - this.bottom - 120;
    image(palm2, palmX - 20, palmYTop + 195, 200, 200);
    image(palm1, palmX, palmYBottom, 200, 200);
  }

  update() {
    this.x -= this.speed;
  }

  offscreen() {
    return this.x < -this.w;
  }

  hits(bird) {
    if (bird.y < this.top || bird.y > height - this.bottom) {
      if (bird.x > this.x && bird.x < this.x + this.w) {
        this.highlight = true;
        return true;
      }
    }
    this.highlight = false;
    return false;
  }

  pass(bird) {
    if (bird.x > this.x && !this.highlight) {
      return true;
    }
    return false;
  }
}