Final Project – F.R.I.E.N.D.S Tribute

This project is very special for me because it’s centered around the first show I have ever watched and one of my favorites ever. I have tried to encapsulate every aspect of the theme of the show into the project as possible and the result is pretty satisfying.

Main Challenge:

One of the biggest challenges for me was to be able to do all the functionalities I wanted efficiently. Passing by reference cannot be done in Java except using objects types so I had to find my way around that. I created a matrix of arrays storing answers for the questions with each row representing a character in the show. But in order for me to randomize the order of the answers every single time the game is played, I used the StringList class. I created a list for every answer, which is a copy of a row in the matrix, then I shuffle using the shuffle() function and I display. The original matrix is kept for me to be able to check which answer exactly is chosen to increment the respective character’s score accordingly. I created a function to check which character’s answer exactly was chosen, and I use the same code for every question page with the appropriate changes. But in order for me to to have all these if conditions to not change question unless a button was pressed and to be able to identify the answer properly, I had to actually write numerous lines of code. But the runtime of the code is actually not that long because it is just mainly if conditions which have a runtime of O(1).

Implementation:

I used the main theme song in the background at all times and the player can lower the volume because it can be too repetitive. The frames of the options and in the instructions and the buttons on the Arduino board all have the same pattern of colors in the same order (red, blue, yellow, red, yellow blue). I used the same shade of purple and gold as in Monica’s apartment throughout the game. I also used the same font as in the original series’ logo. The yellow bulb indicates that the game is waiting for you to choose an answer, the blue blinks while you are pressing, and the green lights up when you finish the trivia. I made it so the instructions appear only during the first time you start the game and not if you replay because by then you surely know how to play. I made it so the choices change color if you hover over them using the mouse to make it more interactive. I was worried people might think this means they can click to choose, but then if they try to click nothing will happen, and the instructions page at the start actually explains that they should click on the Arduino board, so it should be clear enough. Whenever an option is chosen, the choice color changes momentarily as well like when the mouse hovers over it to indicate what exactly was actually chosen. I used 4 questions from the websites I included as reference in the code just to have an existing reference, but I made up the remaining 7 questions on my own in order to make it more personal. The questions at first are very easy, meaning that you can guess right away which answer represents which of the six characters. But as you go further, the answers are less direct and you cannot always guess right away who is who, which  is just because the player is improving in answering the questions by time and to make it more interesting and as if it’s an actual realistic test that is interactive.

This was the Arduino progress in the first stage.

Background Image of the trivia.

This was how I built the logic for the volume knob of the theme song.

The result screens I designed at the end of the trivia based on the answers.

I actually tried to choose the most general traits of the characters so that regardless of the combination of answers leading to such a final result, the player will most likely have at least most of the things which I included in the short paragraph describing their character. I also made it 11 questions (a prime number) so that there will never be a tie in answers where I will have to choose one as winner or put both which is just lame.

This is the final result from the Arduino perspective.

Instructions for the trivia. I tried to make it as visual and realistic as possible, and I even used the same colors to make it clearer for the player. The same font is used consistently in order to maintain the theme at all times.

This is the actual final result on the computer.

Following is the Arduino code for the project:

int choice1 = 0;
int choice2 = 0;
int choice3 = 0;
int choice4 = 0;
int choice5 = 0;
int choice6 = 0;
int last = 0;
int start = 0;        //some variables to store the values from the serial by parseInt

int one = 7;
int two = 6;
int three = 5;
int four = 4;
int five = 3;
int six = 2;          //outlets of the six buttons

int ledYellow = 8;
int ledBlue = 9;
int ledGreen = 10;      //outlets of the three led bulbs

void setup() {
  Serial.begin(9600);
  Serial.println("0,0,0");
 
  pinMode(ledYellow, OUTPUT);
  pinMode(ledBlue, OUTPUT);
  pinMode(ledGreen, OUTPUT);

  pinMode(one, INPUT);
  pinMode(two, INPUT);
  pinMode(three, INPUT);
  pinMode(four, INPUT);
  pinMode(five, INPUT);
  pinMode(six, INPUT);
}

void loop() {
  while (Serial.available()) {
    choice1 = Serial.parseInt();
    choice2 = Serial.parseInt();
    choice3 = Serial.parseInt();
    choice4 = Serial.parseInt();
    choice5 = Serial.parseInt();
    choice6 = Serial.parseInt();
    last = Serial.parseInt();           //stores whether or not the game is off
    start = Serial.parseInt();          //stores whether or not the game has started

    if (Serial.read() == '\n') {
      int sensor = analogRead(A0);
      delay(1);
      int button1 = digitalRead(one);
      delay(1);
      int button2 = digitalRead(two);
      delay(1);
      int button3 = digitalRead(three);
      delay(1);
      int button4 = digitalRead(four);
      delay(1);
      int button5 = digitalRead(five);
      delay(1);
      int button6 = digitalRead(six);
      delay(1);

     if (start == 1) {        //as soon as the game begins after instructions yellow lights
        if (button1 == HIGH || button2 == HIGH || button3 == HIGH || button4 == HIGH || button5 == HIGH || button6 == HIGH) { //while any button is pressed, light blue and dim rest
          digitalWrite(ledBlue, HIGH);
          digitalWrite(ledYellow, LOW);
        }
        else {              //otherwise only keep yellow lit
          digitalWrite(ledBlue, LOW);
          digitalWrite(ledGreen, LOW);
          digitalWrite(ledYellow, HIGH);
        }
      }
      else {              //if game is not on switch yellow and blue off
        digitalWrite(ledYellow, LOW);
        digitalWrite(ledBlue, LOW);
        if (last == 1) {          //if it was specifically on the end page where a pic of character shows, light up the green bulb signifiying end
          digitalWrite(ledGreen, HIGH);  
        }
        else { digitalWrite(ledGreen, LOW);} 
      }
     
      Serial.print(button1);
      Serial.print(",");
      Serial.print(button2);
      Serial.print(",");
      Serial.print(button3);
      Serial.print(",");
      Serial.print(button4);
      Serial.print(",");
      Serial.print(button5);
      Serial.print(",");
      Serial.print(button6);
      Serial.print(",");
      Serial.println(sensor);               //print everything back to complete the handshake
    }
  }
}

Following is the Processing Code:

import processing.serial.*;
import processing.sound.*;    //importing sound library

Serial myPort;
int choice1 = 0;
int choice2 = 0;
int choice3 = 0;
int choice4 = 0;
int choice5 = 0;
int choice6 = 0;

int finish;
int blink;

float prevFrame = 0;

PImage rachelBackground, phoebeBackground, chandlerBackground, rossBackground, monicaBackground, joeyBackground;
PImage bg1, bg2;

float volume = 0;
float volumeWidth;

boolean page0 = false;
boolean page1 = false;
boolean page2 = false;
boolean page3 = false;
boolean page4 = false;
boolean page5 = false;
boolean page6 = false;
boolean page7 = false;
boolean page8 = false;
boolean page9 = false;
boolean page10 = false;
boolean page11 = false;

String[] answers1 = new String[6];
String[] answers2 = new String[6];
String[] answers3 = new String[6];
String[] answers4 = new String[6];
String[] answers5 = new String[6];
String[] answers6 = new String[6];
String[] answers7 = new String[6];
String[] answers8 = new String[6];
String[] answers9 = new String[6];
String[] answers10 = new String[6];
String[] answers11 = new String[6];

StringList[] shuffler = new StringList[11];

StringList shuffler1 = new StringList();
StringList shuffler2 = new StringList();
StringList shuffler3 = new StringList();
StringList shuffler4 = new StringList();
StringList shuffler5 = new StringList();
StringList shuffler6 = new StringList();
StringList shuffler7 = new StringList();
StringList shuffler8 = new StringList();
StringList shuffler9 = new StringList();
StringList shuffler10 = new StringList();
StringList shuffler11 = new StringList();

String[][] answersList = {answers1, answers2, answers3, answers4, answers5, answers6, answers7, answers8, answers9, answers10, answers11};

Score rossScore;
Score phoebeScore;
Score chandlerScore;
Score monicaScore;
Score rachelScore;
Score joeyScore;

IntList scoreList;

//Questions inspired from:
//https://www.beano.com/posts/which-friends-character-are-you
//https://www.radiox.co.uk/games-quizzes/which-friends-character-are-you/
//https://heywise.com/quiz/which-friends-character-are-you/3/
//https://www.zimbio.com/quiz/O6sFuc_NvOh/Friends+Character

String question1 = "What do you consider to be your best quality?";
String question2 = "What is your dream job?";
String question3 = "What do you consider to be your worst quality?";
String question4 = "How do you feel about animals?";
String question5 = "What is your favorite food?";
String question6 = "What is something you cannot live without?";
String question7 = "What do you like to do for fun?";
String question8 = "What pisses you off the most?";
String question9 = "What do you think about marriage?";
String question10 = "Favourite movie genre?";
String question11 = "You value friendship because";

String[] ross = {"Your intelligence","Professor", "Arrogance", "Monkeys are my favorite animals.", "Mashed potatoes with lumps", "Education", "Watching the discovery channel", "Superstitious people", "Cannot get enough of it", "Foreign movies", "Friends are what makes me popular"};
String[] phoebe = {"Your laid back approach to life", "Singer", "Delusional", "Love them! We should not eat them", "Vegetables", "Principles", "Playing with dollhouses", "Arrogance", "Willing to do it once with the right person", "Happy movies", "Friends are the only family I have"};
String[] chandler = {"Your sense of humour", "Advertising executive", "Insecurity", "I do not really like dogs", "Anything but thanksgiving food", "Sarcasm", "Arcade games", "Men wearing makeup", "Freaks me out", "Musicals", "Friends tolerate my awkwardness"};
String[] monica = {"Your cleanliness", "Caterer", "Competitiveness", "They are fine.", "Anything with garlic", "People to boss around", "Competing", "Carelessness", "Ultimate happiness", "Mysteries", "Friends are not afraid to tell me when I am wrong"};
String[] rachel = {"Your good taste", "Fashion consultant", "Selfishness", "Cats with no hair are cool", "Small salads", "Shopping", "Anything but sports", "Touching someone's eye", "Pathetically need it", "Romance", "Friends make the best lovers"};
String[] joey = {"Your looks", "Actor", "Clumsiness", "They taste gooood!", "Fried stuff with cheese", "Food", "Foosball", "Body Shaming", "Not worth it", "Animation", "Friends introduce me to all their hot friends"};

PFont f;
Button button1, button2, button3, button4, button5, button6;
Button start;
Button menu, proceed;
boolean gameOn;
boolean instructions;
boolean end;

SoundFile friends;
SoundFile saturday;

void setup(){
  size(960,720);
  printArray(Serial.list());
  String portname=Serial.list()[2];
  println(portname);
  myPort = new Serial(this,portname,9600);
  myPort.clear();
  myPort.bufferUntil('\n');
  
  f = createFont("GABRWFFR.TTF",72);      //aesthetic font that fits teh theme
  
  start = new Button(width/2, 3*height/4 - 75, 150, 60, 255);
  menu = new Button(width - 100, 50, 150, 60, 255);
  proceed = new Button(width/4, 3*height/4 +50, 200, 80, 0);
  gameOn = false;
  instructions = true;
  end = false;
  
  button1 = new Button(width/6, height/3, 250, 150, #FF4238);
  button2 = new Button(width/2, height/3, 250, 150, #42A2D6);
  button3 = new Button(5*width/6, height/3, 250, 150, #FFDC00);
  button4 = new Button(width/6, height/3 + 3*button1.buttonHeight/2, 250, 150, #FF4238);
  button5 = new Button(width/2, height/3 + 3*button1.buttonHeight/2, 250, 150, #FFDC00);
  button6 = new Button(5*width/6, height/3 + 3*button1.buttonHeight/2, 250, 150, #42A2D6);
  
  for (int i = 0; i<11; i++) {
    answersList[i][0] = ross[i];
    answersList[i][1] = phoebe[i];
    answersList[i][2] = chandler[i];
    answersList[i][3] = monica[i];
    answersList[i][4] = rachel[i];
    answersList[i][5] = joey[i];
    
    //printArray(answersList[i]);
  }
  
  shuffler[0] = shuffler1;
  shuffler[1] = shuffler2;
  shuffler[2] = shuffler3;
  shuffler[3] = shuffler4;
  shuffler[4] = shuffler5;
  shuffler[5] = shuffler6;
  shuffler[6] = shuffler7;
  shuffler[7] = shuffler8;
  shuffler[8] = shuffler9;
  shuffler[9] = shuffler10;
  shuffler[10] = shuffler11;
  
  for (int i = 0; i < 6; i++) {
    shuffler[0].append(answersList[0][i]);
    shuffler[1].append(answersList[1][i]);
    shuffler[2].append(answersList[2][i]);
    shuffler[3].append(answersList[3][i]);
    shuffler[4].append(answersList[4][i]);
    shuffler[5].append(answersList[5][i]);
    shuffler[6].append(answersList[6][i]);
    shuffler[7].append(answersList[7][i]);
    shuffler[8].append(answersList[8][i]);
    shuffler[9].append(answersList[9][i]);
    shuffler[10].append(answersList[10][i]);
  }
  for (int i = 0; i < 11; i++) {
    shuffler[i].shuffle();
    shuffler[i].shuffle();
    shuffler[i].shuffle();
  }
  
  rossScore = new Score();
  phoebeScore = new Score();
  chandlerScore = new Score();
  monicaScore = new Score();
  rachelScore = new Score();
  joeyScore = new Score();
  
  scoreList = new IntList();
  
  rachelBackground = loadImage("rachel.jpg");
  monicaBackground = loadImage("monica.jpg");
  phoebeBackground = loadImage("phoebe.jpg");
  rossBackground = loadImage("ross.jpg");
  chandlerBackground = loadImage("chandler.jpg");
  joeyBackground = loadImage("joey.jpg");
  
  bg1 = loadImage("finalback.jpg");
  bg2 = loadImage("finalback2.png");

  rectMode(CENTER);
  imageMode(CENTER);
  
  friends = new SoundFile(this, "friends2.mp3");
  saturday = new SoundFile(this, "chandler_saturday.mp3");
  friends.loop(); 
  strokeWeight(1);
}


void draw(){
  background(255);
  friends.amp(volume);
  
  if (instructions && !gameOn && !page0) {
    background(bg1);
    start.update(0);
    start.display();
    textFont(f,24); 
    textAlign(CENTER, CENTER);
    fill(255);
    String play = "PLAY";          //text in play button to clarify it
    text(play, start.buttonX , start.buttonY);
    stroke(#E5DCC6);
    fill(#9385B9);
    rect(width/2,height-40,volumeWidth, 30);
    
  }
  else if (page0 && !gameOn && !instructions) {
    background(255);
    image(bg2, width/2, height/2);
    proceed.update(0);
    proceed.buttonColor = color(#9385B9);
    proceed.display();
    textFont(f,24); 
    textAlign(CENTER, CENTER);
    fill(255);
    String cont = "CONTINUE";          //text in play button to clarify it
    text(cont, proceed.buttonX , proceed.buttonY);
    stroke(#E5DCC6);
    fill(#9385B9);
    rect(width/2,height-40,volumeWidth, 30);
  }
  else if (gameOn) {
    background(#9385B9);
    button1.update(choice1);
    button1.display();
    button2.update(choice2);
    button2.display();
    button3.update(choice3);
    button3.display();
    button4.update(choice4);
    button4.display();
    button5.update(choice5);
    button5.display();
    button6.update(choice6);
    button6.display();
    
    if (page1) {
      textFont(f,35); 
      textAlign(CENTER, CENTER);
      fill(0);
      text(question1, width/2, height/8);
      textFont(f,22); 
      fill(255); 
      String one1 = shuffler[0].get(0);
      String two1 = shuffler[0].get(1);
      String three1 = shuffler[0].get(2);
      String four1 = shuffler[0].get(3);
      String five1 = shuffler[0].get(4);
      String six1 = shuffler[0].get(5);
      
      text(one1, button1.buttonX , button1.buttonY, button1.buttonWidth - 20, button1.buttonHeight-10);
      text(two1, button2.buttonX , button2.buttonY, button2.buttonWidth - 20, button2.buttonHeight-10);
      text(three1, button3.buttonX , button3.buttonY, button3.buttonWidth -20, button3.buttonHeight-10);
      text(four1, button4.buttonX , button4.buttonY, button4.buttonWidth-20, button4.buttonHeight-10);
      text(five1, button5.buttonX , button5.buttonY, button5.buttonWidth-20, button5.buttonHeight-10);
      text(six1, button6.buttonX , button6.buttonY, button6.buttonWidth-20, button6.buttonHeight-10);
      
      if (choice1 == 1 || choice2 == 1 || choice3 == 1 || choice4 == 1 || choice5 == 1|| choice6 == 1) {
        
        if (frameCount - prevFrame > 40) {      //only allow jumping constantly after certain number of frames
          prevFrame = frameCount;       
          if (choice1 ==1 && !(choice2 == 1 || choice3 == 1 || choice4 == 1 || choice5 == 1|| choice6 == 1)) {
            checker(one1, 0, rossScore, phoebeScore, chandlerScore, monicaScore, rachelScore, joeyScore);
            page2 = true; 
            page1 = false;
          }
          else if (choice2 ==1 && !(choice1 == 1 || choice3 == 1 || choice4 == 1 || choice5 == 1|| choice6 == 1)) {
            checker(two1, 0, rossScore, phoebeScore, chandlerScore, monicaScore, rachelScore, joeyScore);
            page2 = true; 
            page1 = false;  
          }
          else if (choice3 ==1 && !(choice2 == 1 || choice1 == 1 || choice4 == 1 || choice5 == 1|| choice6 == 1)) {
            checker(three1, 0, rossScore, phoebeScore, chandlerScore, monicaScore, rachelScore, joeyScore);
            page2 = true; 
            page1 = false;  
          }
          else if (choice4 ==1 && !(choice2 == 1 || choice3 == 1 || choice1 == 1 || choice5 == 1|| choice6 == 1)) {
            checker(four1, 0, rossScore, phoebeScore, chandlerScore, monicaScore, rachelScore, joeyScore);
            page2 = true; 
            page1 = false;  
          }
          else if (choice5 ==1 && !(choice2 == 1 || choice3 == 1 || choice4 == 1 || choice1 == 1|| choice6 == 1)) {
            checker(five1, 0, rossScore, phoebeScore, chandlerScore, monicaScore, rachelScore, joeyScore);
            page2 = true; 
            page1 = false;  
          }
          else if (choice6 ==1 && !(choice2 == 1 || choice3 == 1 || choice4 == 1 || choice5 == 1|| choice1 == 1)) {
            checker(six1, 0, rossScore, phoebeScore, chandlerScore, monicaScore, rachelScore, joeyScore);
            page2 = true; 
            page1 = false;  
          }
        }    
      }   
    }
   else if (page2) {
      textFont(f,35); 
      textAlign(CENTER, CENTER);
      fill(0);
      text(question2, width/2, height/8, width - 100);
      textFont(f,22); 
      fill(255); 
      String one2 = shuffler[1].get(0);
      String two2 = shuffler[1].get(1);
      String three2 = shuffler[1].get(2);
      String four2 = shuffler[1].get(3);
      String five2 = shuffler[1].get(4);
      String six2 = shuffler[1].get(5);
      
      text(one2, button1.buttonX , button1.buttonY, button1.buttonWidth - 20, button1.buttonHeight-10);
      text(two2, button2.buttonX , button2.buttonY, button2.buttonWidth - 20, button2.buttonHeight-10);
      text(three2, button3.buttonX , button3.buttonY, button3.buttonWidth -20, button3.buttonHeight-10);
      text(four2, button4.buttonX , button4.buttonY, button4.buttonWidth-20, button4.buttonHeight-10);
      text(five2, button5.buttonX , button5.buttonY, button5.buttonWidth-20, button5.buttonHeight-10);
      text(six2, button6.buttonX , button6.buttonY, button6.buttonWidth-20, button6.buttonHeight-10);
      
      if (choice1 == 1 || choice2 == 1 || choice3 == 1 || choice4 == 1 || choice5 == 1|| choice6 == 1) {
        
        if (frameCount - prevFrame > 40) {      //only allow jumping constantly after certain number of frames
          prevFrame = frameCount;
          if (choice1 ==1 && !(choice2 == 1 || choice3 == 1 || choice4 == 1 || choice5 == 1|| choice6 == 1)) {
            checker(one2, 1, rossScore, phoebeScore, chandlerScore, monicaScore, rachelScore, joeyScore);
            page3 = true; 
            page2 = false;
          }
          else if (choice2 ==1 && !(choice1 == 1 || choice3 == 1 || choice4 == 1 || choice5 == 1|| choice6 == 1)) {
            checker(two2, 1, rossScore, phoebeScore, chandlerScore, monicaScore, rachelScore, joeyScore);
            page3 = true; 
            page2 = false;  
          }
          else if (choice3 ==1 && !(choice2 == 1 || choice1 == 1 || choice4 == 1 || choice5 == 1|| choice6 == 1)) {
            checker(three2, 1, rossScore, phoebeScore, chandlerScore, monicaScore, rachelScore, joeyScore);
            page3 = true; 
            page2 = false;  
          }
          else if (choice4 ==1 && !(choice2 == 1 || choice3 == 1 || choice1 == 1 || choice5 == 1|| choice6 == 1)) {
            checker(four2, 1, rossScore, phoebeScore, chandlerScore, monicaScore, rachelScore, joeyScore);
            page3 = true; 
            page2 = false;  
          }
          else if (choice5 ==1 && !(choice2 == 1 || choice3 == 1 || choice4 == 1 || choice1 == 1|| choice6 == 1)) {
            checker(five2, 1, rossScore, phoebeScore, chandlerScore, monicaScore, rachelScore, joeyScore);
            page3 = true; 
            page2 = false;  
          }
          else if (choice6 ==1 && !(choice2 == 1 || choice3 == 1 || choice4 == 1 || choice5 == 1|| choice1 == 1)) {
            checker(six2, 1, rossScore, phoebeScore, chandlerScore, monicaScore, rachelScore, joeyScore);
            page3 = true; 
            page2 = false;  
          }
        }
        
        
      }
   }
   else if (page3) {
     textFont(f,35); 
      textAlign(CENTER, CENTER);
      fill(0);
      text(question3, width/2, height/8);
      textFont(f,22); 
      fill(255); 
      String one3 = shuffler[2].get(0);
      String two3 = shuffler[2].get(1);
      String three3 = shuffler[2].get(2);
      String four3 = shuffler[2].get(3);
      String five3 = shuffler[2].get(4);
      String six3 = shuffler[2].get(5);
      
      text(one3, button1.buttonX , button1.buttonY, button1.buttonWidth - 20, button1.buttonHeight-10);
      text(two3, button2.buttonX , button2.buttonY, button2.buttonWidth - 20, button2.buttonHeight-10);
      text(three3, button3.buttonX , button3.buttonY, button3.buttonWidth -20, button3.buttonHeight-10);
      text(four3, button4.buttonX , button4.buttonY, button4.buttonWidth-20, button4.buttonHeight-10);
      text(five3, button5.buttonX , button5.buttonY, button5.buttonWidth-20, button5.buttonHeight-10);
      text(six3, button6.buttonX , button6.buttonY, button6.buttonWidth-20, button6.buttonHeight-10);
      
      if (choice1 == 1 || choice2 == 1 || choice3 == 1 || choice4 == 1 || choice5 == 1|| choice6 == 1) {
        
        if (frameCount - prevFrame > 40) {      //only allow jumping constantly after certain number of frames
          prevFrame = frameCount;
          if (choice1 ==1 && !(choice2 == 1 || choice3 == 1 || choice4 == 1 || choice5 == 1|| choice6 == 1)) {
            checker(one3, 2, rossScore, phoebeScore, chandlerScore, monicaScore, rachelScore, joeyScore);
            page4 = true; 
            page3 = false;
          }
          else if (choice2 ==1 && !(choice1 == 1 || choice3 == 1 || choice4 == 1 || choice5 == 1|| choice6 == 1)) {
            checker(two3, 2, rossScore, phoebeScore, chandlerScore, monicaScore, rachelScore, joeyScore);
            page4 = true; 
            page3 = false;  
          }
          else if (choice3 ==1 && !(choice2 == 1 || choice1 == 1 || choice4 == 1 || choice5 == 1|| choice6 == 1)) {
            checker(three3, 2, rossScore, phoebeScore, chandlerScore, monicaScore, rachelScore, joeyScore);
            page4 = true; 
            page3 = false;  
          }
          else if (choice4 ==1 && !(choice2 == 1 || choice3 == 1 || choice1 == 1 || choice5 == 1|| choice6 == 1)) {
            checker(four3, 2, rossScore, phoebeScore, chandlerScore, monicaScore, rachelScore, joeyScore);
            page4 = true; 
            page3 = false;  
          }
          else if (choice5 ==1 && !(choice2 == 1 || choice3 == 1 || choice4 == 1 || choice1 == 1|| choice6 == 1)) {
            checker(five3, 2, rossScore, phoebeScore, chandlerScore, monicaScore, rachelScore, joeyScore);
            page4 = true; 
            page3 = false;  
          }
          else if (choice6 ==1 && !(choice2 == 1 || choice3 == 1 || choice4 == 1 || choice5 == 1|| choice1 == 1)) {
            checker(six3, 2, rossScore, phoebeScore, chandlerScore, monicaScore, rachelScore, joeyScore);
            page4 = true; 
            page3 = false;  
          }
        }
        
        
      }
   }
   else if (page4) {
     textFont(f,35); 
      textAlign(CENTER, CENTER);
      fill(0);
      text(question4, width/2, height/8);
      textFont(f,22); 
      fill(255); 
      String one4 = shuffler[3].get(0);
      String two4 = shuffler[3].get(1);
      String three4 = shuffler[3].get(2);
      String four4 = shuffler[3].get(3);
      String five4 = shuffler[3].get(4);
      String six4 = shuffler[3].get(5);
      
      text(one4, button1.buttonX , button1.buttonY, button1.buttonWidth - 20, button1.buttonHeight-10);
      text(two4, button2.buttonX , button2.buttonY, button2.buttonWidth - 20, button2.buttonHeight-10);
      text(three4, button3.buttonX , button3.buttonY, button3.buttonWidth -20, button3.buttonHeight-10);
      text(four4, button4.buttonX , button4.buttonY, button4.buttonWidth-20, button4.buttonHeight-10);
      text(five4, button5.buttonX , button5.buttonY, button5.buttonWidth-20, button5.buttonHeight-10);
      text(six4, button6.buttonX , button6.buttonY, button6.buttonWidth-20, button6.buttonHeight-10);
      
      if (choice1 == 1 || choice2 == 1 || choice3 == 1 || choice4 == 1 || choice5 == 1|| choice6 == 1) {
        
        if (frameCount - prevFrame > 40) {      //only allow jumping constantly after certain number of frames
          prevFrame = frameCount;
          if (choice1 ==1 && !(choice2 == 1 || choice3 == 1 || choice4 == 1 || choice5 == 1|| choice6 == 1)) {
            checker(one4, 3, rossScore, phoebeScore, chandlerScore, monicaScore, rachelScore, joeyScore);
            page5 = true; 
            page4 = false;
          }
          else if (choice2 ==1 && !(choice1 == 1 || choice3 == 1 || choice4 == 1 || choice5 == 1|| choice6 == 1)) {
            checker(two4, 3, rossScore, phoebeScore, chandlerScore, monicaScore, rachelScore, joeyScore);
            page5 = true; 
            page4 = false;  
          }
          else if (choice3 ==1 && !(choice2 == 1 || choice1 == 1 || choice4 == 1 || choice5 == 1|| choice6 == 1)) {
            checker(three4, 3, rossScore, phoebeScore, chandlerScore, monicaScore, rachelScore, joeyScore);
            page5 = true; 
            page4 = false;  
          }
          else if (choice4 ==1 && !(choice2 == 1 || choice3 == 1 || choice1 == 1 || choice5 == 1|| choice6 == 1)) {
            checker(four4, 3, rossScore, phoebeScore, chandlerScore, monicaScore, rachelScore, joeyScore);
            page5 = true; 
            page4 = false;  
          }
          else if (choice5 ==1 && !(choice2 == 1 || choice3 == 1 || choice4 == 1 || choice1 == 1|| choice6 == 1)) {
            checker(five4, 3, rossScore, phoebeScore, chandlerScore, monicaScore, rachelScore, joeyScore);
           page5 = true; 
            page4 = false;  
          }
          else if (choice6 ==1 && !(choice2 == 1 || choice3 == 1 || choice4 == 1 || choice5 == 1|| choice1 == 1)) {
            checker(six4, 3, rossScore, phoebeScore, chandlerScore, monicaScore, rachelScore, joeyScore);
            page5 = true; 
            page4 = false;  
          }
        }
        
        
      }
   }
   else if (page5) {
     textFont(f,35); 
      textAlign(CENTER, CENTER);
      fill(0);
      text(question5, width/2, height/8);
      textFont(f,22); 
      fill(255); 
      String one5 = shuffler[4].get(0);
      String two5 = shuffler[4].get(1);
      String three5 = shuffler[4].get(2);
      String four5 = shuffler[4].get(3);
      String five5 = shuffler[4].get(4);
      String six5 = shuffler[4].get(5);
      
      text(one5, button1.buttonX , button1.buttonY, button1.buttonWidth - 20, button1.buttonHeight-10);
      text(two5, button2.buttonX , button2.buttonY, button2.buttonWidth - 20, button2.buttonHeight-10);
      text(three5, button3.buttonX , button3.buttonY, button3.buttonWidth -20, button3.buttonHeight-10);
      text(four5, button4.buttonX , button4.buttonY, button4.buttonWidth-20, button4.buttonHeight-10);
      text(five5, button5.buttonX , button5.buttonY, button5.buttonWidth-20, button5.buttonHeight-10);
      text(six5, button6.buttonX , button6.buttonY, button6.buttonWidth-20, button6.buttonHeight-10);
      
      if (choice1 == 1 || choice2 == 1 || choice3 == 1 || choice4 == 1 || choice5 == 1|| choice6 == 1) {
        
        if (frameCount - prevFrame > 40) {      //only allow jumping constantly after certain number of frames
          prevFrame = frameCount;
          if (choice1 ==1 && !(choice2 == 1 || choice3 == 1 || choice4 == 1 || choice5 == 1|| choice6 == 1)) {
            checker(one5, 4, rossScore, phoebeScore, chandlerScore, monicaScore, rachelScore, joeyScore);
            page6 = true; 
            page5 = false;
          }
          else if (choice2 ==1 && !(choice1 == 1 || choice3 == 1 || choice4 == 1 || choice5 == 1|| choice6 == 1)) {
            checker(two5, 4, rossScore, phoebeScore, chandlerScore, monicaScore, rachelScore, joeyScore);
            page6 = true; 
            page5 = false;  
          }
          else if (choice3 ==1 && !(choice2 == 1 || choice1 == 1 || choice4 == 1 || choice5 == 1|| choice6 == 1)) {
            checker(three5, 4, rossScore, phoebeScore, chandlerScore, monicaScore, rachelScore, joeyScore);
            page6 = true; 
            page5 = false;  
          }
          else if (choice4 ==1 && !(choice2 == 1 || choice3 == 1 || choice1 == 1 || choice5 == 1|| choice6 == 1)) {
            checker(four5, 4, rossScore, phoebeScore, chandlerScore, monicaScore, rachelScore, joeyScore);
            page6 = true; 
            page5 = false;  
          }
          else if (choice5 ==1 && !(choice2 == 1 || choice3 == 1 || choice4 == 1 || choice1 == 1|| choice6 == 1)) {
            checker(five5, 4, rossScore, phoebeScore, chandlerScore, monicaScore, rachelScore, joeyScore);
            page6 = true; 
            page5 = false;  
          }
          else if (choice6 ==1 && !(choice2 == 1 || choice3 == 1 || choice4 == 1 || choice5 == 1|| choice1 == 1)) {
            checker(six5, 4, rossScore, phoebeScore, chandlerScore, monicaScore, rachelScore, joeyScore);
            page6 = true; 
            page5 = false;  
          }
        }
        
        
      }
   }
   else if (page6) {
     textFont(f,35); 
      textAlign(CENTER, CENTER);
      fill(0);
      text(question6, width/2, height/8);
      textFont(f,22); 
      fill(255); 
      String one6 = shuffler[5].get(0);
      String two6 = shuffler[5].get(1);
      String three6 = shuffler[5].get(2);
      String four6 = shuffler[5].get(3);
      String five6 = shuffler[5].get(4);
      String six6 = shuffler[5].get(5);
      
      text(one6, button1.buttonX , button1.buttonY, button1.buttonWidth - 20, button1.buttonHeight-10);
      text(two6, button2.buttonX , button2.buttonY, button2.buttonWidth - 20, button2.buttonHeight-10);
      text(three6, button3.buttonX , button3.buttonY, button3.buttonWidth -20, button3.buttonHeight-10);
      text(four6, button4.buttonX , button4.buttonY, button4.buttonWidth-20, button4.buttonHeight-10);
      text(five6, button5.buttonX , button5.buttonY, button5.buttonWidth-20, button5.buttonHeight-10);
      text(six6, button6.buttonX , button6.buttonY, button6.buttonWidth-20, button6.buttonHeight-10);
      
      if (choice1 == 1 || choice2 == 1 || choice3 == 1 || choice4 == 1 || choice5 == 1|| choice6 == 1) {
        
        if (frameCount - prevFrame > 40) {      //only allow jumping constantly after certain number of frames
          prevFrame = frameCount;
          if (choice1 ==1 && !(choice2 == 1 || choice3 == 1 || choice4 == 1 || choice5 == 1|| choice6 == 1)) {
            checker(one6, 5, rossScore, phoebeScore, chandlerScore, monicaScore, rachelScore, joeyScore);
            page7 = true; 
            page6 = false;
          }
          else if (choice2 ==1 && !(choice1 == 1 || choice3 == 1 || choice4 == 1 || choice5 == 1|| choice6 == 1)) {
            checker(two6, 5, rossScore, phoebeScore, chandlerScore, monicaScore, rachelScore, joeyScore);
            page7 = true; 
            page6 = false;  
          }
          else if (choice3 ==1 && !(choice2 == 1 || choice1 == 1 || choice4 == 1 || choice5 == 1|| choice6 == 1)) {
            checker(three6, 5, rossScore, phoebeScore, chandlerScore, monicaScore, rachelScore, joeyScore);
            page7 = true; 
            page6 = false;  
          }
          else if (choice4 ==1 && !(choice2 == 1 || choice3 == 1 || choice1 == 1 || choice5 == 1|| choice6 == 1)) {
            checker(four6, 5, rossScore, phoebeScore, chandlerScore, monicaScore, rachelScore, joeyScore);
            page7 = true; 
            page6 = false;  
          }
          else if (choice5 ==1 && !(choice2 == 1 || choice3 == 1 || choice4 == 1 || choice1 == 1|| choice6 == 1)) {
            checker(five6, 5, rossScore, phoebeScore, chandlerScore, monicaScore, rachelScore, joeyScore);
            page7 = true; 
            page6 = false;  
          }
          else if (choice6 ==1 && !(choice2 == 1 || choice3 == 1 || choice4 == 1 || choice5 == 1|| choice1 == 1)) {
            checker(six6, 5, rossScore, phoebeScore, chandlerScore, monicaScore, rachelScore, joeyScore);
            page7 = true; 
            page6 = false;  
          }
        }
        
        
      }
   }
   else if (page7) {
     textFont(f,35); 
      textAlign(CENTER, CENTER);
      fill(0);
      text(question7, width/2, height/8);
      textFont(f,22); 
      fill(255); 
      String one7 = shuffler[6].get(0);
      String two7 = shuffler[6].get(1);
      String three7 = shuffler[6].get(2);
      String four7 = shuffler[6].get(3);
      String five7 = shuffler[6].get(4);
      String six7 = shuffler[6].get(5);
      
      text(one7, button1.buttonX , button1.buttonY, button1.buttonWidth - 20, button1.buttonHeight-10);
      text(two7, button2.buttonX , button2.buttonY, button2.buttonWidth - 20, button2.buttonHeight-10);
      text(three7, button3.buttonX , button3.buttonY, button3.buttonWidth -20, button3.buttonHeight-10);
      text(four7, button4.buttonX , button4.buttonY, button4.buttonWidth-20, button4.buttonHeight-10);
      text(five7, button5.buttonX , button5.buttonY, button5.buttonWidth-20, button5.buttonHeight-10);
      text(six7, button6.buttonX , button6.buttonY, button6.buttonWidth-20, button6.buttonHeight-10);
      
      if (choice1 == 1 || choice2 == 1 || choice3 == 1 || choice4 == 1 || choice5 == 1|| choice6 == 1) {
        
        if (frameCount - prevFrame > 40) {      //only allow jumping constantly after certain number of frames
          prevFrame = frameCount;
          if (choice1 ==1 && !(choice2 == 1 || choice3 == 1 || choice4 == 1 || choice5 == 1|| choice6 == 1)) {
            checker(one7, 6, rossScore, phoebeScore, chandlerScore, monicaScore, rachelScore, joeyScore);
            page8 = true; 
            page7 = false;
          }
          else if (choice2 ==1 && !(choice1 == 1 || choice3 == 1 || choice4 == 1 || choice5 == 1|| choice6 == 1)) {
            checker(two7, 6, rossScore, phoebeScore, chandlerScore, monicaScore, rachelScore, joeyScore);
            page8 = true; 
            page7 = false;  
          }
          else if (choice3 ==1 && !(choice2 == 1 || choice1 == 1 || choice4 == 1 || choice5 == 1|| choice6 == 1)) {
            checker(three7, 6, rossScore, phoebeScore, chandlerScore, monicaScore, rachelScore, joeyScore);
            page8 = true; 
            page7 = false;  
          }
          else if (choice4 ==1 && !(choice2 == 1 || choice3 == 1 || choice1 == 1 || choice5 == 1|| choice6 == 1)) {
            checker(four7, 6, rossScore, phoebeScore, chandlerScore, monicaScore, rachelScore, joeyScore);
            page8 = true; 
            page7 = false;  
          }
          else if (choice5 ==1 && !(choice2 == 1 || choice3 == 1 || choice4 == 1 || choice1 == 1|| choice6 == 1)) {
            checker(five7, 6, rossScore, phoebeScore, chandlerScore, monicaScore, rachelScore, joeyScore);
            page8 = true; 
            page7 = false;  
          }
          else if (choice6 ==1 && !(choice2 == 1 || choice3 == 1 || choice4 == 1 || choice5 == 1|| choice1 == 1)) {
            checker(six7, 6, rossScore, phoebeScore, chandlerScore, monicaScore, rachelScore, joeyScore);
            page8 = true; 
            page7 = false;  
          }
        }
        
        
      }
   }
   else if (page8) {
     textFont(f,35); 
      textAlign(CENTER, CENTER);
      fill(0);
      text(question8, width/2, height/8);
      textFont(f,22); 
      fill(255); 
      String one8 = shuffler[7].get(0);
      String two8 = shuffler[7].get(1);
      String three8 = shuffler[7].get(2);
      String four8 = shuffler[7].get(3);
      String five8 = shuffler[7].get(4);
      String six8 = shuffler[7].get(5);
      
      text(one8, button1.buttonX , button1.buttonY, button1.buttonWidth - 20, button1.buttonHeight-10);
      text(two8, button2.buttonX , button2.buttonY, button2.buttonWidth - 20, button2.buttonHeight-10);
      text(three8, button3.buttonX , button3.buttonY, button3.buttonWidth -20, button3.buttonHeight-10);
      text(four8, button4.buttonX , button4.buttonY, button4.buttonWidth-20, button4.buttonHeight-10);
      text(five8, button5.buttonX , button5.buttonY, button5.buttonWidth-20, button5.buttonHeight-10);
      text(six8, button6.buttonX , button6.buttonY, button6.buttonWidth-20, button6.buttonHeight-10);
      
      if (choice1 == 1 || choice2 == 1 || choice3 == 1 || choice4 == 1 || choice5 == 1|| choice6 == 1) {
        
        if (frameCount - prevFrame > 40) {      //only allow jumping constantly after certain number of frames
          prevFrame = frameCount;
          if (choice1 ==1 && !(choice2 == 1 || choice3 == 1 || choice4 == 1 || choice5 == 1|| choice6 == 1)) {
            checker(one8, 7, rossScore, phoebeScore, chandlerScore, monicaScore, rachelScore, joeyScore);
            page9 = true; 
            page8 = false;
          }
          else if (choice2 ==1 && !(choice1 == 1 || choice3 == 1 || choice4 == 1 || choice5 == 1|| choice6 == 1)) {
            checker(two8, 7, rossScore, phoebeScore, chandlerScore, monicaScore, rachelScore, joeyScore);
            page9 = true; 
            page8 = false;  
          }
          else if (choice3 ==1 && !(choice2 == 1 || choice1 == 1 || choice4 == 1 || choice5 == 1|| choice6 == 1)) {
            checker(three8, 7, rossScore, phoebeScore, chandlerScore, monicaScore, rachelScore, joeyScore);
            page9 = true; 
            page8 = false;  
          }
          else if (choice4 ==1 && !(choice2 == 1 || choice3 == 1 || choice1 == 1 || choice5 == 1|| choice6 == 1)) {
            checker(four8, 7, rossScore, phoebeScore, chandlerScore, monicaScore, rachelScore, joeyScore);
            page9 = true; 
            page8 = false;  
          }
          else if (choice5 ==1 && !(choice2 == 1 || choice3 == 1 || choice4 == 1 || choice1 == 1|| choice6 == 1)) {
            checker(five8, 7, rossScore, phoebeScore, chandlerScore, monicaScore, rachelScore, joeyScore);
            page9 = true; 
            page8 = false;  
          }
          else if (choice6 ==1 && !(choice2 == 1 || choice3 == 1 || choice4 == 1 || choice5 == 1|| choice1 == 1)) {
            checker(six8, 7, rossScore, phoebeScore, chandlerScore, monicaScore, rachelScore, joeyScore);
            page9 = true; 
            page8 = false;  
          }
        }
        
        
      }
   }
   else if (page9) {
   textFont(f,35); 
      textAlign(CENTER, CENTER);
      fill(0);
      text(question9, width/2, height/8);
      textFont(f,22); 
      fill(255); 
      String one9 = shuffler[8].get(0);
      String two9 = shuffler[8].get(1);
      String three9 = shuffler[8].get(2);
      String four9 = shuffler[8].get(3);
      String five9 = shuffler[8].get(4);
      String six9 = shuffler[8].get(5);
      
      text(one9, button1.buttonX , button1.buttonY, button1.buttonWidth - 20, button1.buttonHeight-10);
      text(two9, button2.buttonX , button2.buttonY, button2.buttonWidth - 20, button2.buttonHeight-10);
      text(three9, button3.buttonX , button3.buttonY, button3.buttonWidth -20, button3.buttonHeight-10);
      text(four9, button4.buttonX , button4.buttonY, button4.buttonWidth-20, button4.buttonHeight-10);
      text(five9, button5.buttonX , button5.buttonY, button5.buttonWidth-20, button5.buttonHeight-10);
      text(six9, button6.buttonX , button6.buttonY, button6.buttonWidth-20, button6.buttonHeight-10);
      
      if (choice1 == 1 || choice2 == 1 || choice3 == 1 || choice4 == 1 || choice5 == 1|| choice6 == 1) {
        
        if (frameCount - prevFrame > 40) {      //only allow jumping constantly after certain number of frames
          prevFrame = frameCount;
          if (choice1 ==1 && !(choice2 == 1 || choice3 == 1 || choice4 == 1 || choice5 == 1|| choice6 == 1)) {
            checker(one9, 8, rossScore, phoebeScore, chandlerScore, monicaScore, rachelScore, joeyScore);
            page10 = true; 
            page9 = false;
          }
          else if (choice2 ==1 && !(choice1 == 1 || choice3 == 1 || choice4 == 1 || choice5 == 1|| choice6 == 1)) {
            checker(two9, 8, rossScore, phoebeScore, chandlerScore, monicaScore, rachelScore, joeyScore);
            page10 = true; 
            page9 = false;  
          }
          else if (choice3 ==1 && !(choice2 == 1 || choice1 == 1 || choice4 == 1 || choice5 == 1|| choice6 == 1)) {
            checker(three9, 8, rossScore, phoebeScore, chandlerScore, monicaScore, rachelScore, joeyScore);
            page10 = true; 
            page9 = false;  
          }
          else if (choice4 ==1 && !(choice2 == 1 || choice3 == 1 || choice1 == 1 || choice5 == 1|| choice6 == 1)) {
            checker(four9, 8, rossScore, phoebeScore, chandlerScore, monicaScore, rachelScore, joeyScore);
            page10 = true; 
            page9 = false;  
          }
          else if (choice5 ==1 && !(choice2 == 1 || choice3 == 1 || choice4 == 1 || choice1 == 1|| choice6 == 1)) {
            checker(five9, 8, rossScore, phoebeScore, chandlerScore, monicaScore, rachelScore, joeyScore);
            page10 = true; 
            page9 = false;  
          }
          else if (choice6 ==1 && !(choice2 == 1 || choice3 == 1 || choice4 == 1 || choice5 == 1|| choice1 == 1)) {
            checker(six9, 8, rossScore, phoebeScore, chandlerScore, monicaScore, rachelScore, joeyScore);
            page10 = true; 
            page9 = false;  
          }
        }
        
        
      }
   }
   else if (page10) {
   textFont(f,35); 
      textAlign(CENTER, CENTER);
      fill(0);
      text(question10, width/2, height/8);
      textFont(f,22); 
      fill(255); 
      String one10 = shuffler[9].get(0);
      String two10 = shuffler[9].get(1);
      String three10 = shuffler[9].get(2);
      String four10 = shuffler[9].get(3);
      String five10 = shuffler[9].get(4);
      String six10 = shuffler[9].get(5);
      
      text(one10, button1.buttonX , button1.buttonY, button1.buttonWidth - 20, button1.buttonHeight-10);
      text(two10, button2.buttonX , button2.buttonY, button2.buttonWidth - 20, button2.buttonHeight-10);
      text(three10, button3.buttonX , button3.buttonY, button3.buttonWidth -20, button3.buttonHeight-10);
      text(four10, button4.buttonX , button4.buttonY, button4.buttonWidth-20, button4.buttonHeight-10);
      text(five10, button5.buttonX , button5.buttonY, button5.buttonWidth-20, button5.buttonHeight-10);
      text(six10, button6.buttonX , button6.buttonY, button6.buttonWidth-20, button6.buttonHeight-10);
      
      if (choice1 == 1 || choice2 == 1 || choice3 == 1 || choice4 == 1 || choice5 == 1|| choice6 == 1) {
        
        if (frameCount - prevFrame > 40) {      //only allow jumping constantly after certain number of frames
          prevFrame = frameCount;
          if (choice1 ==1 && !(choice2 == 1 || choice3 == 1 || choice4 == 1 || choice5 == 1|| choice6 == 1)) {
            checker(one10, 9, rossScore, phoebeScore, chandlerScore, monicaScore, rachelScore, joeyScore);
            page11 = true; 
            page10 = false;
          }
          else if (choice2 ==1 && !(choice1 == 1 || choice3 == 1 || choice4 == 1 || choice5 == 1|| choice6 == 1)) {
            checker(two10, 9, rossScore, phoebeScore, chandlerScore, monicaScore, rachelScore, joeyScore);
            page11 = true; 
            page10 = false;  
          }
          else if (choice3 ==1 && !(choice2 == 1 || choice1 == 1 || choice4 == 1 || choice5 == 1|| choice6 == 1)) {
            checker(three10, 9, rossScore, phoebeScore, chandlerScore, monicaScore, rachelScore, joeyScore);
            page11 = true; 
            page10 = false;  
          }
          else if (choice4 ==1 && !(choice2 == 1 || choice3 == 1 || choice1 == 1 || choice5 == 1|| choice6 == 1)) {
            checker(four10, 9, rossScore, phoebeScore, chandlerScore, monicaScore, rachelScore, joeyScore);
            page11 = true; 
            page10 = false;  
          }
          else if (choice5 ==1 && !(choice2 == 1 || choice3 == 1 || choice4 == 1 || choice1 == 1|| choice6 == 1)) {
            checker(five10, 9, rossScore, phoebeScore, chandlerScore, monicaScore, rachelScore, joeyScore);
            page11 = true; 
            page10 = false;  
          }
          else if (choice6 ==1 && !(choice2 == 1 || choice3 == 1 || choice4 == 1 || choice5 == 1|| choice1 == 1)) {
            checker(six10, 9, rossScore, phoebeScore, chandlerScore, monicaScore, rachelScore, joeyScore);
            page11 = true; 
            page10 = false;  
          }
        }
        
        
      }
   }
   else if (page11) {
     textFont(f,35); 
      textAlign(CENTER, CENTER);
      fill(0);
      text(question11, width/2, height/8);
      textFont(f,22); 
      fill(255); 
      String one11 = shuffler[10].get(0);
      String two11 = shuffler[10].get(1);
      String three11 = shuffler[10].get(2);
      String four11 = shuffler[10].get(3);
      String five11 = shuffler[10].get(4);
      String six11 = shuffler[10].get(5);
      
      text(one11, button1.buttonX , button1.buttonY, button1.buttonWidth - 20, button1.buttonHeight-10);
      text(two11, button2.buttonX , button2.buttonY, button2.buttonWidth - 20, button2.buttonHeight-10);
      text(three11, button3.buttonX , button3.buttonY, button3.buttonWidth -20, button3.buttonHeight-10);
      text(four11, button4.buttonX , button4.buttonY, button4.buttonWidth-20, button4.buttonHeight-10);
      text(five11, button5.buttonX , button5.buttonY, button5.buttonWidth-20, button5.buttonHeight-10);
      text(six11, button6.buttonX , button6.buttonY, button6.buttonWidth-20, button6.buttonHeight-10);
      
      if (choice1 == 1 || choice2 == 1 || choice3 == 1 || choice4 == 1 || choice5 == 1|| choice6 == 1) {
        
        if (frameCount - prevFrame > 40) {      //only allow jumping constantly after certain number of frames
          prevFrame = frameCount;
          if (choice1 ==1 && !(choice2 == 1 || choice3 == 1 || choice4 == 1 || choice5 == 1|| choice6 == 1)) {
            checker(one11, 10, rossScore, phoebeScore, chandlerScore, monicaScore, rachelScore, joeyScore);
            end = true;
            gameOn = false;
            page11 = false;
          }
          else if (choice2 ==1 && !(choice1 == 1 || choice3 == 1 || choice4 == 1 || choice5 == 1|| choice6 == 1)) {
            checker(two11, 10, rossScore, phoebeScore, chandlerScore, monicaScore, rachelScore, joeyScore);
            end = true;
            gameOn = false;
            page11 = false;  
          }
          else if (choice3 ==1 && !(choice2 == 1 || choice1 == 1 || choice4 == 1 || choice5 == 1|| choice6 == 1)) {
            checker(three11, 10, rossScore, phoebeScore, chandlerScore, monicaScore, rachelScore, joeyScore);
            end = true;
            gameOn = false;
            page11 = false;  
          }
          else if (choice4 ==1 && !(choice2 == 1 || choice3 == 1 || choice1 == 1 || choice5 == 1|| choice6 == 1)) {
            checker(four11, 10, rossScore, phoebeScore, chandlerScore, monicaScore, rachelScore, joeyScore);
            end = true;
            gameOn = false;
            page11 = false;  
          }
          else if (choice5 ==1 && !(choice2 == 1 || choice3 == 1 || choice4 == 1 || choice1 == 1|| choice6 == 1)) {
            checker(five11, 10, rossScore, phoebeScore, chandlerScore, monicaScore, rachelScore, joeyScore);
            end = true;
            gameOn = false;
            page11 = false;  
          }
          else if (choice6 ==1 && !(choice2 == 1 || choice3 == 1 || choice4 == 1 || choice5 == 1|| choice1 == 1)) {
            checker(six11, 10, rossScore, phoebeScore, chandlerScore, monicaScore, rachelScore, joeyScore);
            end = true;
            gameOn = false;
            page11 = false;  
          }
        }  
      }
    }
    stroke(#E5DCC6);
    fill(#9385B9);
    rect(width/2,height-40,volumeWidth, 30);
  }
  
  else if (end && !gameOn) {
   scoreList.append(rossScore.value);
   scoreList.append(phoebeScore.value);
   scoreList.append(monicaScore.value);
   scoreList.append(chandlerScore.value);
   scoreList.append(joeyScore.value);
   scoreList.append(rachelScore.value);
   
   if (scoreList.max() == rossScore.value) {background(rossBackground);}
   else if (scoreList.max() == phoebeScore.value) {background(phoebeBackground);}
   else if (scoreList.max() == monicaScore.value) {background(monicaBackground);}
   else if (scoreList.max() == chandlerScore.value) 
     {
       background(chandlerBackground);
       
     }
   else if (scoreList.max() == joeyScore.value) {background(joeyBackground);}
   else {background(rachelBackground);}
   
   menu.update(0);
   menu.buttonColor = color(#808080);
   menu.display();
   textFont(f,24); 
   textAlign(CENTER, CENTER);
   fill(255);
   String back = "BACK";
   text(back, menu.buttonX, menu.buttonY);
  }
}

void checker(String test, int index, Score rossScore, Score phoebeScore, Score chandlerScore, Score monicaScore, Score rachelScore, Score joeyScore) {
  if (test == answersList[index][0]) {
    rossScore.add();
  }
  else if (test == answersList[index][1]) {
    phoebeScore.add();  
  }
  else if (test == answersList[index][2]) {
    chandlerScore.add();  
  }
  else if (test == answersList[index][3]) {
    monicaScore.add();  
  }
  else if (test == answersList[index][4]) {
    rachelScore.add(); 
  }
  else if (test == answersList[index][5]) {
    joeyScore.add(); 
  }
}

void mousePressed() {
  if (start.buttonOver && instructions && !gameOn) {
    instructions = false;
    gameOn = false;
    page0 = true;
  }
 if (proceed.buttonOver && page0) {
   gameOn = true;
   page1 = true;
   page0 = false;
 }
 if (menu.buttonOver && !instructions && !gameOn && end) {
   instructions = true;
   rossScore.value = 0;
   rachelScore.value = 0;
   monicaScore.value = 0;
   phoebeScore.value = 0;
   joeyScore.value = 0;
   chandlerScore.value = 0;
   for (int i = 0; i < 11; i++) {
    shuffler[i].shuffle();
  }
 }
}

void serialEvent(Serial myPort){
  String s=myPort.readStringUntil('\n');
  s=trim(s);
  if (s!=null){
    println(s);
    int values[]=int(split(s,','));
    if (values.length==7){
      choice1 = (int)values[0];
      choice2 = (int)values[1];
      choice3 = (int)values[2];
      choice4 = (int)values[3];
      choice5 = (int)values[4];
      choice6 = (int)values[5];
      volume = (float)map(values[6], 0, 1023, 0.0, 1.0);
      volumeWidth = map(values[6],0,1023,0, width/3);
      if (end) finish = 1;
      else finish = 0;
      if(gameOn) blink = 1;
      else blink = 0;
    }
  }
  myPort.write(choice1+","+choice2+","+choice3+","+choice4+","+choice5+","+choice6+","+finish+","+blink+"\n");
}

Following is the Button Class:

class Button {
  float buttonX, buttonY;
  int buttonWidth, buttonHeight;
  color buttonColor, baseColor, frame;
  color buttonHighlight, currentColor;
  boolean buttonOver;
  
  
  Button(float _x, float _y, int w, int h, color outline) {
    
  buttonX = _x;
  buttonY = _y;
  frame = outline;
  buttonColor = color(0);
  buttonHighlight = color(51);
  baseColor = color(102);
  currentColor = baseColor;
  buttonWidth = w;
  buttonHeight = h;
    
  }
  
  boolean overButton(float x, float y, int buttonWidth, int buttonHeight, int clickState)  {            //check if mouse is over button
    if ((mouseX >= x - buttonWidth/2 && mouseX <= x + buttonWidth/2 && mouseY >= y - buttonHeight/2 && mouseY <= y + buttonHeight/2) || (clickState == 1)) {
      return true;
    } else {
      return false;
    }
  }
  
  void update(int clickState) {
    if ( overButton(buttonX, buttonY, buttonWidth, buttonHeight, clickState) ) {      //check if mouse is over the button to change color
      buttonOver = true;
    } 
    else {
      buttonOver = false;
    }
  }
  
  void display() {
    stroke(frame);
    if (buttonOver) {
      fill(buttonHighlight);            //if mous hovers over button change color
      rect(buttonX, buttonY, buttonWidth, buttonHeight, 20);      //play button
    }
    else {
      fill(buttonColor);
      strokeWeight(8);
      rect(buttonX, buttonY, buttonWidth, buttonHeight, 20);      //play button
    }   
  }
  
};

 

Following is the Score Class:

class Score {
  int value;
  
  Score() {  
  value = 0;  
  }
  
  void add() {
    value++;
  }
}

Final Project File if you want to download it:

finalProcessing

 

Final Project Progress

For the final project, I intend to have FRIENDS theme song play as you start the program on loop, and the potentiometer knob acts like a volume knob so the player can change it whenever they want to. There will be six buttons and they will be used to choose answers A, B, C, D, E, or F. The colors of the buttons will match those in the logo of FRIENDS and in the same order (but I might use white instead of yellow). Instructions will display at the beginning, telling the player the knob decreases volume and that each button corresponds to which answer on screen.  The yellow bulb lights up as soon as the game starts, and for 1 second as the player clicks and answer, the blue bulb blinks. Questions will generally become harder (it’s harder for the player to match each answer with a character). When all of the trivia is done, green bulb lights and yellow and blue are dim. The screen will show a picture of the character you are most similar to, and a description based on the answers. There will be a clickable button where if clicked plays a famous catchphrase of that character. Another button will be to restart the trivia questions.

I will use example 6 from the files that Aaron uploaded as a reference for my work.

The questions I have so far:

  1. How do you feel about animals?
    1. Love them! We shouldn’t eat them…
    2. They’re fine.
    3. Monkeys are my favorite animals.
    4. I don’t really like dogs
    5. They taste gooood!
    6. Cats with no hair are cool.
  2. What do you consider to be your best quality?
    1. Your looks
    2. Your intelligence
    3. Your cleanliness
    4. Your sense of humour
    5. Your good taste
    6. Your laid-back approach to life
  3. What is your dream job:
    1. Singer
    2. Professor
    3. Fashion consultant
    4. Actor
    5. Advertising executive
    6. Caterer
  4. What do you consider to be your worst quality?
    1. Clumsiness
    2. Arrogance
    3. Competitiveness
    4. Selfishness
    5. Insecurity
    6. Delusional
  5. You value friendship because…
    1. Friends are not afraid to tell me when I’m wrong
    2. Friends make the best lovers
    3. Friends are the only family I have
    4. Friends are what makes me popular
    5. Friends tolerate my awkwardness
    6. Friends introduce me to all their hot friends

https://www.beano.com/posts/which-friends-character-are-you

https://www.radiox.co.uk/games-quizzes/which-friends-character-are-you/

https://heywise.com/quiz/which-friends-character-are-you/3/

https://www.zimbio.com/quiz/O6sFuc_NvOh/Friends+Character

Final Project Brainstorming

So as usual, being the indecisive person I am, I have no clue what I will be doing for the final project. I have some random ideas as to what I can do so far:

Idea 1:

Building some kind of trivia for a TV show like How I Met Your Mother, where questions pop up and you answer using the buttons and a yellow bulb signifies waiting for response, a blue one blinks when you answer, and at the end a green one. According to your answers, the screen tells you which character you are most similar to.

Idea 2:

Building some kind of spike ball representing COVID-19 where each spike when clicked would bring an output of sound, picture, or data of a country/ worldwide.

Idea 3:

Connect 4 game on screen played by 4 buttons representing each position.

Idea 4:

Obstacle course game on screen where you move using buttons and collect power-ups to overcome challenges. Could be a multiplayer race between 2 players.

Hockey Game – Arduino/Processing

Initiation:

Ever since we did the simple example of the ball using Processing and Arduino together, I had the idea of implementing a hockey game using two potentiometers. Unfortunately, I was not able to visit the electronics store during the weekend and so I just decided to make player 2 use the mouse instead. Unlike previous assignments where I keep changing my mind over which idea to implement and what to do, I was pretty decided on my assignment for this week.

References:

I used example 4 from the folder which Aaron provided us with in order to have a proper serial event on Processing which can take in multiple inputs from Arduino and complete the handshake. I also used the example titled Bounce from the Processing application as reference.

Implementation:

I decided to make a class for every single object in order to have much deeper and control and power over what exactly happens in the game. At first, I only had gameOn and !gameOn as conditions for playing or a screen with instructional text. But then I realized that hockey usually involves 7 rounds and there should be some transitional phase between each round which requires some interaction from the players, so I added a situation named roundEnd and functions called display() in each class which show the pucks at the middle and the ball at the very middle and sets their positions there accordingly until the players click anywhere to continue playing, at which point the pucks go back to depending on the potentiometer and mouseX for position. The conditioning for this took some time because there are many factors involved and I need to calculate both scores simultaneously while keeping count of the rounds in order to finish the game at round 7 and declare a winner.

how the game looks like before playing/ after each round is finished

Challenges:

One major problem I faced which I actually didn’t exactly resolve was the collision of the ball with the pucks, where the blocks are wide and very thin so calculating the distance from the middle of the ball to the middle of the block varies greatly from one end to another, and I just took some average distance of collision as part of the equation but sometimes when the ball touches the far end of the block it looks as if it lags and is moving horizontally on the surface of the block before continuing on. I hope I can improve this aspect because I faced similar problems in past assignments when it comes to calculating distance.

I also realized that a player would not really be focusing on changing how dark/light their puck is but rather try to ensure they hit the ball quickly every time, so perhaps the photocell usage was just an extra feature that may not be very necessary or functional, even though it is still a cool effect in the theme of the game.

Improvement:

One thing I improved from the midterm is actually using mousePressed() instead of mouseClicked(), which is more effective when it comes to restarting the game and works better, the other required a particularly long click in order to work.

Here is my perspective as the player (very sad playing this alone and very hard as well):

Here is the actual final game:

Below is the Arduino Code:

//code inspired from example 4

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

void loop() {
  if(Serial.available()>0){
    char inByte=Serial.read();
    int knobValue = analogRead(A0);
    delay(1);
    int color = analogRead(A1);
    delay(1);
    Serial.print(knobValue);
    Serial.print(',');
    Serial.println(color);
  }
}

 

Below is the Processing Code:

import processing.serial.*;
Serial myPort;
Tab block;
Tab2 block2;
Ball ball;
int rounds = 0;
boolean gameOn = true;
boolean roundEnd = true;
int score1 = 0;          //initializing score to 0
int score2 = 0;
PFont f;              //f object for all the texts in the game

//inspired from bounce example

class Ball {
  
  int radius = 20;        // Width of the shape
  float xpos, ypos;    // Starting position of shape    
  
  float xspeed = 2;  // Speed of the shape
  float yspeed = 2;  // Speed of the shape
  
  int xdirection = 1;  // Left or Right
  int ydirection = 1;  // Top to Bottom
  
  
 Ball() 
  {  
    
    noStroke();
    ellipseMode(CENTER);
    // Set the starting position of the shape
    xpos = random(radius, width - radius);
    ypos = radius;
  }
  
  void display() {
    xpos = width/2;
    ypos = height/2;
    ellipse(xpos, ypos, radius, radius);
  }
  
  void update(int x, int y) 
  {
    
    // Update the position of the shape
    xpos = xpos + ( xspeed * xdirection );
    ypos = ypos + ( yspeed * ydirection );
    
    // Test to see if the shape exceeds the boundaries of the screen
    // If it does, reverse its direction by multiplying by -1
    if (dist(x, y, xpos, ypos) < radius + 15) {
      ydirection *= -1;
    }
    
    if (xpos > width-radius || xpos < radius) {
      xdirection *= -1;
    }
  
    // Draw the shape
    fill(255);
    ellipse(xpos, ypos, radius, radius);
  }
  
}

class Tab {
  int xPos=0;
  int yPos = height - 50;
  int rectWidth = 80;
  int rectHeight = 10;
  int colorInput=4;
  
  Tab() {
    fill(colorInput - 4, colorInput, random(230,255)); 
    rect(xPos,height - 50, rectWidth, rectHeight);
  }
  
  void display() {
    fill(colorInput - 4, colorInput, random(230,255)); 
    xPos = width/2;
    rect(xPos, yPos, rectWidth, rectHeight);
  }
  
  void update() {
    fill(colorInput - 4, colorInput, random(230,255)); 
    rect(xPos,yPos, rectWidth, rectHeight);
  }


  void serialEvent(Serial myPort){
    String s=myPort.readStringUntil('\n');
    s=trim(s);
    if (s!=null){
      int values[]=int(split(s,','));
      if (values.length==2){
        xPos=(int)map(values[0],0,1023, 0 + rectWidth/2 , width - rectWidth/2);
        colorInput=(int)map(values[1],0,1023, 150, 10);
      }
    }
    println(xPos);
    myPort.write('0');
  }
}

class Tab2 {
  int xPos= width/2;
  int yPos = 50;
  int rectWidth = 80;
  int rectHeight = 10;
  
  Tab2() {
    fill(255, 50, 50);
    rect(xPos,height - 50, rectWidth, rectHeight);
  }
  
  void display() {
    fill(random(230,255), 70, 75); 
    xPos = width/2;
    rect(xPos, yPos, rectWidth, rectHeight);
  }
  
  void update() { 
    fill(random(230,255), 70, 75); 
    xPos = (int)map(mouseX, 0, width, rectWidth/2, width - rectWidth/2);
    rect(xPos,yPos, rectWidth, rectHeight);
  }
  

}

void setup(){
  size(600,680);
  printArray(Serial.list());
  String portname=Serial.list()[2];
  println(portname);
  myPort = new Serial(this,portname,9600);
  myPort.clear();
  myPort.bufferUntil('\n');
  rectMode(CENTER);
  block = new Tab();
  block2 = new Tab2();
  ball = new Ball();
  f = createFont("Raleway-Bold.ttf",72);      //aesthetic font that fits teh theme
}

void draw(){
  background(0);
  
  if (gameOn && !roundEnd) {
    block.serialEvent(myPort);
    block.update();
    block2.update();
    ball.update(block2.xPos,block2.yPos);
    ball.update(block.xPos,block.yPos);
    
    if ( rounds == 7) {
      gameOn = false;
      //roundEnd = false;
    }
    
    if (ball.ypos < 59) {
      score1++;
      rounds++;
      roundEnd = true;
    }
    else if (ball.ypos > height - 59) {
      score2++;
      rounds++;
      roundEnd = true;
    }
    
  }
  
  else if (roundEnd && gameOn) {
    ball.display();
    block.display();
    block2.display();
    
    textAlign(CENTER);
    String round = "ROUND: ";
    String Score1 = "Blue Player: ";          //constantly show score at the corner
    String Score2 = "Red Player: ";          //constantly show score at the corner
    textFont(f,20);
    fill(255);
    text(Score1 + score1, width/2, height/2 - 15);        //score text bottom right
    text(Score2 + score2, width/2, height/2 - 35);        //score text bottom right
    textFont(f,24);
    text(round + rounds, width/2, height/2 + 35);
  }
  
  else {
    textAlign(CENTER, CENTER);
    
    textFont(f,40); 
    //same shade as in the flag
    String first;
    if (score1 > score2) {
      fill(#002868);
      first = "BLUE PLAYER WINS!!";
    }
    else {
      fill(#BF0A30);
      first = "RED PLAYER WINS!!";
    }
    
    text(first, width/2, height/2 - 90);
    
    textFont(f,24);
    //same shade as in the flag
    fill(255);
    String second = "CLICK TO PLAY AGAIN!";
    text(second, width/2 - 5, height/2 + 90);      //game over text
    
    textFont(f,20);
    fill(255);
    String third = "Blue Player: ";
    String fourth = "Red Player: ";
    fill(#002868);
    text(third + score1, width/2, height - 20);        //score text bottom right
     fill(#BF0A30);
    text(fourth + score2, width/2, height - 50);        //score text bottom right
  }
  
}

void mousePressed() {
      
   if (gameOn == false){        //if mouse is clicked when the game is off, turn it on and reset everything to zero and empty lists
      rounds = 0;
      score1 = 0;
      score2 = 0;
      ball.ypos = height/2;
      gameOn = true;   
   }
   
   else if (roundEnd == true) {
      gameOn = true;
      roundEnd = false;
   }
}

 

This assignment was pretty fun to make and I look forward to diving deeper into the combination of the Arduino and Processing worlds.

Week 9: Musical Instrument of “BEETHOVEN”

Being named Beethoven, I had to live up to my name somehow, so I decided to create a (very) mini piano.

What I had in mind was a button that acts as a switch, a potentiometer that affects the frequency of the notes, and seven buttons to be clicked as the basic fundamental notes (C4, D4, E4, F4, G4, A4, B4). So this is how I imagined my circuit to look like and it actually ended up being the same exact thing.

Interestingly, for this assignment, I faced challenges only in code and not in wiring at all. So I just kept changing my strategy of coding in order to suit what I was building.

So in my first trial, I used if conditions to play the notes according to the corresponding button. I made the potentiometer be like some kind of volume changer. When I tested the potentiometer only, it changed the volume from 0 to 255 perfectly and worked well using analogWrite().

I would write analogWrite(piezo, pwm) , where pwm is the mapped value of knobValue from 0 to 125.

When I used the buttons only and the function tone(), they worked perfectly fine and the switch worked too.

I would write tone(piezo, notes[i], 100).

But when I merged the two in code, it was weird. The switch button almost did not work, the buttons wouldn’t work if the switch was off, but the buzzer still produced some background noise all the time. In addition, the potentiometer would only turn on the keys after a certain point, and turn them before that, there was no spectrum but rather as if it was a switch. The circuit would only be silenced if the potentiometer was at 0 and while one of the keys was held.

In my second attempt, I tried to separate analogWrite() and tone() because I realized the two cannot work simultaneously on the same output device. So instead of changing volume I changed the frequency by keeping the range 0 to 1023 mapped into 0 to 100 and multiplying some of the keys by the mapped value (specifically the last button) and adding the value to the rest as you change the potentiometer.

But then I just felt like multiplying the frequencies by any number just produces an 8-bit very annoying sound, and adding the same number to them makes it actually hard to differentiate between them because they are all already not equal and have increasing values which differ by around 32 Hz. So I decided to dismiss the idea of changing the volume using the potentiometer like in trial 1 and stick to changing frequency like trial 2. I decided to make the mapping in range 0 to 32 (unlike trial 2) because that’s the average difference between them, and then I would add pwm to the first, 2*pwm to the second, 3*pwm to the third, … and so on, to keep the difference between them constant. I also chose a relatively low number so the tones could still be identifiable and fit in an instrument that can be bearable. I have to point out that the piezo that I have produces low quality sounds in any case so the videos might be a bit noisy.

The piano turned out to be not very enjoyable to be honest, but with more trials and better equipment, it could be improved and shaped into a more realistic one.

The code I used for this assignment:

#include "pitches.h"

int button = 2;                 //button pin

int key1 = 5;
int key2 = 6;
int key3 = 7;
int key4 = 8;
int key5 = 9;
int key6 = 10;
int key7 = 11;

int notes[7] = {NOTE_C4, NOTE_D4, NOTE_E4, NOTE_F4, NOTE_G4, NOTE_A4, NOTE_B4}; //standard notes

int piezo = 3;

bool prevButtonState = LOW;     //initializing button to be unpressed

bool gameOn = false;
 
int knob = A0;                  //pin of potentiometer
 
void setup() {
 
  pinMode(button, INPUT);         //button initialized as input
  
  pinMode(key1, INPUT);         //button initialized as input
  pinMode(key2, INPUT);         //button initialized as input
  pinMode(key3, INPUT);         //button initialized as input
  pinMode(key4, INPUT);         //button initialized as input
  pinMode(key5, INPUT);         //button initialized as input
  pinMode(key6, INPUT);         //button initialized as input
  pinMode(key7, INPUT);         //button initialized as input, these are the piano keys

  pinMode(piezo, OUTPUT);     //buzzer is output
  
  Serial.begin(9600);
}
 
void loop() {
  int buttonState = digitalRead(button);              //storing reading from button
  Serial.println(buttonState);
 
  if (buttonState == HIGH && prevButtonState == LOW) {      //if button is clicked change the piano states to their opposites
    gameOn = !gameOn;
    }
 
  if (gameOn == true) {           //if the piano were previously off then were turned on by button
      int knobValue = analogRead(knob);                   //store reading from photocell
      
      int button1 = digitalRead(key1);
      int button2 = digitalRead(key2);
      int button3 = digitalRead(key3);
      int button4 = digitalRead(key4);
      int button5 = digitalRead(key5);
      int button6 = digitalRead(key6);
      int button7 = digitalRead(key7);                    //read current values from buttons/keys

      byte pwm = map(knobValue, 0, 1023, 0, 32);          //mapping analog values into range of average difference between the standard notes
      Serial.println(knobValue);
      
      if (button1 == HIGH) {              //if button is pressed
        tone(piezo, notes[0] + pwm, 100);  //add to the standard frequency the corresponding value from potentiometer
      }

      if (button2 == HIGH) {
        tone(piezo, notes[1] + 2*pwm, 100);           //add twice the value from potentiometer to frequency
      }

      if (button3 == HIGH) {
        tone(piezo, notes[2] + 3*pwm, 100);           //add 3 times the values from potentiometer to frequency
      }

      if (button4 == HIGH) {
        tone(piezo, notes[3] + 4*pwm, 100);          //add 4 times the values from potentiometer to frequency
      }

      if (button5 == HIGH) {
        tone(piezo, notes[4] + 5*pwm, 100);         // add 5 times the values from potentiometer to frequency
      }

      if (button6 == HIGH) {
        tone(piezo, notes[5] + 6*pwm, 100);          //add 6 times the values from potentiometer to frequency
      }

      if (button7 == HIGH) {
        tone(piezo, notes[6] + 7*pwm, 100);          //add 7 times the values from potentiometer to frequency
      }

      if (button1 == LOW && button2 == LOW && button3 == LOW && button4 == LOW && button5 == LOW && button6 == LOW && button7 == LOW){
        analogWrite(piezo, 255);                    //if none of the buttons is pressed then make buzzer make no noise
      }

      
      delay(10);
    }
    
  else {
     analogWrite(piezo, 255);                       //if the switch is off turn buzzer off
    }
 
  prevButtonState = buttonState;                    //update prevButtonState in each loop
}

 

Day/Night Arduino Simulation

For probably the first time since we started the semester, I was able to do a weekly assignment just as I planned it initially. As soon as we were assigned to include some analog sensor in our circuit and a digital one, I thought of the photocell (because it’s just so cool) and some application of it where the environment is dark and then is bright. I thought of having three bulbs, red, yellow, and green and as you get closer with your finger it changes from red to yellow to green. Then I thought of drawing a rabbit and a turtle and having bulbs as their eyes; if you get too close then the rabbit’s eyes brighten up, but if you are too far (bright environment)  the turtle’s eyes brighten up. But after a long time brainstorming, I decided to go with the most intuitive idea relating to darkness and light: day and night in real life.

Artistic (not so much) steps:

As visible, I draw small icons of the sun and the moon in order to represent day and night, where the yellow bulb would sit in the middle of the sun, and the white bulb will sit in the middle of the white crescent.

Process:

Learning from last assignment, I extrapolated the power and the ground to the rest of the board using two jumper wires, in order to give myself extra space to work with.

I put a button the middle as some kind of digital switch for the whole simulation, if you click once, it’s on and stays on until you click once again.

I put both bulbs in pins with the “~” sign next to them so that their pulse can be changed using the photocell readings.

I decided to make the simulation so that the yellow bulb is very bright (bright sun at the beginning of the day), and as you get your finger closer (as time passes throughout the day and light lessens) the brightness decreases until at one point it stops completely (the evening), and as you continue to get closer, the white bulb of the moon becomes brighter and bright (through the night), until it’s maximized when you physically touch the photocell and block almost all light (midnight), then as you move your finger back upwards the opposite happens (after midnight until dusk). The key is that I map the first values until half of the maximum reading of photocell into inverted values for the bulb so I would get that effect of a spectrum.

Struggles:

The only problem I faced was with the if conditions and digital/analog writing bearing in mind that I always do analogRead(); if I only had analogwrite() then the bulb would keep being bright, and of it’s only digitalWrite() then the bulb doesn’t turn on at all. I’m sure I had some errors in there which I was not able to deal with. So I decided to have two scenarios, if the simulation is on, read photocell and analogWrite() based on that, and if simulation is off then digitalWrite() the bulbs to be off.

Also, when I forgot to make “prevButtonState = buttonState” at the very end and rather had it inside the if statement, everything would work incorrectly, so that was another thing I learned.

The last issue was just that I had a non-working jumper wire, and a bulb that was probably not 100% functional, which caused some confusion for me at first but soon I realized the issue and resolved it.

Final Project Angle 1:

Final Project Angle 2:

The code for the assignment:

int button = 2;                 //button pin

int ledWhite = 3;               //white bulb pin
int ledState1;                  
int ledYellow = 5;              //yellow bulb pin
int ledState2
bool prevButtonState = LOW;     //initializing button to be unpressed

int knob = A0;                  //pin of photocell

void setup() {
 
  pinMode(button, INPUT);         //button initialized as input
  pinMode(ledWhite, OUTPUT);      //bulbs initialized as outputs
  pinMode(ledYellow, OUTPUT);
  
  Serial.begin(9600);
}

void loop() {
  int buttonState = digitalRead(button);              //storing reading from button
  Serial.println(buttonState);

  if (buttonState == HIGH && prevButtonState == LOW) {      //if button is clicked change the led states to their opposites
    ledState1 = !ledState1;
    ledState2 = !ledState2;
    }

  if (ledState1 == HIGH && ledState2 == HIGH) {           //if the bulbs were previously off then were turned on by button
      int knobValue = analogRead(knob);                   //store reading from photocell
      int mappedValue1 = constrain( map(knobValue, 596, 850, 0, 255), 0, 255);        //map the values from half the max until the max of the photocell readings into 0 -> 255 so that as they increase teh brightness increases, and constrain that within 0 to 255
      int mappedValue2 = constrain( map(knobValue, 340, 595, 255, 0), 0, 255);        //map the first values until half the max of photocell readings into 255 -> 0 so that as they increase the brightness decreases, and constrain that within 0 to 255
      
      
      Serial.println(knobValue);

    analogWrite(ledYellow, mappedValue1);             //change output of sun bulb accordingly
    analogWrite(ledWhite, mappedValue2);              //change output of moon bulb accordingly
    }
    
  else {
    digitalWrite(ledWhite, ledState2);              //make bulbs's state = LOW, hence turned off
    digitalWrite(ledYellow, ledState1);             //make bulb's state = LOW, hence turned off
    }

  prevButtonState = buttonState;                    //update prevButtonState in each loop
}

 

 

Arduino Circuit 1

I struggled to think of any creative ideas at first and just started working. After a while, my initial idea was to have 4 buttons and 4 bulbs, where clicking on a button triggers a temporary lighting of the bulbs in the order 1234, the second triggers them in the same order with the last bulb off (123), third lights 2 bulbs (12), and the fourth lights 1. If you click two times, the order changes to 4123, and the same logic applies to buttons, 2, 3, and 4. Then if three clicks it is 3412, and if 4 clicks it is 2341, basically shifting every number to fit in all four possible positions.

Major Struggles

This assignment was actually very challenging for me for several reasons. Firstaly, I was not able to get buttons until Sunday night which made me very stressed while working during the tight time. I was not able to find big colorful buttons like the ones which my peers have in their kits; I found much smaller ones instead which are all just black. This in itself made it very hard to try them out properly and I would sometimes cause the buttons to fall off from the circuit if I simply press a bit hard. In order to resolve the color issue, I actually used nail polish to color the small surfaces of the buttons.

one of the buttons which I colored white

I kept working for hours and a recurring issue kept happening; anything I use in the lower half of the board simply did not work, even if I copy the literal code for it and corresponding electrical wiring from above. After hours of extreme frustration, I realized that half of my breadboard doesn’t work properly.

The lower half is untouched as it can be seen

In order to resolve the issue, I actually extended my power and ground wires to the right side too, and added a button and bulb on the right side. Even though I wanted to have more than three items at the start, that was not feasible at this point.

Idea and implementation

After getting acquainted with my board and with playing with electrical tools in general, I started to dive right into my idea. I realized that lighting the bulbs one after the other might be too much work that is not very necessary so I decided to just dismiss that idea. I decided pressing certain buttons would trigger certain bulbs and that pressing several buttons together would yield another result.

I was able to achieve this goal after several trials and errors where the following applies to my final project:

  • Pressing the blue button on the left turns the 3 bulbs on
  • Pressing it again right after turning them on turns them all off
  • Pressing the purple button in the middle turns the last 2 (yellow and white) bulbs on
  • Pressing it again right after turning them on turns them off
  • Pressing the dark red button on the left turns the 1st and 3rd (red and white) bulbs on
  • Pressing it again right after turning them on turns them off
  • Pressing/holding the first and second buttons together turns only the red (1st) one on
  • Pressing/holding the second and third buttons together turns only the yellow (2nd) one on
  • Pressing/holding the third and first buttons together turns only the white (3rd) one on
  • Pressing/holding the 3 buttons simply turns them all off

It should be noted that I made sure that if you already had some lights on and click a certain button, it adapts the bulbs to fit the appropriate output without having to turn off all of them and resetting then turning the appropriate ones on, which is so much aesthetically pleasing.

Below, I show how clicking on two buttons lights one bulb up (red in this case).

Below is the final assignment:

I learned so much from this assignment as the experience of coding and building such circuits is quite new me, and my pace is not as fast as with Processing which will require some extra effort from my end.

Here is the code I used for the circuit:

int ledRed = 5;               //pin of the red bulb
int ledYellow = 9;            //pin of yellow bulb
int ledWhite = 11;            //pin of white bulb

int prevButtonState1= LOW;    //previous state of blue button
int prevButtonState2= LOW;    //previous state of purple button
int prevButtonState3= LOW;    //previous state of red button

int ledState1;                //state of red bulb
int ledState2;                //state of yellow bulb
int ledState3;                //state of white bulb

int buttonBlue = 4;           //pin of blue button
int buttonPurple = 8;         //pin of purple button
int buttonRed = 10;           //pin of red button


void setup() {
  ledState1 = LOW;            //initializing blue button state to not clicked
  ledState2 = LOW;            //initializing purple button state to not clicked
  ledState3 = LOW;            //initializing red button state to not clicked
  
  pinMode(ledRed, OUTPUT);        //declaring red led as output variable
  pinMode(buttonBlue, INPUT);     //declaring blue button as intput variable
  pinMode(ledYellow, OUTPUT);     //declaring yellow led as output variable
  pinMode(buttonPurple, INPUT);   //declaring purple button as intput variable
  pinMode(ledWhite, OUTPUT);      //declaring white led as output variable
  pinMode(buttonRed, INPUT);      //declaring red button as intput variable
  
  Serial.begin(9600);
}
void loop() {
  int currentButtonState1 = digitalRead(buttonBlue);        //setting variable to digital reading of state of blue button
  int currentButtonState2 = digitalRead(buttonPurple);      //setting variable to digital reading of state of purple button
  int currentButtonState3 = digitalRead(buttonRed);         //setting variable to digital reading of state of red button
  if ((currentButtonState1 == HIGH) && (currentButtonState2 == HIGH) && (currentButtonState3 == HIGH)) {    //if all buttons are pressed, turn all bulbs off
    ledState1 = LOW;
    ledState2 = LOW;
    ledState3 = LOW;
  }
  else if ((currentButtonState1 == HIGH) && (currentButtonState2 == HIGH)) {       //if both the blue and purple buttons are pressed/held together
    if (ledState1 == HIGH) {                                                  //if red bulb was lighting turn it off
      ledState1 = LOW;
      }
    else if (ledState1 == LOW) {                                              //if red bulb was not on, turn it on
      ledState1 = HIGH;
      }
      
    ledState2 = LOW;                                                          //ensure the yellow bulb is off
      
    ledState3 = LOW;                                                          //ensure the white bulb is off
     
    
  }
  else if ((currentButtonState2 == HIGH) && (currentButtonState3 == HIGH)) {      //if both the purple and red buttons are pressed/held together
    if (ledState2 == HIGH) {                                                      //if yellow bulb was on, turn off
      ledState2 = LOW;
      }
    else if (ledState2 == LOW) {                                                  //if yellow bulb was off, turn on
      ledState2 = HIGH;
      }
      
    ledState1 = LOW;                                                              //ensure red bulb is off

    ledState3 = LOW;                                                              //ensure white bulb is off
    
    
  }
  else if ((currentButtonState1 == HIGH) && (currentButtonState3 == HIGH)) {            //if both the blue and red buttons are pressed/held together
    if (ledState3 == HIGH) {                                                            //if white bulb is on, turn off
      ledState3 = LOW;
      }
    else if (ledState3 == LOW) {                                                        //if white bulb is off, turn on
      ledState3 = HIGH;
      }
      
    ledState1 = LOW;                                                                    //ensure red bulb is off

    ledState2 = LOW;                                                                    //ensure yellow bulb is off
      
    
  }

  else if (currentButtonState1 == HIGH && prevButtonState1 == LOW) {                //if blue button is pressed
    if (ledState1 == HIGH && ledState2 == HIGH && ledState3 == HIGH) {              //if this was the last button previously pressed, turn off all bulbs
        ledState1 = LOW;
        ledState2 = LOW;
        ledState3 = LOW;
    }
    else {                                                                          //otherwise, turn them all on
      ledState1 = HIGH;
    
      ledState2 = HIGH;

      ledState3 = HIGH;
    }
    
    
  }
  

  else if (currentButtonState2 == HIGH && prevButtonState2 == LOW) {              //if the purple button is pressed                 
     if (ledState2 == HIGH && ledState3 == HIGH && ledState1 == LOW) {          //if this was the last pressed button, turn the lit ones off
        ledState2 = LOW;
        ledState3 = LOW;
    }

    else {                                                                    //otherwise, turn the yellow and white bulbs only on
      ledState2 = HIGH;
      ledState3 = HIGH;
      ledState1 = LOW;
    }
     
    
  }

  else if (currentButtonState3 == HIGH && prevButtonState3 == LOW) {              //if the red button is pressed
    if (ledState1 == HIGH && ledState3 == HIGH && ledState2 == LOW) {             //if it was teh last pressed button, turn lit ones off
        ledState1 = LOW;
        ledState3 = LOW;
    }
    
    else {                                                                        //otherwise, turn the red and white bulbs on
      ledState3 = HIGH;
      ledState1 = HIGH;
      ledState2 = LOW;
    }
    
    
    }

  digitalWrite(ledRed, ledState1);
  digitalWrite(ledYellow, ledState2);
  digitalWrite(ledWhite, ledState3);                                        //update the bulbs accordingly
  
  prevButtonState1 = currentButtonState1;
  prevButtonState2 = currentButtonState2;
  prevButtonState3 = currentButtonState3;                                   //update the current states of the buttons for evaluation in the next frame

}

 

 

 

Midterm: It’s all under control…

Building upon what I had already, I decided to develop my game much further.

Initial issues

I had many issues at first which include: pressing any key would make Trump move in place, if you held down an arrow key and jumped you stopped moving once you landed, the jump was very abrupt and strictly vertical which was weird for the level of realism in the game, shooting would stop the motion of Trump, and the bullets would appear but not move at all.

Resolving issues, help from Jack

I resolved these issues using many different lines of code where instead of doing most of the work in the main code, I kept creating functions which do the tasks in order for me to be able to keep calling them in multiple situations. I made sure to add “keyCode = …” under each if condition if keyPressed and otherwise just keep direction = direction, which even enabled me to allow motion using w, a, s, d as well. Instead of just using keyPressed in draw loop for all, I used the function one outside to call on the act of shooting and jumping just once whenever the keys are pressed and not every frame.

By asking Jack for some help, we figured out I must also use the keyReleased function outside the draw loop to decide what the game should look like the moment the player releases the important keys to keep the playing going. Jack also helped me with the concept of flying the bullet where I had the code in the main tab and the motion was called upon once in the draw loop but we made it a function in the class instead that is called upon continuously. I also added a small increment/decrement in the x-dimension for Trump when he jumps sideways to make it more realistic.

Jack also introduced the concept of saving the previous frame to me, where I used it to make sure no two bullets are created within a certain amount of frames, and similarly with the coronas. This made the game so much more realistic and intuitive, especially when you keep holding the shooting key.

Further development

I then brought an image of a sanitizer and made it smaller, and then made it seem as though Trump is holding it in his right hand (because he is right-handed) by ordering the image printing accordingly. I had many options for choosing the corona character but I chose this funky one because it is rather satirical, which is the obvious theme of my game, and because it is visible in the green without disturbing the eye like if it was red.

I chose the title based on the actual quote of Trump about COVID-19, and I chose the sentence printed out when you lose as also another quote from Trump about COVID-19, which just fits the theme perfectly. I added the US flag and used an online photo editor called “Pixlr X” to make it more transparent and to add the individual instructions all on the background. I decided to make the instructions visually aesthetic so as to not bore the player and to be very intuitive, and because the game is satirical in nature so it need not be too complicated or serious. I added that face at the end and then added the sound from a YouTube video of a mashup of Trump saying ‘no’ to resemble his hilarious failure and annoyance from getting infected with the virus, which happened in real life despite him making fun of COVID’s repercussions. Also, the sound is annoying to encourage the player to restart the game.

original flag background
background after edits

I added some sound effects for the shooting (squirt sound), killing a corona particle (pop sound) which were both dropped down in amplitude to not be too noisy, and a background music of the US national anthem but an 8bit version of it from YouTube to go along with the clipart theme of the game while maintaining Trump’s Republican Party’s patriotic notion. The music drops down in volume as soon as you start playing so as to draw you attention to the visuals, so you can hear the pop and squirt sounds, and so it does not become too noisy and loud.

I used processing examples to build the button used for playing the game, making it clickable and changing its color when you hover over it.

As suggested in the class, I added a black fence resembling the real one in the White House to show where exactly Trump cannot run anymore on the ground in a visibly clear manner.

fence I used to show the limit of trump’s motion

Personal Feeling

The game has a fun a political taste to it while being very relevant to our current situation in the COVID-19 pandemic. I am a Muslim Arab man and Trump is a very significant man in my life because of the actions he has done towards immigrants of my race and because he is the president of the most influential country in the world. Even though I am an American citizen, I am still very pissed off by what he has done and I have many loved ones who were harmed by the consequences of his actions. As an Egyptian, our way of expressing emotions is always through satire and comedy, and this is my simple way of expressing how I feel about this man right now in 2020.

starting page with game instructions
how the game itself looks
what comes up when you lose

Final Version

If you want to try out the game yourself, here is a zip file of the code:

midterm

Main Code:

import processing.sound.*;    //importing sound library

PImage whiteHouse, sanitizer, laser, corona, trumpBack, americaFlag, fence;     //all images needed
PImage spritesheet;      //sprites of trump
boolean gameOn;        //condition for game
float prevFrame = 0;      //initializing value for previous frame
float randX, randY;      //random numbers for coordinates of creation of corona particles
ArrayList <Laser> lasers;    //initializing arraylist for sanitizer bullets
ArrayList <Corona> coronas;    //initializing array list for corona particles
int score = 0;          //initializing score to 0
PFont f;              //f object for all the texts in the game
int luck;            //randomizing number to make corona particles start motion towards the left or the right
int buttonX, buttonY;      // Position of button
int buttonWidth, buttonHeight;     //dimensions of play button
color buttonColor, baseColor;    //colors of play button
color buttonHighlight;
color currentColor;
boolean buttonOver;
boolean instructions;        //condition for whether instructions page is open or not
SoundFile click, squirt, pop, trumpSound, anthem;      //all sounds in the game

Trump trumps;      //initializing trump character 


//button logic inspired from https://processing.org/examples/button.html

void setup() {
  size(720,477);
  
  instructions = true;      //start game with instructions page
  buttonOver = false;      //start with condition of button pressed false
  gameOn = false;          //don't start game till play is clicked
  
  
  f = createFont("Raleway-Bold.ttf",72);      //aesthetic font that fits teh theme
  
  whiteHouse = loadImage("house4.png");      //white house background pic
  spritesheet = loadImage("trump.png");    //sprites of trump
  sanitizer = loadImage("sanitizer.png");    //sanitizer image
  laser = loadImage("laser.png");            //sanitizer bullet image
  corona = loadImage("corona3.png");          //corona particle image
  trumpBack = loadImage("trumpbackground.jpg");      //trump face when loses image
  americaFlag = loadImage("americaFlag3.jpg");      //america flag background in the beginning with the instructions image
  fence = loadImage("fence4.png");      //black fence image
  
  click = new SoundFile (this, "click.mp3");      //sound when you click
  squirt = new SoundFile (this, "squirt.mp3");       //sound when you shoot
  pop = new SoundFile (this, "pop.mp3");      //sound when you kill corona particle
  trumpSound = new SoundFile (this, "no.mp3");      //long sound playing when you lose until you click anywhere to restart
  anthem = new SoundFile (this, "anthem (6).mp3");      //8bit anthem background music
  
  trumps = new Trump(width/2, height -40);        //creates instance of class trump
  lasers = new ArrayList();        //initializes sanitizer bullets list
  coronas = new ArrayList();      //initializes coronas list
  
  buttonColor = color(0);
  buttonHighlight = color(51);
  baseColor = color(102);
  currentColor = baseColor;
  buttonWidth = 150;
  buttonHeight = 60;
  buttonX = width/2;
  buttonY = 3*height/4 + 30;        //initializations of the button color, color when hovered upon, dimensions, and position
  
  anthem.loop();      //keep the anthem playing on loop always
  trumpSound.amp(0.001);      //reduce the amplitude of trump sound to nothing so it is not heard now
  trumpSound.loop();      //keep the trump sound playing continuously in the background
  
  rectMode(CENTER);
  imageMode(CENTER);
}

void draw() {
  
  if (gameOn == true && instructions == false) {      //if game is one the instructions page is not opened
    //trumpSound.pause();
    background(whiteHouse);
    image(fence, width/6, height -145, width/3, 80);
    image(fence, width/3 + width/6, height -145, width/3, 80);
    image(fence, 2*width/3 + width/6, height -145, width/3, 80);      //draw the fence three times side by side
    
    if (keyPressed) {
        if (keyCode == DOWN || key == 's') {
          keyCode = DOWN;                    //handling keyCode when key = s is pressed instead, because I use keyCode throughout teh code
          trumps.direction = 0;
          trumps.move();
        }
          
        else if (keyCode == LEFT || key == 'a') {
          keyCode = LEFT;
          trumps.direction = 3;
          trumps.move();
        }
        else if (keyCode == RIGHT || key == 'd') {
          keyCode = RIGHT;
          trumps.direction = 1;
          trumps.move();
        }
        
        else if (keyCode == UP || key == 'w') {
          keyCode = UP;
          trumps.direction = 2;
          trumps.move();                                    //handling the moements of trump, whether using keys or using w, a, s, d
        } 
        else {
          trumps.direction = trumps.direction;
        }
    }
      
      if (trumps.direction == 3) {
        pushMatrix();
        translate(trumps.x - 23, trumps.y + 15);
        //rotateY(radians(180));
        image(sanitizer, 0, 0);
        popMatrix();                      //draw sanitizer direction right
      }
      
       if (trumps.direction == 2) {
        image(sanitizer, trumps.x + 20, trumps.y + 8);      //draw sanitizer direction up
      }
      
  
      image(trumps.sprites[trumps.direction][trumps.step], trumps.x, trumps.y);      //drawing trump himself
      trumps.update();                    //calling on gravity
      
      if (trumps.direction == 1) {
        image(sanitizer, trumps.x + 23, trumps.y + 15);      //draw sanitizer direction left
      }
      
      if (trumps.direction == 0) {
        image(sanitizer, trumps.x - 15, trumps.y + 20);        //draw sanitizer direction down
      }
      
      if (frameCount % 100 == 0) {
        if (coronas.size() < 8) {            //setting limit of 8 coronas at a time
           luck = (int)random(100);
           randX = random(100, width - 100);
           randY = random (100, height - (190 + trumps.h));
           
           
           Corona temp = new Corona(randX, randY, luck);
           coronas.add(temp);
        }
      }                                                   //create coronas after a certain number of frames at random starting positions and random starting direction of left or right
      
      for (int i = coronas.size()-1; i >= 0; i--) {
        Corona current = coronas.get(i);
        current.display();
        current.move();                                    //call on functional methods of corona class for each of them
        
        if (current.checkTrump(trumps.x, trumps.y)) {          //checking if corona collided with trump
          anthem.stop();          //stop the background music
          gameOn = false;          //game condition false
          break;                //break from the conditions to enter others
        }
      }
      
      for (int i = lasers.size()-1; i >= 0; i--) {
        Laser laser = lasers.get(i);
        laser.display();
        laser.fly();                //call on functional methods of sanitizer bullets for each object
        
        if (laser.checkEdges()) {        //check if laser is out of frame to remove it
          lasers.remove(laser);
        }
        
        for (int j = coronas.size()-1; j >= 0; j--){        //iterate through all coronas
          Corona important = coronas.get(j);
          if (laser.checkCollision(important.coronaX, important.coronaY, important.coronaWidth)) {      //if bullet hits corona
            pop.amp(0.1);
            pop.play();      //make pop sound
            coronas.remove(important);       //remove hit corona
            lasers.remove(laser);           //remove the bullet that hit it too
            score += 10;        //increment score by 10
          }
          //pop.stop();
        }
        
      }
      
      textAlign(CORNER);
      String Score = "Score: ";          //constantly show score at the corner
      //fill(0);
      //rect(width - 130 , height - 100, textWidth(Score) + 10, 50);
      textFont(f,20);
      fill(255);
      
      
      text(Score + score, width - 115, height - 20);        //score text bottom right
    
  }
  
  else if (instructions == true && gameOn == false) {        //starting phase of instructions pre-game
    
    background(255);
    update();
  
    if (buttonOver) {
      fill(buttonHighlight);            //if mous hovers over button change color
    } 
    else {
      fill(buttonColor);
    }
    
    image(americaFlag, width/2, height/2);        //image of flag with game instructions on it
    
    stroke(255);
    rect(buttonX, buttonY, buttonWidth, buttonHeight, 20);      //play button
    
    textFont(f,25); 
    textAlign(CENTER, CENTER);
    fill(255);
    String play = "PLAY";          //text in play button to clarify it
    text(play, buttonX , buttonY - 3);
  }
  
  else if (instructions == false && gameOn == false) {      //if player loses
    anthem.stop();      //stop background music
    //trumpSound.play();
    trumpSound.amp(0.8);      //increase trump saying no to be heard

    
    
    background(trumpBack);      //trump's face
    textAlign(CENTER);
    
    textFont(f,40); 
    //same shade as in the flag
    fill(#BF0A30);
    String first = "'This was unexpected...'";
    text(first, width/2 , (height/4) - 90);
    
    textFont(f,24);
    //same shade as in the flag
    fill(#002868);
    String second = "CLICK ANYWHERE TO TRY AGAIN";
    text(second, width/2 - 5, height/2 + 215);      //game over text
    
    textAlign(CORNER);
    textFont(f,20);
    fill(0);
    String third = "Score: ";
    text(third + score, width - 115, height -20);      //final score text
    
   
  }
}

void keyPressed()
{
   if(key == ' '){
      if (frameCount - prevFrame > 15) {      //only allow jumping constantly after certain number of frames
        prevFrame = frameCount;
        trumps.jump();      
      }
   }
   
   if(key == 'e') {          //shoot sanitizer bullet
   trumps.recoil();           //recoil when trump shoots
      if (frameCount - prevFrame > 20) {        //only allow multiple shooting after certain number of frames if key is held
        squirt.amp(0.2);        //play squirt sound
        squirt.play();
        prevFrame = frameCount;
        Laser temp = new Laser(trumps.x, trumps.y, trumps.direction);        //create new bullet
        lasers.add(temp);      //add it to teh list
      }
    }
}

void update() {
  if ( overButton(buttonX, buttonY, buttonWidth, buttonHeight) ) {      //check if mouse is over the button to change color
    buttonOver = true;
  } 
  else {
    buttonOver = false;
  }
}

void keyReleased() {
  if(key == ' ') {          //keep trump in correct direction and keep moving even while/after jumping
    if (trumps.direction == 0) {
        keyCode = DOWN;              
      }
        
      if (trumps.direction == 3 ) {
        keyCode = LEFT;
      }
      if (trumps.direction == 1) {
        keyCode = RIGHT;
      }
      
      if (trumps.direction == 2) {
        keyCode = UP;
      } 
  }
  
  if(key == 'e') {        //keep trump in correct direction and keep moving even while/after shooting
    //squirt.stop();
    if (trumps.direction == 0) {
        keyCode = DOWN;
      }
        
      if (trumps.direction == 3 ) {
        keyCode = LEFT;
      }
      if (trumps.direction == 1) {
        keyCode = RIGHT;
      }
      
      if (trumps.direction == 2) {
        keyCode = UP;
      } 
  }
}

boolean overButton(int x, int y, int buttonWidth, int buttonHeight)  {            //check if mouse is over button
  if (mouseX >= x - buttonWidth/2 && mouseX <= x + buttonWidth/2 && mouseY >= y - buttonHeight/2 && mouseY <= y + buttonHeight/2) {
    return true;
  } else {
    return false;
  }
}

void mouseClicked() {
  if (buttonOver) {      //check if mouse is clicked over button then start game
    
      click.amp(0.3);
      click.play();
      instructions = false;
      
     if (gameOn == false){        //if mouse is clicked when the game is off, turn it on and reset everything to zero and empty lists
        //trumpSound.stop();
        //instructions = false;
        score = 0;
        gameOn = true;
        anthem.amp(0.4);
        anthem.loop();        //replay background music
        trumpSound.amp(0.001);
        for (int i = coronas.size()-1; i >= 0; i--) {       //reset coronas list
          coronas.remove(i); 
        }
        for (int i = lasers.size()-1; i >= 0; i--) {         //reset bullets list
          lasers.remove(i);   
        }
      
    }
    
  }
  
}

Corona class, contains three functions: displaying, moving around, and checking if it collided with Trump:

class Corona {
  float coronaX, coronaY;
  float xSpeed;
  float ySpeed;
  float xDirection, yDirection;
  float coronaWidth, coronaHeight;
  int rand;
  
  
  Corona(float _x, float _y, int _rand) {
    
    coronaX = _x;
    coronaY = _y;
    
    coronaWidth = 100;
    coronaHeight = 100;
    
    xDirection = 1;
    yDirection = 1;
    
    xSpeed = 2;
    ySpeed = 2;
    
    rand = _rand;
    
  }
  
  void display() {
    image(corona, coronaX, coronaY, coronaWidth, coronaHeight);      //display corona image
  }
  
  void move() {
    
    if (rand > 50) {              //if random number is this then move in right direction
      coronaX += (xSpeed * xDirection);
      coronaY += (ySpeed * yDirection);
    }
    
    else {                    //if random number is less tha or equal to 50, move in the left direction
      coronaX -= (xSpeed * xDirection);
      coronaY -= (ySpeed * yDirection);
    }
    
    if ((coronaX + (coronaWidth/2) > width) || (coronaX - (coronaWidth/2) < 0)) {      //if corona hits either walls horizontally switch direction of motion to bounce
      xDirection *= -1;
    }
    
    if ((coronaY + (coronaHeight/2) > height) || (coronaY - (coronaHeight/2) < 0)) {        //if corona hits either walls vertically switch direction of motion to bounce
      yDirection *= -1;
    }
   
  }
  
  boolean checkTrump(float _x, float _y) {          //check if it collided with trump
     float otherX = _x;
     float otherY = _y;
     if (dist(coronaX, coronaY, otherX, otherY) < coronaWidth/2) {
       return true;
     } 
     else {
       return false;
     }
  }


}

Sanitizer Class, has 4 functions: displaying the sanitizer bullet, flying the bullet in the appropriate direction, checking if it collided with a corona particle, and checking if it is outside the frame of the game:

//code inspired from https://forum.processing.org/two/discussion/1324/how-to-create-a-bullet-array-for-asteroids-game
class Laser {

  int laserDirection;
  float laserX, laserY;
  float xSpeed;
  float ySpeed;
  float laserWidth, laserHeight;


  Laser(float _x, float _y, int direction) {
    
    laserDirection = direction;
    xSpeed = 8;
    ySpeed = 8;
    
    if (laserDirection == 0) {
      laserX = _x - 15;
      laserY = _y + 23;
    }
    if (laserDirection == 1) {
      laserX = _x + 23;
      laserY = _y + 15;
    }
    if (laserDirection == 2) {
      laserX = _x + 23;
      laserY = _y - 15;
    }
    if (laserDirection == 3) {
      laserX = _x - 23;
      laserY = _y + 15;
    }
                                          //initialize direction of laser so it remains so even if trump changes his direction later
    laserWidth = 60;
    laserHeight = 20;
    
   }
  
   void display() {
     if (laserDirection == 2){
       pushMatrix();
         translate(laserX, laserY - 20);
         rotate(HALF_PI);
         image(laser, 0, 0, laserWidth, laserHeight);
       popMatrix();
       
     }                                                  //rotate bullet to shoot up
     
     else if( laserDirection==0) {
     pushMatrix();
         translate(laserX, laserY + 25);
         rotate(HALF_PI);
         image(laser, 0, 0, laserWidth, laserHeight);
       popMatrix();
     }                                            //rotate bullet to shoot down
     
     else if ( laserDirection==1){
       image(laser, laserX + 28, laserY - 18, laserWidth, laserHeight);      //bullet shoot right
     }
     
     else if ( laserDirection==3){
       image(laser, laserX - 28, laserY - 18 , laserWidth, laserHeight);      //bullet shoot left
     }
   }
   
   void fly() {
     if (laserDirection == 3) {        //left
       laserX -= xSpeed;
     }
     
     if (laserDirection == 1) {        //right
       laserX += xSpeed;
     }
     
     if (laserDirection == 2) {        //up
       laserY -= ySpeed;
     }
     
     if (laserDirection == 0) {        //down
       laserY += ySpeed;
     }
                                                        //movement according to the direction
   }
   
   boolean checkCollision (float _x, float _y, float w) {      //check collision with corona coordinates
     float otherX = _x;
     float otherY = _y;
     if (dist(laserX, laserY, otherX, otherY + 10) < w/2 ) {
       return true;
     } 
     else {
       return false;
     }
   }
   
   boolean checkEdges() {
     if ((laserX - laserWidth/2 > width) || (laserX + laserWidth/2 < 0) || (laserY - laserHeight/2 > height) || (laserY + laserHeight/2 < 0)) {      //check if laser is outside frame to remove it
       return true;
     }
     else {
       return false;
     }
   }
  

}

Trump class, has 4 functions: updating the y-position of Trump according to gravity,  moving the character around in the appropriate directions, recoiling Trump backwards whenever he shoots to make it more realistic, and jumping:

class Trump {
  
  PImage[][] sprites;
  int direction = 1;
  int step = 0;
  int w, h;
  float x, y;
  float xspeed = 6;
  float yspeed = 6;
  float gravity;
  
  Trump(float _x , float _y){
  sprites = new PImage[4][6];
  
  w = spritesheet.width/6;
  h = spritesheet.height/4;
  
  gravity = 0.0001;

  for (int y=0; y < 4; y++) {
    for (int x=0; x< 6; x++) {
      sprites[y][x] = spritesheet.get(x*w, y*h, w, h);      //creating each instance's individual sprite from spritesheet
    }
  }

  x = _x;
  y =_y;
  
  }
  
  void update() {        //if trump is in the air make him go down through gravity
  
    if (y - h/2 < height - 190.5) {
      yspeed = yspeed + gravity;
      y += yspeed;
    }
  }
  
  void move() {
    if (direction == 0) {
      if (y + (h/2) < height) {    //move down until frame limit
          y += yspeed;
      }
    }
    if (direction == 1) {      //right till wall
      if (x + (w/2) < width) {
          x += xspeed;
        }
    }
    if (direction == 2) {      //up till fence
      if (y - (h/2) > height - 189) {
          y -= yspeed;
        }
    }
    if (direction == 3) {      //left till wall
      if (x - (w/2) > 0) {
          x -= xspeed;
        }
    }                                //move according to direction
    
    if (frameCount % xspeed == 0) {      //transition from one sprite to another
        step = (step+1) % 6;
    }
  }
  
  void recoil() {        //push trump slightly backwards when he shoots to be more realistic
    if (direction == 0) {      //down
      if (y - (h/2) > height - 189) {    //go up till fence
          y -= yspeed/4;
      }
    }
    if (direction == 1) {      //right
      if (x - (w/2) > 0) {      //left till wall
          x -= xspeed/4;
        }
    }
    if (direction == 2) {      //up
      if (y + (h/2) < height) {    //down till frame limit
          y += yspeed/4;
        }
    }
    if (direction == 3) {      //left
      if (x + (w/2) < width) {      //right till wall
          x += xspeed/4;
        }
    }
    
    //if (frameCount % xspeed == 0) {
    //    step = (step+1) % 6;
    //}
  }

  void jump() {
    
    if (y - (h/2) > height - 191) {      //if trump is not already flying make him jump
      y -= 150;
      
      if (direction == 3 ) {      //if he was moving to left push him slightly to left
        if (x - (w/2) > 0) {
          x-= 20;
        }
      }
      else if (direction == 1) {      //if he was moving to right push him slightly to right
        if (x + (w/2) < width) {
          x += 20;
        }
      }
    }
      
  }
  
  
}

 

 

Midterm Progress… (“COVID-19 affects virtually nobody”)

My midterm project underwent several changes (and will undergo some more) during the past week.

With 2020 coming to an end and after all of what we have gone through with this coronavirus pandemic, it would have been a shame if I did not make at least one of my projects in this class have a theme of COVID-19.

I imagined a game where a character is moved by the user around the screen while holding a hand sanitizer using which they fire shots at the incoming corona particles. I imagined that there would be two terrified characters, a couple who are the main character’s elderly parents and who would remain inside the house which has its interior visible to the user from the outside. I wanted the main character to try to prevent the particles from reaching their parents inside the house or else they would lose the game.

perspective of a house with the parents inside

But then I thought that the game might not be as I want it to be because the interior of the house must be of some relevance to the functionalities where the character should be able to get inside or climb up the stairs for example, which would be unnecessary coding that I do not see as being worth it. In addition, I felt like it was very similar to other online games I have seen which makes it redundant.

Furthermore, I decided to change the idea a bit my making the fight not involve any parents but rather be inside a house and a character tries to protect themselves from being hit by the virus particles to survive.

two floor house in which the fighting takes place
another version of a two floor house

 

 

 

 

I imagined that the player can, for example, go from floor to the other by running into one of the edges of the screen, and that they keep moving and shooting until they take down all of the corona particles.

The idea was actually better now for me and I decided that this character would best suit what I want to do in general, even if I have to alter the background to be more appealing design-wise.

sprites of the main character which I found to be the most suitable at first

But then after further research I found some sprites of the US president Donald Trump and I then thought that I can make my game political! I decided that I can make it be outside the White House and the main character would be Trump. The game would be of satirical nature and makes fun of the disastrous way the president dealt with the coronavirus pandemic allowing for the USA to be reportedly the number one country with COVID-19 cases worldwide.

sprites of the trump character I used

Trump would try to kill the coronavirus particles with the ability to run only on the grass and jump once if the spacebar is pressed. I also decided to print out his most famous quotes about the pandemic, which were the most controversial, and let them fall down from the sky on banners to add to the excitement of the game.

white house background which I am currently using for the game

I want to add power-up facial masks which act as some sort of temporary shield for Trump while dodging the corona particles’ attacks. I decided to use this sanitizer and this “bullet” for shooting.

sanitizer used as a gun

 

bullet shot from sanitizer

 

 

 

 

I am still very unsure about my next steps and I hope to get a better sense of direction after meeting Aaron during today’s class.

Egyptian King(s)

I am no different than any other Egyptian when it comes to loving the Liverpool forward Mohamed Salah who is known as “The Egyptian King”. This man has done so much for Egypt and the world and I am proud to say he is a role model for me. Nevertheless, another more original “Egyptian King” is very close to my heart, the timeless singer Mohamed Mounir. Seeing that they are both always smiling and have distinctive curly black hair, I decided to manipulate images of them as my assignment for this week.

The most difficult part for starting was actually choosing the images from the internet. I tried very high quality pictures but they had too many pixels in them. I tried very small ones but they were too tiny to be able to deal with them. When I got PNG images with transparent backgrounds the effects I had did not work as intended because of the limited space used. Even after finding proper pictures I had to find ones for both Salah and Mounir which are similar in posture, size, and quality. These are some images which I tried but did not work for me:

 

 

 

 

After several trials and errors, I decided to use these two images after I cropped them to be exactly the same size.


 

 

 

Then I decided to get the best out of some code  found on the Pixels tutorial page on Processing.org and the past geomerative class. I used the idea of getting the colors of the image and filling some rectangles with them as if they were large pixels. I then made on of the images the background (Mounir) which is hidden under the image on top (Salah) and tried the idea of making use of distance to significantly change the z-dimension of the squares as if they were flying away with the movement of the mouse as if the user was using a magnifying glass to have a look at the background. I made sure the picture returns to its original state as soon as the mouse leaves the plane so that the image doesn’t remain distorted afterwards.

This is the code I used for the interactive image manipulation.

//inspired from the pixels tutorial on teh processing website
 
PImage mounir;
PImage salah;       // The source image
int rectify = 4; // Dimensions of each cell in the grid
int cols, rows;   // Number of columns and rows in our system
int offset =255;

void setup() {
  size(460, 275, P3D); 
  salah  = loadImage("salah2.jpeg"); // Load the image
  mounir = loadImage("mounir.jpg");
  cols = width/rectify;             // Calculate # of columns
  rows = height/rectify;            // Calculate # of rows
}

void draw() {

  background(mounir);
  loadPixels();
  // Begin loop for columns
  for ( int i = 0; i < cols;i++) {
    // Begin loop for rows
    for ( int j = 0; j < rows;j++) {
      int xS = i*rectify + rectify/2; // x position
      int yS = j*rectify + rectify/2; // y position
      int locS = xS + yS*width;       // Pixel array location
      float r = red(salah.pixels[locS]);
      float g = green(salah.pixels[locS]);
      float b = blue(salah.pixels[locS]);
     // Grab the color
      //color cM = mounir.pixels[locS];
      offset -= mouseX/500;
      constrain(offset,0,255);
      // Calculate a z position as a function of mouseX and pixel brightness
      float zS =(8000/dist(mouseX, mouseY, xS, yS)) ;
      if (mouseX > 450 || mouseX < 10 || mouseY > 266 || mouseY < 10) {
          zS =30;
      }
      // Translate to the location, set fill and stroke, and draw the rect
      pushMatrix();
      translate(xS,yS, zS);
      tint(255, offset);
      fill(r, g, b);
      noStroke();
      rectMode(CENTER);
      rect(0,0,rectify,rectify);
      popMatrix();
    }
  }
  updatePixels();
}

The logic itself is a bit simple but it conveys the message and the purpose directly and creatively, which is the most important thing for me. It represents who I am and that is why I personally like it and feel it is me.