HAPPINESS LEVEL – SHAIKHA ALKAABI

The initial idea of this project is a bit different from what I ended up with. The initial idea was designed for two players, each placing one hand on a heart rate monitor. This game uses heart rate data to measure and display the level of affection or excitement between the participants. The faster the heartbeats, the higher the presumed love connection. But after I heard that we’d have to return the items we borrowed from the IM lab I thought it would be better if I order my own two heart rate monitors and solder them myself, then I wouldn’t have to take apart my hard work. With my not-so-good soldering skills I ruined one heart rate monitor and had only one to work with. I had to improvise and solve this issue working with only one heart rate monitor which led to changing the theme of the game a bit. Professor Aaron helped me with coming up with a new game that measures the players Happiness Level by reading their heart rates through the heart monitor. The game was initially supposed to start by pressing on a yellow button but due to time constrains and many other technical difficulties, such as linking the Arduino and the P5 together, I still managed to make it work fine with the keyboard even though I feel like the yellow button gives it more of a “gamey” feel to it which is what I would’ve much preferred.

Arduino Code:

const int buttonPin = 3;      // Pin where the button is connected
const int heartRatePin = A0;  // Analog pin for heart rate sensor

int heartRateValue = 0;
bool buttonPressed = false;

void setup() {
  pinMode(buttonPin, INPUT_PULLUP);  // Set the button pin as input with internal pull-up resistor
  pinMode(heartRatePin, INPUT);
  Serial.begin(9600);
  while (Serial.available() <= 0) {  // on/blink while waiting for serial data
    Serial.println("0,0");
    delay(50);
  }
}

void loop() {
  heartRateValue = analogRead(heartRatePin);  // Read the value from the heart rate sensor
  int bpm = calculateBPM(heartRateValue);     // Convert the analog reading to BPM

  // Read button state
  int buttonState = 1 - digitalRead(buttonPin);

 

  while (Serial.available()) {
  

    int left = Serial.parseInt();

    if (Serial.read() == '\n') {
      Serial.print(buttonState);
      Serial.print("0,50");
      Serial.println(bpm);
    }
  }


  // Always send the current heart rate and button state
}

// Function to simulate BPM calculation - replace this with your sensor-specific calculation
int calculateBPM(int sensorValue) {
  return sensorValue / 10;  // Simplified calculation for demonstration
}

P5.Js Code:

class MainMenu extends Menu {
  constructor(id) {
    super(id);

    this.pos = createVector(width / 2, height / 2.7);
    this.size = 240;
    this.strokeCol = color(
      random(100, 255),
      random(100, 255),
      random(100, 255)
    );
    this.hearts = [];
    for (let i = 0; i < 20; i++) {
      this.hearts.push({ x: random(width), y: random(height) });
    }
    this.random_seed = random(100, 10000); //use for heard animations in the back
    this.heartPos = { x: width / 2, y: height * 2 };
  }

  render() {
    background("#24182e");
    textAlign(CENTER, CENTER);
    textSize(44);
    textFont(pixel_font);
    fill("#8249c6");
    stroke(this.strokeCol);
    strokeWeight(4);

    text("HAPPINESS  LEVEL", width / 2, 50);
    //change strokcol every 20 farmes
    if (frameCount % 60 == 0) {
      this.strokeCol = color(
        random(100, 255),
        random(100, 255),
        random(100, 255)
      );
      this.random_seed = random(100, 10000);
    }
    textSize(30);
    stroke(200, 100, 100);
    push();
    randomSeed(this.random_seed);
    textFont("arial");
    for (let h of this.hearts) {
      for (let h2 of this.hearts) {
        if (dist(h.x, h.y, h2.x, h2.y) < 10) {
          strokeWeight(2);
          line(h.x, h.y, h2.x, h2.y);
        }
      }
      text("♥", h.x, h.y);
      h.x = lerp(h.x, random(width), 0.01);
      h.y = lerp(h.y, random(height), 0.01);
    }
    pop();
    push();
    textFont("arial");
    textSize(160);
    this.heartPos.y = lerp(this.heartPos.y, height / 1.5, 0.1);
    stroke(255);
    fill("#B28CDEAA");
    text("♥", this.heartPos.x, this.heartPos.y);
    textSize(30);
    noStroke();
    fill(255);
    textFont(pixel_font);
    text(
      "PLACE YOUR FINGER ON THE HEART",
      this.heartPos.x,
      this.heartPos.y + 100
    );
    pop();
    noStroke();
  }
}
class GameMenu extends Menu {
  constructor(id) {
    super(id);

    this.heart = new Heart(createVector(width / 2, height / 2.7), 240);
  }

  render() {
    textAlign(CENTER, CENTER);
    textSize(18); 
    background("#24182e");
    fill("#A88DC7");
    text("CHECKING YOUR LOVE LEVEL!", width / 2, height - 30);
    fill("#8249C67C");
    textFont("arial");
    textSize(34);

    for (let i = 0; i < 12; i++) {
      for (let j = 0; j < 8; j++) {
        let x = map(i, 0, 11, 0, width);
        let y = map(j, 0, 7, 0, height);
        if (frameCount % 40 < 20) {
          if (i % 2 == 0 || j % 2 == 0) {
            text("♥", x, y);
          }
        } else {
          if (i % 2 != 0 || j % 2 != 0) {
            text("♥", x, y);
          }
        }
      }
    }

    this.heart.render();
  }

  update() {
    this.heart.update();
    // Removed the timer decrement and check
  }

  reset() {
    this.heart = new Heart(createVector(width / 2, height / 2.7), 220);
  }
}
class EndMenu extends Menu {
  constructor(id) {
    super(id);

    this.finalScore = null;

    this.hearts = [];
    for (let i = 0; i < 2; i++) {
      this.hearts.push({ x: random(width), y: random(height) });
    }
    this.random_seed = random(100, 10000); //use for heard animations in the back
  }

  render() {
    background("#24182e");
    push();
    stroke(200, 100, 100);
    randomSeed(this.random_seed);
    textFont("arial");
    textSize(34);
    for (let h of this.hearts) {
      for (let h2 of this.hearts) {
        if (dist(h.x, h.y, h2.x, h2.y) < 100) {
          line(h.x, h.y, h2.x, h2.y);
        }
      }
      text("♥", h.x, h.y);
      h.x = lerp(h.x, random(width), 0.01);
      h.y = lerp(h.y, random(height), 0.01);
    }
    if (frameCount % 60 == 0) {
      this.random_seed = random(100, 10000);
    }
    pop();

    fill("#A88DC7");
    stroke(255);
    textFont(pixel_font);
    textSize(60);
    textAlign(CENTER, CENTER);
    text("THANK YOU !", width / 2, 160);
    noStroke();
    textSize(24);
    // text(
    //   `${this.finalScore}\n\nYOUR COMPATIBILITY SCORE`,
    //   width / 2,
    //   height / 1.5
    // );
    //     push();
    //     noStroke();
    //     fill(0);
    //     rect(0, 0, width, height);

    //     fill(255);
    //     textStyle(BOLD);
    //     textAlign(CENTER, CENTER);
    //     textSize(96);
    //     text("GAME OVER", width / 2, height / 4);

    //     textSize(40);
    //     text(`COMPATIBILITY SCORE: ${this.finalScore}`, width / 2, height / 2);

    //     textStyle(NORMAL);
    textSize(16);
    text("TRY AGAIN?", width / 2, height - 60);
    text("Yes", 100, height - 60);
    text("No", width - 100, height - 60);
    push();
    textFont("arial");
    pop();

    //     textSize(40);
    //     text("YES? OR NO?", width / 2, 640);

    //     pop();
  }

  reset() {
    this.finalScore = null;
  }
}

 I’m content with the final product despite getting extremely sick two days before the showcase while having other final projects due the day before it. For future improvements I’d like to incorporate my initial idea and also add a different game mode, Lie Detector Mode, which sounds fun to make with using the heart rate monitor. Overall, I feel like I got exposed to many things in this course which makes me much more comfortable with the things we’ve been working with during the entirety of this semester. I’d also like to thank professor Aaron for being extremely patient and helpful with me 🙂

Week 12 Reading – Shaikha AlKaabi

This week’s reading, “Design Meets Disability,” examines the relationship between design and disability, challenging the traditional view that disability aids should be discreet and practically invisible. The book argues for a new approach that balances functionality with aesthetic appeal, similar to how glasses have evolved from a medical necessity to a fashion statement. It emphasizes that disability aids should not only serve practical purposes but also make positive aesthetic statements.

The text highlights examples like the Eameses’ leg splints, initially designed for functionality but now celebrated for their innovative design. This shows the potential for disability design to extend beyond basic functionality and influence broader design disciplines.

The book critiques cultural and social norms that favor invisibility in disability aids and advocates for designs that are empowering and expressive. It explores how products like glasses have successfully become both functional and fashionable, suggesting a similar potential for other disability aids.

To conclude, “Design Meets Disability” calls for a reevaluation of design principles in the context of disability. It argues for designs that are not only functional but also aspirational and culturally relevant, aiming to reflect the diversity of users and contribute to a more inclusive society where design enhances individual identity and expression.

Final Project Idea “Love Level” – Shaikha AlKaabi

Project Idea: Love Level Game

  

The Love Sensor game is an interactive experience designed for two players, each placing one hand on a heart rate monitor. This innovative game uses heart rate data to measure and display the level of affection or excitement between the participants. The faster the heartbeats, the higher the presumed love connection. 

How It Works: 

  1. Heart Rate Monitoring: Each player places a hand on the heart rate monitor, which captures their pulse in real time.
  2. Data Processing: An Arduino board processes the heart rate data, assessing the intensity and changes in each player’s heartbeat.
  3. Dynamic Feedback: The processed data is then sent to a computer where p5.js generates visual and auditive outputs. These outputs are designed to dynamically respond to the heart rate data. For instance, visuals willgrow more vibrant as the players’ heart rates increase, symbolizing a stronger connection. Audio feedback may also escalate, creating a rich sensory environment that reflects the intensity of the game.
  4. Interactive Experience: The game aims to create a playful and engaging experience that not only entertains but also visually and audibly illustrates the emotional bond between the players, making it a fascinating exploration of human interactions.

  

Melody steps – (Hamdah, Shaikha, Shereena)

Concept: 

Replicating the piano playing mat that we all used to play as children was the idea behind this assignment. Even those who are not musically inclined are drawn to play with the piano mat again because of how logically it was created. Why not make something that makes us all feel nostalgic, rather than just one of us? You’ll be overwhelmed with happiness as you play about with our design and hopefully be able to relive all your childhood memories in a way. This initiative will facilitate audience engagement and provide a means of connection to one another. 

https://youtu.be/Epy7WpZjhno

Code:

The code is for an Arduino setup that uses an ultrasonic sensor to measure distance and a force-sensitive resistor to detect pressure. It plays different musical notes based on the distance measured by the sensor, but only if a certain pressure threshold is exceeded on the resistor. If the measured distance is out of a specified range or the pressure is too low, no sound is played. The system uses this setup to create an interactive musical device where sound changes with distance and pressure.

 

int trig = 10;

int echo = 11;

long duration;

long distance;

int force;



void setup() {

  pinMode(echo, INPUT);



  pinMode(trig, OUTPUT);



  Serial.begin(9600);

}



void loop() {

  digitalWrite(trig, LOW); //triggers on/off and then reads data

  delayMicroseconds(2);

  digitalWrite(trig, HIGH);

  delayMicroseconds(10);

  digitalWrite(trig, LOW);

  duration = pulseIn(echo, HIGH);

  distance = (duration / 2) * .0344;    //344 m/s = speed of sound. We're converting into cm





  int notes[7] = {261, 294, 329, 349, 392, 440, 494}; //Putting several notes in an array

  //          mid C  D   E   F   G   A   B



  force = analogRead(A0); //defining force as FSR data




  if (distance < 0 || distance > 50 || force < 100) { //if not presed and not in front



    noTone(12); //dont play music



  }



  else if ((force > 100)) {  //if pressed



    int sound = map(distance, 0, 50, 0, 6);  //map distance to the array of notes

    tone(12, notes[sound]);  //call a certain note depending on distance



  }




}

 

Reflections & Challenges:

One of the challenges we had while working on this project was the weakness of the sensors; if we had an ultrasonic sensor that measured the distance longer and a larger force detecting resistor, we would not have had any trouble playing notes. Therefore, we were forced to limit the user to playing notes (C-D-E-F-G-A) as a result of this.

 

Reading Response Week 11 – Shaikha AlKaabi

In the text A Brief Rant on the Future of Interaction Design, the author argues for a thoughtful approach to tool design, emphasizing that a tool’s primary function should be to serve human needs and enhance our innate abilities. The essence of his argument is that tools should not be valued merely for their aesthetics, but for their ability to improve our efficiency and effectiveness. He expresses a certain dissatisfaction with current technology, particularly critiquing devices he describes as “Pictures Under Glass.” He suggests that such technologies diminish the sensory richness and the interactive potential of our hands, more specifically our fingertips. He’s worried that focusing too much on making interfaces look good might make us forget how important it is to actually touch and interact with things around us.The author urges us to think about all the ways we can interact with tools, suggesting we use interfaces that involve more of our senses and movements. He believes that just using one finger on a touchscreen doesn’t make full use of our ability to move and feel.

In conclusion, the author calls for a future where technology development is inspired by the full range of human abilities. Instead of adapting to the constraints of existing technology, he challenges designers to envision tools that integrate seamlessly with human capacity for manipulation and sensory experience, fostering a more intuitive and enriching interaction with our tools.

As for his follow-up article, the author has replied to some critiques about his previous article on the future of interaction design, where he ranted about current tech not being up to par. He clarifies he wasn’t out to offer a solution but to spark deeper research into better solutions that really fit human capabilities. He’s not against current tech like iPhones or iPads, but he’s worried if we don’t push for more, we’ll get stuck with something that’s only a bit better than what we have. He’s not keen on just adding physical keyboards or styluses to our devices because that doesn’t really tap into the full experience of interacting with the world around us. And when it comes to voice commands, he thinks they’re fine for simple questions or tasks, but for more complex stuff like exploring ideas or creating art, they fall short.The author isn’t thrilled with tech that’s all about swiping on screens either. It might be easy, but it’s not making the most of what our bodies can do, and it could even hold back kids’ development because it’s not challenging them enough. He thinks we’re meant to interact with our world in more dynamic ways, and our future tech should reflect that.

Week 10 Light Play – Shaikha Alkaabi

Inspiration:

Fidget Cube Blue-gray/Black

The inspiration for this code setup comes from the interactive and tactile nature of fidget toys, which are designed to engage the senses through hands-on manipulation. Just as fidget toys provide sensory feedback through various textures and movements to captivate attention, this Arduino project uses buttons and variable light settings to create a dynamic interaction. Users can physically alter the brightness of LEDs or toggle them on and off, mirroring the satisfying and immediate response found in fidget toys, making the learning process both fun and engaging.

Video:

Code:

const int led0 = 3; 
const int led1 = 5; 
const int photoResistor = A1; 
const int potentiometer = A0; 
const int buttonPin = 2; 

void setup() {
  Serial.begin(9600);
  pinMode(led0, OUTPUT);
  pinMode(led1, OUTPUT);
  pinMode(buttonPin, INPUT); // sets the button as an input device
}

void loop() {
  int lightValue = analogRead(photoResistor);
  int potValue = analogRead(potentiometer);
  int delayTime = map(potValue, 0, 1023, 50, 1000); 
  int buttonState = digitalRead(buttonPin);

  Serial.print("Light Value: ");
  Serial.println(lightValue);

  // Analog control of red LED using potentiometer
  int brightness = map(potValue, 0, 1023, 0, 255); 
  analogWrite(led0, brightness);

  // Digital control of green LED using a button
  if (buttonState == HIGH) {
    digitalWrite(led1, HIGH);
  } else {
    digitalWrite(led1, LOW);
  }

  // Additional feature using the photoresistor to change the behavior based on light
  if (lightValue < 300) {
    // When light levels are low, flash the green LED rapidly.
    digitalWrite(led1, HIGH);
    delay(100); // Short delay for rapid flash
    digitalWrite(led1, LOW);
    delay(100); // Continue rapid flash
  }
}

The code controls two LEDs based on inputs from a combination of analog and digital sensors, resulting in an interactive and dynamic output that depends on environmental conditions and user interaction.

  1. Red LED (Analog Control): The brightness of the red LED is directly controlled by a potentiometer. As the user adjusts the potentiometer, the red LED’s brightness varies smoothly from completely off to fully bright. This provides a visual representation of the analog input value, allowing users to see a direct correlation between the potentiometer’s position and the LED’s intensity.
  2. Green LED (Digital Control): The state of the green LED is controlled by a photoseisitor. Pressing photoresistor  turns the LED on, and releasing it turns the LED off. This simple binary control mimics typical digital behaviors in electronics, where a switch controls a circuit’s on/off state.
  3. Additional Behavior with Photoresistor: When it gets dark, the green LED automatically starts flashing rapidly to signal a change in light conditions, overriding the button control.

Week 10 Reading Response – Shaikha AlKaabi

Physical Computing’s Greatest Hits (and misses)

The article provides a fascinating exploration into the realm of physical computing, revealing a pattern of innovation that breathes new life into established concepts. It’s not merely about crafting something entirely new, it’s about the clever adaptation and imaginative expansion of familiar ideas. 

Starting with Theremin-like instruments and advancing through gloves equipped with sensors, the text underscores the perpetual evolution of interaction between humans and machines. Projects like ‘Hand-as-cursor’ and ‘Multitouch Interfaces’ take this further by translating human gestures into digital reactions, while ‘Tilty stands and tables’ employ physical manipulation to navigate virtual spaces. 

‘Tilty Controllers’ demonstrate the significance of object orientation, expanding our perception of how we can control and influence technology. ‘Things You Yell At’ and ‘Meditation Helpers’ show a more personal side, engaging with our voices and physiological states to guide or react in a context-sensitive manner. 

With ‘Fields of Grass’, we see a poetic application of sensor arrays, creating responsive textures that react to human touch. ‘Remote Hugs’ and ‘Dolls and Pets’ showcase the emotional and relational potentials of physical computing, emphasizing companionship and emotional communication. ‘LED Fetishism’ reminds us to push past the allure of visual feedback to discover deeper, more meaningful interactions. 

The text concludes with an ode to ‘Hybrid projects’, which combine different elements for novel experiences, like a flight simulator that mimics bird flight, showing the limitless potential when various facets of physical computing are merged.

Overall, the reading serves as an inspiration and a challenge to think beyond the conventional, urging creators in the field of physical computing to seek out the untapped potential in the interplay of the digital and physical worlds. It’s an invitation to innovate within the spectrum of sensory experiences, enriching our interaction with technology in both profound and playful ways.

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

The article on interactive art highlights a unique perspective on creation: the artist’s role is to set up an experience and then let the audience interact with it in their own way. It suggests that interactive art isn’t about dictating experiences but about creating opportunities for the audience to explore and interpret. This idea parallels a conversation where the artist ‘speaks’ through their work and then listens to the audience’s response through their interactions with it. Just as a stage director doesn’t perform but sets the scene for actors, the artist here provides the tools for expression and then steps back, allowing the audience to find personal meaning and contribute to the art’s ongoing narrative.

Week 9 Shaikha Alkaabi – Wink at me

My Project Idea:

I decided to build a project using an Arduino board that can detect when I wink. At first, I thought about making something that could sense how close my body was to a sensor. Later on in class, my teacher mentioned we shouldn’t use sensors for this project because that’s not what DigitalRead is about. So, I had to think of something else. That’s when I thought about how I often wink without even realizing it. I figured, why not turn that into my project? Surprisingly, setting up the breadboard, which I thought would be tough, turned out to be easier than I expected.

How It Works:

  1. Circuit Setup: I attached two small pieces of aluminum foil in a way that they sit close to my eye, one above and one below. These foils are connected to the Arduino board. I also connected a green LED to the Arduino, which acts as the output signal.
  2. Detecting the Wink: When I wink, the eyelid movement causes the two pieces of aluminum foil to touch. This touch closes the circuit, similar to pressing a button, but it’s my wink that makes it happen.
  3. Interacting With the Project: To interact with my project, all I have to do is wink. The aluminum foil pieces make contact, the Arduino notices the change, and the green LED lights up in response.
  4. Feedback: The lighting up of the green LED serves as immediate feedback that my wink was detected. It’s a simple and effective way to communicate the input action.
    Some challenges that I faced with this project are:
  1.  Getting the aluminum foil just right so it detects winks without false triggers from other facial movements was tricky.
  2. Keeping the foil safe and comfortable to wear around my eye needed thoughtful setup and possibly skin-friendly materials to avoid irritation which is why I opted to use a bandaid, which still seemed to irritated the area around my eyes.

Project Video:

IMG_5451 2

 

Week 8a: Reading Response

-Attractive Things Work Better 

In reflecting on the article “Attractive Things Work Better,” I have been intrigued by the intersection of aesthetics and usability in design and how it shapes our cognitive and emotional experiences. The piece profoundly highlights the influence of affect on cognition. It introduces the idea that positive affect, obtained by attractive, aesthetically pleasing design, can enhance creativity and flexibility in problem-solving, whereas negative affect can lead to a narrower scope of thought, suited for depth-first processing and focused tasks.

The article discusses three distinct teapots, each illustrating a different aspect of design. The teapot designed by Jacques Carelman, which is intentionally unusable, serves as a humorous critique of the functionality of everyday objects. Michael Graves’ teapot, while more practical, still places emphasis on aesthetic appeal. And then there is the Nanna teapot, which may not be conventionally beautiful but offers an intuitive design that caters to the brewing process and enhances the tea-drinking experience.

These examples lead to an essential realization: while usability is crucial, especially in high-stress situations where focus and efficiency are important, attractive design has its own merits. In more relaxed or positive situations, an attractive appearance can actually improve usability by making individuals more tolerant of minor inconveniences. This does not, however, diminish the importance of usability, rather, it suggests that usability and aesthetics are not mutually exclusive.

The argument extends beyond teapots to technology, like color monitors, which were initially dismissed as unnecessary but now are standard due to their positive affect. Norman’s earlier work, which seemed to prioritize usability at the expense of aesthetics, is now understood in a more nuanced light. Affect and design are not separate entities but are interwoven, influencing how we interact with and feel about the tools and objects in our lives.

In conclusion, as a student with keen interest in design, this has reshaped my understanding that to enhance the quality of life through design, we must integrate usability with desirability, ensuring that products not only serve their purpose efficiently but also bring joy and satisfaction through their aesthetic appeal. 

-Her Code Got Humans on the Moon

Margaret Hamilton’s story is a profound reminder of the immense impact one individual can have on technology and history. As a young mathematician working at MIT in the 1960s, she was pivotal in developing the onboard flight software for the Apollo missions, which ultimately enabled humans to land on the moon.

It’s striking to consider that she did this in an era when software engineering was not even recognized as a discipline. Her foresight to advocate for rigorous error-checking in the software, despite skepticism from her peers, was crucial, particularly evident during the Apollo 8 mission when an astronaut’s mistake could have been catastrophic without her code.

Her contributions went beyond the Apollo program, they laid the groundwork for modern software development. Her story is not just about technical brilliance but also about breaking barriers and defying expectations, which is especially meaningful in the continuous fight for gender equality in STEM fields. Her legacy inspires me to approach problems with determination and a forward-thinking mindset.

Midterm Project – Shaikha AlKaabi

 

When I first started working on my midterm project, I really wanted to make a game about planting flowers. It sounded fun and I thought it would be something different. But as I kept working on it and thinking more about how it would work, it started to feel less like a game and more like a simulator for planting. It wasn’t as fun as I had hoped it would be, and that was really important to me. So, I decided to change it.

I switched my idea to “Back and Forth.” At first, I thought about making a volleyball game. It seemed like a good idea because it was about moving back and forth, which is what I wanted. But the more I thought about it, the more I realized that making it feel realistic and fun at the same time was going to be really hard. So, I started looking for something similar but a bit simpler, and that’s when I landed on a ping-pong game. Ping-pong still had that back and forth action which I liked, but it felt more doable and still really fun. That’s how I ended up with the idea for my project.


Challenges:

The tricky  part was figuring out how to make the ball start from the center of the screen. But then I remembered the width /2 and height/2 that we used to center things and I used that to position the ball at the center whenever it went out of the screen:

reset() { // Reset the ball’s position and speed this.x = width / 2; this.y = height / 2; this.xSpeed = random([-5, 5]); // Increased speed this.ySpeed = random([-5, 5]); // Increased speed }

Overall, I’m quite happy with my game.

let leftPaddle;
let rightPaddle;
let ball;
let leftScore = 0;
let rightScore = 0;
let gameState = "start";
let tableColor;
let startScreenImage;
let gameOverSound;
let paddleHitSound;

function preload() {
  startScreenImage = loadImage('background-image.jpg');
  gameOverSound = loadSound('game over.mp3');
  paddleHitSound = loadSound('paddle.mp3');
}

function setup() {
  createCanvas(800, 400);
  textAlign(CENTER, CENTER);
  textSize(40);
  leftPaddle = new Paddle(true);
  rightPaddle = new Paddle(false);
  ball = new Ball();
  tableColor = color(138, 43, 226);
}

function draw() {
  background(tableColor);
  drawNet();
  if (gameState === "start") {
    showStartScreen();
  } else if (gameState === "play") {
    leftPaddle.show();
    rightPaddle.show();
    ball.show();
    leftPaddle.update();
    rightPaddle.update();
    ball.update();
    ball.checkPaddleCollision(leftPaddle);
    ball.checkPaddleCollision(rightPaddle);
    ball.checkScore();
    drawScore();
  } else if (gameState === "gameover") {
    showGameOverScreen();
  }
}

function keyPressed() {
  // Start the game when ENTER is pressed
  if (keyCode === ENTER && gameState === "start") {
    gameState = "play";
  }
  // Reset the game when ENTER is pressed after game over
  else if (keyCode === ENTER && gameState === "gameover") {
    gameState = "start";
    leftScore = 0;
    rightScore = 0;
    ball.reset();
  }

  // Control the right paddle with arrow keys
  if (keyCode === UP_ARROW) {
    rightPaddle.ySpeed = -5;
  } else if (keyCode === DOWN_ARROW) {
    rightPaddle.ySpeed = 5;
  }

  // Control the left paddle with 'W' and 'S' keys
  if (key === 'w' || key === 'W') {
    leftPaddle.ySpeed = -5;
  } else if (key === 's' || key === 'S') {
    leftPaddle.ySpeed = 5;
  }
}

function keyReleased() {
  // Stop the left paddle when 'W' or 'S' key is released
  if (key === 'w' || key === 'W' || key === 's' || key === 'S') {
    leftPaddle.ySpeed = 0;
  }

  // Stop the right paddle when arrow keys are released
  if (keyCode === UP_ARROW || keyCode === DOWN_ARROW) {
    rightPaddle.ySpeed = 0;
  }
}


function keyReleased() {
  // Stop the left paddle when 'W' or 'S' key is released
  if (key === 'W' || key === 'S') {
    leftPaddle.ySpeed = 0;
  }

  // Stop the right paddle when arrow keys are released
  if (keyCode === UP_ARROW || keyCode === DOWN_ARROW) {
    rightPaddle.ySpeed = 0;
  }
}

function drawNet() {
  // Draw the net in the middle of the table
  stroke(255);
  strokeWeight(2);
  for (let i = 0; i < height; i += 20) {
    line(width / 2, i, width / 2, i + 10);
  }
}

function drawScore() {
  // Display the scores below the player names with text indicating it is the score
  fill(255);
  textSize(20);
  textFont("Courier New");
  textAlign(CENTER, CENTER);
  
  // Player 1 score
  stroke(0)
  text("Player 1", width / 4, 90);
  text("Score: " + leftScore, width / 4, 110);

  // Player 2 score
  stroke(0)
  text("Player 2", (3 * width) / 4, 90);
  text("Score: " + rightScore, (3 * width) / 4, 110);
}


function showStartScreen() {
  // Display the start screen with instructions
  image(startScreenImage, 0, 0, width, height);
  fill(138, 43, 226);
  stroke(255); // Outline color
  strokeWeight(2); // Outline weight
  textFont("Courier New");
  textStyle(BOLD);
  textSize(40);
  text("Back and Forth", width / 2, height / 2 - 100);
  textSize(20);
  text("Press ENTER to Start", width / 2, height / 2 + 50);
  textSize(15);
  text("Press 'W' to move the left paddle up and 'S' to move it down", width / 2, height / 2 + 125);
  textSize(15);
  text("Press Upward-Arrow to move the right paddle up and Down-Arrow to move it down", width / 2, height / 2 + 150);
}

function showGameOverScreen() {
  // Display the game over screen with the winning player's name
  let winner = leftScore > rightScore ? "Player 1" : "Player 2";
  fill(255);
  stroke(0); // Outline color
  strokeWeight(5); // Outline weight
  textFont("Courier New");
  textSize(40);
  text(winner + " Wins!", width / 2, height / 2 - 40);
  textSize(20);
  text("Press ENTER to Play Again", width / 2, height / 2 + 40);
}

class Paddle {
  constructor(isLeft) {
    this.w = 10;
    this.h = 80;
    this.y = height / 2 - this.h / 2;
    if (isLeft) {
      this.x = 20;
    } else {
      this.x = width - 30;
    }
    this.ySpeed = 0;
  }

  show() {
    // Draw the paddle
    fill(255);
    rect(this.x, this.y, this.w, this.h);
  }

  update() {
    // Update the paddle's position based on key inputs
    this.y += this.ySpeed;
    this.y = constrain(this.y, 0, height - this.h);
  }
}

class Ball {
  constructor() {
    this.reset();
  }

  reset() {
    // Reset the ball's position and speed
    this.x = width / 2;
    this.y = height / 2;
    this.xSpeed = random([-5, 5]); // Increased speed
    this.ySpeed = random([-5, 5]); // Increased speed
  }

  show() {
    // Draw the ball
    fill(255);
    ellipse(this.x, this.y, 10, 10);
  }

  update() {
    // Update the ball's position
    this.x += this.xSpeed;
    this.y += this.ySpeed;
    if (this.y < 0 || this.y > height) {
      this.ySpeed *= -1;
    }
  }

  checkPaddleCollision(paddle) {
    // Check for collision with paddles and change direction
    if (this.x - 5 < paddle.x + paddle.w && this.x + 5 > paddle.x && this.y - 5 < paddle.y + paddle.h && this.y + 5 > paddle.y) {
      this.xSpeed *= -1;
      paddleHitSound.play();
    }
  }

  checkScore() {
    // Check for scoring and end game condition
    if (this.x < 0) {
      rightScore++;
      this.reset();
      gameOverSound.play();
    } else if (this.x > width) {
      leftScore++;
      this.reset();
      gameOverSound.play();
    }
    if (leftScore >= 5 || rightScore >= 5) {
      gameState = "gameover";
    }
  }
}