[FINAL PROJECT] Smash It!/Smash Your Memory! (A Music Memory Game)

IDEA:

Setup: Five Pads on the floor and an interface.

Operations: The note pads correspond to the pentatonic C scale: C, D, E, G, A. As shown on the pads, they represent all the things I hate, I assume you too, the most throughout this semester. To win the game, you must recreate a melody by smashing the pads.

Symbols: The things I hate the most this semester

  • C note: COVID
  • D note: Deadlines
  • E note: course Enrollment
  • G note: GPA
  • A note: Anxiety

IMPLEMENTATION:

  1. Title Page
  2. Rules
  3. Practice: plays demo melody
  4. Test
  5. Win or Lose

video of im showcase:

Most people got it correct after 2-3 tries, around 3-5 succeeded on the first try (talk about music talents), and 3 people just gave up. People enjoyed it a lot more than I thought they would!

CODES:

//Processing Codes

/*
 name: Chi-Ting Tsai
 assignment: final project
 date: 12/07/2021
 "Smash It!" is a music memory game where player would be instructed to memorize a melody 
 and recreate it by stepping on the pads corresponding to notes on the pentatonic C scale.
 */

import processing.sound.*;
SoundFile demoMelody;
SoundFile recC;
SoundFile recD;
SoundFile recE;
SoundFile recG;
SoundFile recA;
SoundFile winning;
SoundFile losing;

int size = 200;
color frame = color(237, 168, 17);

int stage;
int noteC = 1;
int noteD = 2;
int noteE = 3;
int noteG = 5;
int noteA = 6;
int[] correctMelody = {noteD, noteC, noteE, noteG, noteA, noteG, noteD, noteC};

void setup() {
  size (displayWidth, displayHeight);
  background(color(99, 144, 130));
  String portname=Serial.list()[3];
  println(portname);
  myPort = new Serial(this, portname, 9600);
  myPort.clear();
  myPort.bufferUntil('\n');
  demoMelody = new SoundFile (this, "/Users/chi-tingtsai/Downloads/5-seconds-of-silence_gcP1Vako.wav");
  recC = new SoundFile (this, "/Users/chi-tingtsai/Downloads/C.wav");
  recD = new SoundFile (this, "/Users/chi-tingtsai/Downloads/D.wav");
  recE = new SoundFile (this, "/Users/chi-tingtsai/Downloads/E.wav");
  recG = new SoundFile (this, "/Users/chi-tingtsai/Downloads/G.wav");
  recA = new SoundFile (this, "/Users/chi-tingtsai/Downloads/A.wav");
  winning = new SoundFile (this, "/Users/chi-tingtsai/Downloads/Winning Sound Effect.wav");
  losing = new SoundFile (this, "/Users/chi-tingtsai/Downloads/The Price is Right Losing Horn - Gaming Sound Effect (HD).wav");
}

void draw() {
  //scene change
  if (stage == 0) {
    rank();
  } else if (stage == 1) {
    rules();
  } else if (stage == 2) {
    practice();
  } else if (stage == 3) {
    game();
  } else if (stage == 4) {
    lose();
  } else if (stage == 5) {
    win();
  }
}
//Processing codes 

void rank() {
background(color(99, 144, 130));
PFont F = createFont("TimesNewRomanPS-BoldMT", 1);
noStroke();
fill(255);
textAlign(CENTER);

textFont(F, 50);
text("Smash Your Memory!\nA Music Memory Game", width/2, height/2-50);
text("Smash C note(COVID) to Begin", width/2, height*3/4);

//frame
noStroke();
rectMode(CENTER);
fill(frame);
rect(width/2, 10, width, 20);
rect(width/2, height-60, width, 20);
rect(10, height/2, 20, height);
rect(width-10, height/2, 20, height);
}
//Processing 

void rules() {
  background(color(99, 144, 130));
  PFont F = createFont("TimesNewRomanPS-BoldMT", 1);
  noStroke();
  fill(255);
  textAlign(CENTER);

  //explain how to play
  textFont(F, 50);
  text("RULES: Memory Game", width/2, height/4);
  textFont(F, 30);
  text("INSTRUCTIONS:\n The note pads correspond to the pentatonic C scale: C,D,E,G,A.\n As shown on the pads, they represent all the things I hate,\nI assume you too, the most throughout this semester.\n To win the game, you must recreate a melody by smashing the pads.", width/2, height/2-120);
  textFont(F, 30);
  text("Smash Deadlines to play the melody ONCE(AND ONLY ONCE!) and practice!", width/2, height-200);
  
  //frame
  noStroke();
  rectMode(CENTER);
  fill(frame);
  rect(width/2, 10, width, 20);
  rect(width/2, height-60, width, 20);
  rect(10, height/2, 20, height);
  rect(width-10, height/2, 20, height);
}
//Processing Codes 

int i = 0;
char[] refMelody = {' ', ' ', ' ', 'D', 'C', 'E', 'G', 'A', 'G', 'D', 'C'};


void practice() {
  background(color(99, 144, 130));
  PFont F = createFont("TimesNewRomanPS-BoldMT", 1);
  noStroke();
  fill(255);
  textAlign(CENTER);

  //text
  textFont(F, 50);
  text("LISTEN CAREFULLY & PRACTICE (8 NOTES)", width/2, height/4);
  textFont(F, 30);
  text("Practice to familiarize with how the notes sound!\nRememer: your job is to smash the pads to recreate the melody!\n", width/2, height/2-120);
  textFont(F, 50);
  textFont(F, 50);
  text("Smash Space Bar to begin smashing!", width/2, height-170);

  //frame
  noStroke();
  rectMode(CENTER);
  fill(frame);
  rect(width/2, 10, width, 20);
  rect(width/2, height-60, width, 20);
  rect(10, height/2, 20, height);
  rect(width-10, height/2, 20, height);

  //telling player which note it is
  if (frameCount%118 == 0 && i < 10) {
    i++;
  }
  text("Now playing: \n" + refMelody[i], width/2, height/2+75);
}
//Processing Codes

import processing.serial.*;
Serial myPort;

int aSignal = 0;
int prevASignal = 0;
int val = 0;

void game() {
  if (i == 10) {
    i = 0;
  }
  
  //background
  background(color(99, 144, 130));
  PFont F = createFont("TimesNewRomanPS-BoldMT", 1);
  noStroke();
  fill(255);
  textAlign(CENTER);

  textFont(F, 50);
  text("Listen Carefully and Recreate!", width/2, height/4);
  textFont(F, 30);
  text("The things I hate the most this semester\nC note: COVID\nD note: Deadlines\nE note: course Enrollment\nG note: GPA\nA note: Anxiety\n", width/2, height/2-80);
  fill(frame);
  textFont(F, 50);
  text(val + "/8" + " Notes Correct! Keep smashing!", width/2, height-170);

  //frame
  noStroke();
  rectMode(CENTER);
  fill(frame);
  rect(width/2, 10, width, 20);
  rect(width/2, height-60, width, 20);
  rect(10, height/2, 20, height);
  rect(width-10, height/2, 20, height);
}

void serialEvent(Serial myPort) {
  String s=myPort.readStringUntil('\n');
  s=trim(s);
  if (s!= null) {
    aSignal = parseInt(s);
    //scene transition
    if (stage == 0 && aSignal == noteC) {
      stage = 1;
      recC.play();
      val = 0;
    }
    if (stage == 1 && aSignal == noteD) {
      stage = 2;
      demoMelody.amp(0.8);
      demoMelody.play();
    }
    if ((stage == 4 || stage == 5) && aSignal == noteG) {
      stage = 0;
      recG.play();
    }

    //note playing and verification
    if ((stage == 2 || stage == 3) && prevASignal!= aSignal) {
      if (aSignal == noteC) {
        recC.play();
      } else if (aSignal == noteD) {
        recD.play();
      } else if (aSignal == noteE) {
        recE.play();
      } else if (aSignal == noteG) {
        recG.play();
      } else if (aSignal == noteA) {
        recA.play();
      }
      //verify note in array
      if (stage == 3 && aSignal != 0) {
        if (correctMelody[val] == aSignal) {
          val++;
          prevASignal = aSignal;
          if (val == 8) {
            delay(2000);
            stage = 5;
            winning.play();
          }
        } else {
          delay(2000);
          stage = 4;
          losing.amp(0.3);
          losing.play();
        }
      }
      prevASignal = aSignal;
    }
  }
  myPort.write('\n');
}

void keyReleased() {
  if (key == ' ' && stage == 2) {
    stage = 3;
    game();
  }
}
//Processing Codes

void lose() {
  background(color(99, 144, 130));
  PFont F = createFont("TimesNewRomanPS-BoldMT", 1);
  noStroke();
  fill(255);
  textAlign(CENTER);
  
  textFont(F, 50);
  text("Awwww... Smash GPA to play again.", width/2, height*3/4);
  text("Not the right note!\nYou've reached the " + (val) + "th note in the melody!", width/2, height/2-80);
  //frame
  noStroke();
  rectMode(CENTER);
  fill(frame);
  rect(width/2, 10, width, 20);
  rect(width/2, height-60, width, 20);
  rect(10, height/2, 20, height);
  rect(width-10, height/2, 20, height);
}
//Processing 

void win() {
  background(color(99, 144, 130));
  PFont F = createFont("TimesNewRomanPS-BoldMT", 1);
  noStroke();
  fill(255);
  textAlign(CENTER);

  textFont(F, 50);
  text("Congratulations! You have recreated the entire melody!", width/2, height/2);
  textFont(F, 50);
  text("Smash GPA to play again!", width/2, height/2+50);
  textFont(F, 30);
  fill(frame);
  text("Have you found your peace by smashing those that give off negative energy?", width/2, height/2-50);

  //frame
  noStroke();
  rectMode(CENTER);
  fill(frame);
  rect(width/2, 10, width, 20);
  rect(width/2, height-60, width, 20);
  rect(10, height/2, 20, height);
  rect(width-10, height/2, 20, height);
}
//Arduino codes 

//variable declaration
const int C = 1;
const int D = 2;
const int E = 3;
const int G = 5;
const int A = 6;
const int in_C = 2;
const int in_D = 3;
const int in_E = 4;
const int in_G = 5;
const int in_A = 6;

const int led_C = 9;
const int led_D = 10;
const int led_E = 11;
const int led_G = 12;
const int led_A = 13;

int switch_C, switch_D, switch_E, switch_G, switch_A = 0;

int smash = 0;

void setup() {
  // put your setup code here, to run once:
  pinMode(in_C, INPUT);
  pinMode(in_D, INPUT);
  pinMode(in_E, INPUT);
  pinMode(in_G, INPUT);
  pinMode(in_A, INPUT);

  Serial.begin(9600);
  Serial.println("0");
}

void loop() {
  // put your main code here, to run repeatedly:
  switch_C = digitalRead(in_C);
  switch_D = digitalRead(in_D);
  switch_E = digitalRead(in_E);
  switch_G = digitalRead(in_G);
  switch_A = digitalRead(in_A);

  while (Serial.available()) {
    smash = 0;
    if (Serial.read() == '\n') {
      //Note C
      if (switch_C == 1) {                //released, if the two aluminum foils touch
        smash = C;
      }
      else if (switch_C && switch_D && switch_E && switch_G && switch_A == 0)
      { //released, if the two aluminum foils partLED
        smash = 0;
      }
      //Note D
      if (switch_D == 1) {                //released, if the two aluminum foils touch
        smash = D;
      }
      else if (switch_C && switch_D && switch_E && switch_G && switch_A == 0)
      { //released, if the two aluminum foils partLED
        smash = 0;
      }
      //Note E
      if (switch_E == 1) {                //released, if the two aluminum foils touch
        smash = E;
      }
      else if (switch_C && switch_D && switch_E && switch_G && switch_A == 0)
      { //released, if the two aluminum foils partLED
        smash = 0;
      }
      //Note G
      if (switch_G == 1) {                //released, if the two aluminum foils touch
        smash = G;
      }
      else if (switch_C && switch_D && switch_E && switch_G && switch_A == 0)
      { //released, if the two aluminum foils partLED
        smash = 0;
      }
      //Note A
      if (switch_A == 1) {                //released, if the two aluminum foils touch
        smash = A;
      }
      Serial.println(smash);
    }
  }
} 

CHALLENGES:

After receiving feedback from classmates, I have made several improvements:

  1. Adding visual cues with the demo melody
  2. Informing players how many notes they have recreated correctly

At the beginning of the showcase, someone flagged out a few bugs in the interface but nothing major. They were removed swiftly and the rest of the show went by smoothly in back-to-back user testing!

last note

Thank you so much for the semester. Happy Christmas holidays and have a joyful New Year. Have a restful winter break as well.

Warms regards,

Chi-Ting

Final Project: Smash Your Memory [User Testing]

IDEA:

I would have the pads laid on the floor and use longer wires to create a bigger space.

user testing:

THINGS TO WORK ON 

  1. User testing feedback
    1. shorten the melody line
    2. allow players to practice and familiarize the notes
  2. Display ranking
  3. Aesthetics and physical decorations
    1. wooden box to contain the breadboard and Arduino Uno
    2. square pieces to package the pads
//Processing codes

/*
 1. fix the melody
 2. display ranking
 3. aesthetics and physical decoration
 */

/*
 name: Chi-Ting Tsai
 assignment: final project
 date: 12/07/2021
 "Smash Your Memory"
 */

import processing.sound.*;
SoundFile demoMelody;
SoundFile recC;
SoundFile recD;
SoundFile recE;
SoundFile recG;
SoundFile recA;

int size = 200;
color frame = color(237, 168, 17);

int stage = 0;
int noteC = 1;
int noteD = 2;
int noteE = 3;
int noteG = 5;
int noteA = 6;
int[] correctMelody = {noteD, noteC, noteE, noteD, noteG, noteA, noteG, noteE, noteD, noteC};


void setup() {
  size (1024, 768);
  printArray(Serial.list());
  String portname=Serial.list()[3];
  println(portname);
  myPort = new Serial(this, portname, 9600);
  myPort.clear();
  myPort.bufferUntil('\n');
  demoMelody = new SoundFile (this, "/Users/chi-tingtsai/Downloads/10.wav");
  recC = new SoundFile (this, "/Users/chi-tingtsai/Downloads/C.wav");
  recD = new SoundFile (this, "/Users/chi-tingtsai/Downloads/D.wav");
  recE = new SoundFile (this, "/Users/chi-tingtsai/Downloads/E.wav");
  recG = new SoundFile (this, "/Users/chi-tingtsai/Downloads/G.wav");
  recA = new SoundFile (this, "/Users/chi-tingtsai/Downloads/A.wav");
}

void draw() {
  if (stage == 0) {
    ranking();
  } else if (stage == 1) {
    rules();
  } else if (stage == 2) {
    game();
  } else if (stage == 3) {
    lose();
  } else if (stage ==4) {
    win();
  }
}

//display ranking
void ranking() {
  background(color(99, 144, 130));
  PFont F = createFont("PatuaOne-Regular", 1);
  fill(255);
  textAlign(CENTER);

  //Game title
  textFont(F, 50);
  text("Smash Your Memory", width/2, height/2-50);
  //explain how to start
  textFont(F, 30);
  text("Smash Covid to Begin Game", width/2, height*3/4);

  //frame
  noStroke();
  rectMode(CENTER);
  fill(frame);
  rect(width/2, 10, width, 20);
  rect(width/2, height-10, width, 20);
  rect(10, height/2, 20, height);
  rect(width-10, height/2, 20, height);
}

void rules() {
  background(color(99, 144, 130));
  PFont F = createFont("PatuaOne-Regular", 1);
  fill(255);
  textAlign(CENTER);

  //explain how to play
  textFont(F, 50);
  text("RULES", width/2, height/4);
  textFont(F, 30);
  text("Listen to the pentatonic melody played after this scene.\n It's only going to play once!\n Smash the corresponding pads to recreate the melody!\nC: COVID\nD: Deadlines\nE: course Enrollment\nG: GPA\nA: Anxiety", width/2, height/2-120);
  textFont(F, 30);
  text("Smash course Enrollment to listen to the melody and begin!", width/2, height-110);

  //frame
  noStroke();
  rectMode(CENTER);
  fill(frame);
  rect(width/2, 10, width, 20);
  rect(width/2, height-10, width, 20);
  rect(10, height/2, 20, height);
  rect(width-10, height/2, 20, height);
}

import processing.serial.*;
Serial myPort;

int aSignal = 0;
int prevASignal = 3;
int val = 0;

void game() {
  //background
   background(color(99, 144, 130));
  fill(255);
  PFont F = createFont("PatuaOne-Regular", 1);
  textAlign(CENTER);

  textFont(F, 50);
  text("Listen Carefully and Recreate!", width/2, height/2-50);
}

void serialEvent(Serial myPort) {
  String s=myPort.readStringUntil('\n');
  s=trim(s);
  if (s!= null) {
    aSignal = parseInt(s);
    //println("signal from arduino: " + s);
    //scene transition
    if (stage == 0 && aSignal == noteC) {
      recC.play();
      stage = 1;
    }
    //if (stage == 1 && aSignal == noteD) {
    //  demoMelody.play();
    //}
    if (stage == 1 && aSignal == noteE) {
      stage = 2;
      demoMelody.play();
    }
    if ((stage == 3 || stage == 4) && aSignal == noteG) {
      recG.play();
      stage = 0;
    }

    //note playing and verification
    if (stage == 2 && prevASignal!= aSignal) {
      println("number stored in the array: " + aSignal);
      if (aSignal == noteC) {
        recC.play();
      } else if (aSignal == noteD) {
        recD.play();
      } else if (aSignal == noteE) {
        recE.play();
      } else if (aSignal == noteG) {
        recG.play();
      } else if (aSignal == noteA) {
        recA.play();
      }
      //verify note in array
      if (correctMelody[val] == aSignal) {
        //change circle color
        val++;
        prevASignal = aSignal;
        if (val == 10) {
          stage = 4;
        }
      } else {
        //change circle color
        delay(5000);
        stage = 3;
      }
    }
  }
  myPort.write('\n');
}

void lose() {
  background(color(99, 144, 130));
  PFont F = createFont("PatuaOne-Regular", 1);
  noStroke();
  fill(255);
  
  textFont(F, 80);
  text("Not the right note!", width/2, height/2);
  textFont(F, 50);
  text("Awwww... Smash GPA to see your ranking and restart.", width/2, height/2+50);
}

void win() {
  background(color(99, 144, 130));
  PFont F = createFont("PatuaOne-Regular", 1);
  noStroke();
  fill(255);

  textFont(F, 80);
  text("Congratulations! You have done it!", width/2, height/2);
  textFont(F, 50);
  text("Have you found your peace by smashing those that give off negative energy?", width/2, height/2-50);
  textFont(F, 30);
  text("Smash GPA to see your ranking", width/2, height/2+50);
}
//Arduino codes

//variable declaration
const int C = 1;
const int D = 2;
const int E = 3;
const int G = 5;
const int A = 6;
const int in_C = 2;
const int in_D = 3;
const int in_E = 4;
const int in_G = 5;
const int in_A = 6;
const int speaker_Pin = 8;
const int led_C = 9;
const int led_D = 10;
const int led_E = 11;
const int led_G = 12;
const int led_A = 13;

int switch_C, switch_D, switch_E, switch_G, switch_A = 0;

int smash = 0;

void setup() {
  // put your setup code here, to run once:
  pinMode(in_C, INPUT);
  pinMode(in_D, INPUT);
  pinMode(in_E, INPUT);
  pinMode(in_G, INPUT);
  pinMode(in_A, INPUT);
  pinMode(speaker_Pin, OUTPUT);
  pinMode(led_C, OUTPUT);
  pinMode(led_D, OUTPUT);
  pinMode(led_E, OUTPUT);
  pinMode(led_G, OUTPUT);
  pinMode(led_A, OUTPUT);

  Serial.begin(9600);
  Serial.println("0");
}

void loop() {
  // put your main code here, to run repeatedly:
  switch_C = digitalRead(in_C);
  switch_D = digitalRead(in_D);
  switch_E = digitalRead(in_E);
  switch_G = digitalRead(in_G);
  switch_A = digitalRead(in_A);

  while (Serial.available()) {
    if (Serial.read() == '\n') {
      //Note C
      if (switch_C == 1) {                //released, if the two aluminum foils touch
        digitalWrite(led_C, HIGH);        //turns on LED
        smash = C;
      }
      else if (switch_C && switch_D && switch_E && switch_G && switch_A == 0)
      { //released, if the two aluminum foils part
        digitalWrite (led_C, LOW);        //turns off LED
        smash = 0;
      };

      //Note D
      if (switch_D == 1) {                //released, if the two aluminum foils touch
        digitalWrite(led_D, HIGH);        //turns on LED
        smash = D;
      }
      else if (switch_C && switch_D && switch_E && switch_G && switch_A == 0)
      { //released, if the two aluminum foils part
        digitalWrite (led_D, LOW);        //turns off LED
        smash = 0;
      };

      //Note E
      if (switch_E == 1) {                //released, if the two aluminum foils touch
        digitalWrite(led_E, HIGH);        //turns on LED
        smash = E;
      }
      else if (switch_C && switch_D && switch_E && switch_G && switch_A == 0)
      { //released, if the two aluminum foils part
        digitalWrite (led_E, LOW);        //turns off LED
        smash = 0;
      };

      //Note G
      if (switch_G == 1) {                //released, if the two aluminum foils touch
        digitalWrite(led_G, HIGH);        //turns on LED
        smash = G;
      }
      else if (switch_C && switch_D && switch_E && switch_G && switch_A == 0)
      { //released, if the two aluminum foils part
        digitalWrite (led_G, LOW);        //turns off LED
        smash = 0;
      };

      //Note A
      if (switch_A == 1) {                //released, if the two aluminum foils touch
        digitalWrite(led_A, HIGH);        //turns on LED
        smash = A;
      }
      else if (switch_C && switch_D && switch_E && switch_G && switch_A == 0)
      { //released, if the two aluminum foils part
        digitalWrite (led_A, LOW);        //turns off LED
        smash = 0;
      }
      Serial.println(smash);
    }
  }
  //  Serial.print("smash: ");
  //  Serial.println(smash);
  //  Serial.print("C: ");
  //  Serial.println(switch_C);
  //  Serial.print("D: ");
  //  Serial.println(smash);
  //  Serial.print("E: ");
  //  Serial.println(smash);
  //  Serial.print("G: ");
  //  Serial.println(smash);
  //  Serial.print("A: ");
  //  Serial.println(smash);
}

Final Project: How fast you can dance

inspiration 

From the dancing games in the arcade, where you step on pads to create sound or match the falling arrows.

Team: solo

game

The game entails 5 pads, each representing one note on the pentatonic scale. In processing, there will be five circles corresponding to the five pads. The game would give you a sequence of notes by lighting up the circles in processing and, through Arduino, the LEDs surrounding the pads. The player would have to recreate the sequence by stepping on the pads. The LEDs and the circles would light up as the player jump between the pads.

FUNCTION

Have players remember the sequence and recreate it. The sequence gets longer as the game progresses.

mATERIALS

  1. LED strips
  2. sponges (non-conductive materials)
  3. force detectors
  4. Arduino
  5. lots of wires
  6. space: a 2m x 2m space to place the pads

challenges

Codes: The hardest part would be recording what the player is doing and checking if it is the same as the displayed demo sequence.

Physical: Making the pads durable enough for people to step on them and still remain functional.

PROGRESS

I’ve been doing research about verifying and checking the notes.  I have sone codes for doing more but will need something more to meet the needs of the game.

Final Project: A Music/Dancing Concept

inspiration 

From the dancing games in the arcade, where you step on pads to create sound or match the falling arrows.

game

The game entails 5 pads, each representing one note on the pentatonic scale. In processing, there will be five circles corresponding to the five pads. The game would give you a sequence of notes by lighting up the circles in processing and, through Arduino, the LEDs surrounding the pads. The player would have to recreate the sequence by stepping on the pads. The LEDs and the circles would light up as the player jump between the pads.

POTENTIAL FUNCTION

  1. Key change, using analog function
  2. Ear training game

Serial Communication: Three Exercises

//arduino exercase #1
void setup() {
  Serial.begin(9600);
  Serial.println("0,0");
}

void loop() {
  while (Serial.available()) {
    if (Serial.read() == '\n') {
      int sensor = analogRead(A0);
      delay(1);
      Serial.print(sensor);
      Serial.println(',');
    }
  }
}
//processing exercise #1

import processing.serial.*;
Serial myPort;
int xPos=0;
int yPos=height/2;

void setup() {
  size(960, 720);
  printArray(Serial.list());
  String portname=Serial.list()[3];
  println(portname);
  myPort = new Serial(this, portname, 9600);
  myPort.clear();
  myPort.bufferUntil('\n');
}

void draw() {
  background(255);
  ellipse(xPos, yPos, 30, 30);
}

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==2) {
      xPos=(int)map(values[0], 0, 1023, 0, width);
    }
  }
  myPort.write(xPos+','+"\n");
}
//arduino exercise #2

int left = 0;
int right = 0;

void setup() {
  Serial.begin(9600);
  Serial.println("0,0");
  pinMode(3, OUTPUT);
}

void loop() {
  while (Serial.available()) {
    right = Serial.parseInt();
    left = Serial.parseInt();
    if (Serial.read() == '\n') {
      analogWrite(3, right);
      Serial.print(0);
      Serial.print(',');
      Serial.println(0);
    }
  }
}
//processing exercise #2 

import processing.serial.*;
Serial myPort;
int xPos=0;

void setup(){
  size(960,720);
  printArray(Serial.list());
  String portname=Serial.list()[3];
  println(portname);
  myPort = new Serial(this,portname,9600);
  myPort.clear();
  myPort.bufferUntil('\n');
}

void draw(){
  background(255);
}

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==2){
      xPos=(int)map(mouseX,0,width, 0, 255);
    }
  }
  myPort.write(xPos+","+0+"\n");
}
//arduino exercise #3
 
void setup() {
  Serial.begin(9600);
  Serial.println("0,0");
  pinMode(3, OUTPUT);
}
 
void loop() {
  while (Serial.available()) {
    int onOff = Serial.parseInt();
    if (Serial.read() == '\n') {
      digitalWrite(3, onOff);
      int sensor = analogRead(A0);
      delay(1);
      Serial.println(sensor);
    }
  }
}
//processing exercise #3

import processing.serial.*;
Serial myPort;

PVector velocity;
PVector gravity;
PVector position;
PVector acceleration;
PVector wind;
float drag = 0.99;
float mass = 50;
float hDampening;
boolean onOff=false;
float analog;

void setup() {
  size(640, 360);
  String portname=Serial.list()[3];
  println(portname);
  myPort = new Serial(this, portname, 9600);
  myPort.clear();
  myPort.bufferUntil('\n');

  noFill();
  position = new PVector(width/2, 0);
  velocity = new PVector(0, 0);
  acceleration = new PVector(0, 0);
  gravity = new PVector(0, 0.5*mass);
  wind = new PVector(0, 0);
  hDampening=map(mass, 15, 80, .98, .96);
}
void draw() {
  background(255);
  if (!keyPressed) {
    wind.x= analog;
    velocity.x*=hDampening;
  }
  applyForce(wind);
  applyForce(gravity);
  velocity.add(acceleration);
  velocity.mult(drag);
  position.add(velocity);
  acceleration.mult(0);
  ellipse(position.x, position.y, mass, mass);
  if (position.y > height-mass/2) {
    velocity.y *= -0.9;  // A little dampening when hitting the bottom
    position.y = height-mass/2;
  }
  
  if (position.y >= height - mass){
  onOff = true;
  }
  else{
  onOff = false;
  }
}

void serialEvent(Serial myPort) {
  String s=myPort.readStringUntil('\n');
  s=trim(s);
  int values = parseInt(s);
  if (s!=null) {
    analog =map(values, 0, 1023, -3, 3);
  }
  myPort.write(int(onOff)+"\n");
}

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

void keyPressed() {
  if (key==' ') {
    mass=random(15, 80);
    position.y=-mass;
    velocity.mult(0);
  }
}

Video

[Chi-Ting & Theyab] How to troll your friends, again, in an Arduino way

INSPIRATION

On the internet, there’s a way of making people listen to a specific song, but in a new way every time. We decided to use Arduino to do just that.

IDEA

A switch to start playing the song and stop playing the song.

A potentiometer to fasten or slow down the tempo of the song.

BREADBOARD

Here

VIDEO DEMO

CODES

int speaker_pin = 2;
bool Switch = LOW;


volatile int tone_length = 100; // determines tempo



// Parts 1 and 2 (Intro)

int melody[] =
{
  554, 622, 622, 698, 831, 740, 698, 622, 554, 622, -1, 415, 415,
  554, 622, 622, 698, 831, 740, 698, 622, 554, 622, -1, 415, 415,
  -1, 277, 277, 277, 277, 311,
  -1, 261, 233, 208,
  -1, 233, 233, 261, 277, 208, 415, 415, 311,
  -1, 233, 233, 261, 277, 233, 277, 311,
  -1, 261, 233, 233, 208,
  -1, 233, 233, 261, 277, 208, 208, 311, 311, 311, 349, 311, 277, 311, 349, 277, 311, 311, 311, 349, 311, 208,
  -1, 233, 261, 277, 208, -1, 311, 349, 311,
  -1, 277, 277, 277, 277, 311,
  -1, 261, 233, 208,
  -1, 233, 233, 261, 277, 208, 415, 415, 311,
  -1, 233, 233, 261, 277, 233, 277, 311,
  -1, 261, 233, 233, 208,
  -1, 233, 233, 261, 277, 208, 208, 311, 311, 311, 349, 311, 277, 311, 349, 277, 311, 311, 311, 349, 311, 208,
  -1, 233, 261, 277, 208, -1, 311, 349, 311,
  466, 466, 415, 415, 698, 698, 622, 466, 466, 415, 415, 622, 622, 554, 523, 466, 554, 554, 554, 554, 554, 622, 523, 466, 415, 415, 415, 622, 554, 466, 466, 415, 415,
  698, 698, 622, 466, 466, 415, 415, 831, 523, 554, 523, 466, 554, 554, 554, 554, 554, 622, 523, 466, 415, -1, 415, 622, 554, -1,
  466, 466, 415, 415, 698, 698, 622, 466, 466, 415, 415, 622, 622, 554, 523, 466, 554, 554, 554, 554, 554, 622, 523, 466, 415, 415, 415, 622, 554, 466, 466, 415, 415,
  698, 698, 622, 466, 466, 415, 415, 831, 523, 554, 523, 466, 554, 554, 554, 554, 554, 622, 523, 466, 415, -1, 415, 622, 554, -1

};

int rhythmn[] =
{
  6, 10, 6, 6, 1, 1, 1, 1, 6, 10, 4, 2, 10,
  6, 10, 6, 6, 1, 1, 1, 1, 6, 10, 4, 2, 10,
  2, 1, 1, 1, 1, 2, 1, 1, 1, 5, 1, 1, 1, 1, 3, 1, 2, 1, 5, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1,
  3, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 4, 5, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 1, 1, 1, 3, 1, 1, 1, 3,
  2, 1, 1, 1, 1, 2, 1, 1, 1, 5, 1, 1, 1, 1, 3, 1, 2, 1, 5, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1,
  3, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 4, 5, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 1, 1, 1, 3, 1, 1, 1, 3,
  1, 1, 1, 1, 3, 3, 6, 1, 1, 1, 1, 3, 3, 3, 1, 2, 1, 1, 1, 1, 3, 3, 3, 1, 2, 2, 2, 4, 8, 1, 1, 1, 1,
  3, 3, 6, 1, 1, 1, 1, 3, 3, 3, 1, 2, 1, 1, 1, 1,  3, 3, 3, 1, 2, 2, 2, 4, 8, 4,
  1, 1, 1, 1, 3, 3, 6, 1, 1, 1, 1, 3, 3, 3, 1, 2, 1, 1, 1, 1, 3, 3, 3, 1, 2, 2, 2, 4, 8, 1, 1, 1, 1,
  3, 3, 6, 1, 1, 1, 1, 3, 3, 3, 1, 2, 1, 1, 1, 1,  3, 3, 3, 1, 2, 2, 2, 4, 8, 4,
  1, 1, 1, 1, 3, 3, 6, 1, 1, 1, 1, 3, 3, 3, 1, 2, 1, 1, 1, 1, 3, 3, 3, 1, 2, 2, 2, 4, 8, 1, 1, 1, 1,
  3, 3, 6, 1, 1, 1, 1, 3, 3, 3, 1, 2, 1, 1, 1, 1,  3, 3, 3, 1, 2, 2, 2, 4, 8, 4
};

// Parts 3 or 5 (Verse 1)





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

  pinMode(3 , INPUT_PULLUP);

  Serial.begin(9600);

  //while (digitalRead(3));
}

void loop()
{
  Switch = digitalRead(3);
  int note_delay;

  check_pot();
  if (Switch == HIGH) {
    for (int i = 0 ; i < sizeof(rhythmn) ; i++)
    {
      if (melody[i] > 0) {

        check_pot();
        note_delay = tone_length * rhythmn[i];
        tone(speaker_pin, melody[i], note_delay);
      }
      delay(note_delay);
      delay(tone_length * 0.3);

    }
    delay(note_delay);
    noTone(speaker_pin);
  }


}

void check_pot()
{
  tone_length = map(analogRead(A0) , 0 , 1023 , 10 , 200);

}

 

CHALLENGES

It was a hassle trying to locate the frequencies of the notes and manipulate the duration intervals between each note.

“RA?” Party Saver

INSPIRATION

The most dreadful thing at a party is when someone knocks on the door. The booming bass abruptly stops and people scramble to hide. Now we need someone to check while others are in their safe spots. To communicate discreetly, we need a visual indicator.

IDEa

When the button is pressed, a conspicuous red exclamation appears. Once the button is released, the bright green question mark comes back. If someone turns on the light, which is very bright compared to the dim party environment, the LED indicators brighten up to signal the message better.

BREADBOARD & ARDUINO BOARD

HERE

DEMO

CODES

bool button = LOW; 
int light = 0; 

void setup() {
  // put your setup code here, to run once:
    pinMode(7, INPUT);
  for (int i = 2; i < 14; i++) {
    pinMode(i, OUTPUT);
  }
  Serial.begin(9600);
}

void loop() {
  // put your main code here, to run repeatedly:
  button = digitalRead(7);
  light = analogRead(A0);

  int mappedLight = map(light, 0, 1023, 0, 255);
  Serial.print("Analog value : ");
  Serial.print(light);
  Serial.print(" Mapped value : ");
  Serial.println(mappedLight);
  
  if (button == HIGH) {
    for (int i = 2; i < 7; i++) {
      digitalWrite (i, HIGH); //turns on red LED
      analogWrite(i, mappedLight);
    }
    for (int j = 8; j < 14; j++) {
      digitalWrite (j, LOW);        //turns off green LED
    }
  }
  else {
    for (int i = 2; i < 7; i++) {
      digitalWrite (i, LOW);        //turns off red LED
    }
    for (int j = 8; j < 14; j++) {
      digitalWrite (j, HIGH);        //turns on green LED
      analogWrite(j, mappedLight);
    }
  }
}

CHALLENGES

Given the fact that 10 LEDs were used, the breadboard obviously look messy, which made it hard to organize. It was not simple to figure out the mistake in the circuit, but, with patience, it came out alright.

“Please Don’t Laugh When I Am Sleeping”

INSPIRATION

My suitemates would bring friends over to “study” at 3 AM. They would laugh, play music, and shout all the way to 5 AM when my roommate and I had 9 AM classes the next day. Therefore, I am creating an indicator that there is someone asleep in the room and the wall is paper-thin, even though they probably know that but chose to ignore the fact. Anyways, if this subtle hint doesn’t work, I will do something else.

IDEA

When the two aluminum foil touch, the boolean turns true, and green turns off and red turns on. On the other hand, when they part, the boolean turns false, and green turns on and red turns off.

BREADBOARD & ARDUINO BOARD

Photos

VIDEO DEMO

CODES

void setup() {
  // put your setup code here, to run once:
  pinMode(4, INPUT);
  pinMode(2, OUTPUT);
  pinMode(3, OUTPUT);
}

void loop() {
  // put your main code here, to run repeatedly:
  if (bool digitalRead(4) == HIGH) {   //pressed, if the two aluminum foils touch
    digitalWrite(3, HIGH);        //turns on red LED
    digitalWrite(2, LOW);         //turns off green LED
  }
  else {                          //released, if the two aluminum foils part
    digitalWrite (3, LOW);        //turns off red LED
    digitalWrite(2, HIGH);        //turns on green LED
  };
}

CHALLENGES

  1. Maybe it’s some problems with my codes. The green light turns on immediately when the two aluminum foils touch. However, it takes 5 to 7 seconds for the boolean flips, and then the red light turns on.
  2. Sometimes when the foil connected to the resistor and the ground gets in contact with something conductive, green turns off and red turns on, signifying that the boolean flips. This may be a problem with the circuit, but I am still figuring it out.

Midterm Project: Catching Fallen Stars (Taiwanese Version)

Catching fallen stars(Taiwanese Version)

INSPIRATION:

There is a Taiwanese myth about catching fallen stars to make a wish come true. I intend to create a game that consists of a traditional Taiwanese bamboo woven basket and white stars falling from the night sky.

RULES:

The way to win is to collect 66 stars (white). The players would lose one life if hit by fallen satellite remains (red). They have three lives in total and loses the game when all three lives are wasted. However, players can catch Taiwanese street food (green) to restore lost lives.

OBJECTS:
  • Background: import an image of the Taiwanese famous night sky of lanterns
  • Sound: Background music – summer night time in Taiwanese mountains
  • Object behavior:
    1. Stars: falling with medium speed
    2. Satellite: falling with extremely fast speed
    3. Food: falling with extremely low speed
STORYBOARD:
  1. MENU (START)
  2. STORY
  3. RULES
  4. GAME
  5. Restart
    1. win
    2. lose
CHALLENGES: 
    1. The hardest part was the collision detection. It was hard to wrap my head around the logic. For the satellite remains, player lives should have decrement one when one satellite hits, but for some reason, perhaps the boundary setting or the collision content, player lives decrease ridiculously fast. However, sometimes it works perfectly. I am still in the process of figuring it out.
    2. Slight mistake: not clarifying how to play the game (what key to press)
CODES:
1. Main Function
PImage sky;
PImage stinkyTofu;
PImage sausage;
PImage oysterOmlette; 

//another variable name to create another object
Fall [] fallStars;
Fall [] fallGood;
Fall [] fallBad;

import processing.sound.*;
SoundFile bgMusic;
//SoundFile winMusic;
//SoundFile loseMusic;

//setup the basket
int stage;
float basketWidth = 100;
float basketHeight = 50;
float X = 384;
float Y = 723;
color basketColor = color(188, 123, 25);
int lives = 3;
int stars = 0;
boolean goLeft = false;
boolean goRight = false;


void setup() {
  size (1024, 768);
  
  bgMusic = new SoundFile (this, "/Users/chi-tingtsai/Downloads/summer night.mp3");
  bgMusic.loop();
  //winMusic = new SoundFile (this, "/Users/chi-tingtsai/Documents/Processing/Intro_to_IM_Midterm_ver2/data/win.mp3");
  //loseMusic = new SoundFile (this, "/Users/chi-tingtsai/Documents/Processing/Intro_to_IM_Midterm_ver2/data/lose.mp3");
  stage = 0;
  
  //setup the falling objects
  fallStars = new Fall[10];
  for (int k=0; k<fallStars.length; k++) {
    fallStars[k] = new Fall(random(width), 0, random(2, 7), color(255));
  }
  fallGood = new Fall[5];
  for (int i=0; i<fallGood.length; i++) {
    fallGood[i] = new Fall(random(width), 0, random(1, 5), color(94, 240, 134));
  }
  fallBad = new Fall[15];
  for (int l=0; l<fallBad.length; l++) {
    fallBad[l] = new Fall(random(width), 0, random(6, 10), color(234, 83, 131));
  }
}

//EXECUTION
void draw () {
  if (stage == 0) {
    menu();
  }
  if (stage == 3) {
    playGame();
  }
}

void keyReleased() {
  goLeft = false;
  goRight = false;
  if (key == ' ' && stage == 0) {
    stage = 1;
    story();
  } else if (key == ' ' && stage == 1) {
    stage = 2;
    rules();
  } else if (key == ' ' && stage == 2) {
    stage = 3;
  } else if (key == ' ' && stage == 3) {
    for (int k=0; k<fallStars.length; k++) {
      fallStars[k].restart();
    }

    for (int i=0; i<fallGood.length; i++) {
      fallGood[i].restart();
    }

    for (int l=0; l<fallBad.length; l++) {
      fallBad[l].restart();
    }
  }
}
2. MENU FUNCTION:
color frame = color(237, 168, 17);

void menu() {
  background(color(99, 144, 130));
  fill(255);
  textAlign(CENTER);
  PFont F = createFont("PatuaOne-Regular", 1);

  //explain how to start
  textFont(F, 30);
  text("Press Space Bar to Begin Game", width/2, height*3/4);
  //explain this game
  textFont(F, 50);
  text("CATCHING FALLEN STARS\n(TAIWANESE VERSION)", width/2, height/2-50);

  //frame
  noStroke();
  rectMode(CENTER);
  fill(frame);
  rect(width/2, 10, width, 20);
  rect(width/2, height-10, width, 20);
  rect(10, height/2, 20, height);
  rect(width-10, height/2, 20, height);
}
3. STORY:
int rectWidth = width/10;
int rectHeight = height/10;
float bg, up, mid, down;

void story() {
  background(color(99, 144, 130));
  fill(255);
  textAlign(CENTER);
  PFont F = createFont("PatuaOne-Regular", 1);

  //explain how to start
  textFont(F, 50);
  text("STORY", width/2, height/4);
  textFont(F, 30);
  text("A long time ago,\nDeep in the mountains of Yu and Ali,\nThere was a lake called Sun Moon Lake.\nRumor has it that if you collected enough fallen stars\nDuring Mid Autumn Festival,\nYour fears will disipate,\nInsecurities will calm,\nAnd peace will shine on you.", width/2, height/2-120);

  //frame
  noStroke();
  rectMode(CENTER);
  fill(frame);
  rect(width/2, 10, width, 20);
  rect(width/2, height-10, width, 20);
  rect(10, height/2, 20, height);
  rect(width-10, height/2, 20, height);

  //Next to Rules
  textFont(F, 40);
  text("Press Space Bar to Continue", width/2, height*3/4+75);
}
4. RULES:
int size = 200;
void rules() {
  stinkyTofu = loadImage("stinkytofu.jpeg");
  stinkyTofu.resize(size, size);
  sausage = loadImage("sausage.jpeg");
  sausage.resize(size, size);
  oysterOmlette = loadImage("oysteromlette.jpeg");
  oysterOmlette.resize(size-30, size-30);

  background(color(99, 144, 130));
  fill(255);
  textAlign(CENTER);
  PFont F = createFont("PatuaOne-Regular", 1);

  //display images of food
  image(stinkyTofu, 30, 30);
  image(sausage, 784, 30);
  image(oysterOmlette, width-200, height - 200);

  //explain how to play
  textFont(F, 50);
  text("RULES", width/2, height/4);
  textFont(F, 30);
  text("The way to win is to catch 66 stars(white)\nwith you bamboo woven basket\nYou have three lives in total.\nYou lose one life if hit by a satellite (red).\nYou lost the game when all lives are wasted.\nHowever, you can catch Taiwanese street food(green)\nto restore lost lives.", width/2, height/2-60);

  //frame
  noStroke();
  rectMode(CENTER);
  fill(frame);
  rect(width/2, 10, width, 20);
  rect(width/2, height-10, width, 20);
  rect(10, height/2, 20, height);
  rect(width-10, height/2, 20, height);
}
5. PLAY GAME:
void playGame() {
  sky = loadImage("pinxi sky lantern.jpeg");
  sky.resize(width, height);
  PFont F = createFont("PatuaOne-Regular", 1);
  noStroke();

  //background
  background (255);
  image (sky, 0, 0);

  //objects start falling
  for (int k=0; k<fallStars.length; k++) {
    fallStars[k].runFall();
  }

  for (int i=0; i<fallGood.length; i++) {
    fallGood[i].runFall();
  }

  for (int l=0; l<fallBad.length; l++) {
    fallBad[l].runFall();
  }

  //different kinds of collision
  for (int i=0; i<fallStars.length; i++) {
    fallStars[i].starcollision();
  }

  for (int k=0; k<fallGood.length; k++) {
    fallGood[k].goodcollision();
  }

  for (int l=0; l<fallBad.length; l++) {
    fallBad[l].badcollision();
  }

  //player basket
  rectMode(CENTER);
  fill(basketColor);
  rect(X, Y, basketWidth, basketHeight);
  if (goLeft == true) {
    X -= 15;
  }
  if (goRight == true) {
    X += 15;
  }

  if (stars == 66 && stage == 3) {
    background(color(99, 144, 130));
    textFont(F, 80);
    fill(255);
    text("Congratulations! You have done it!", width/2, height/2);
    textFont(F, 50);
    text("Have you found your peace?\nOr even more chaotic?\nhehe)", width/2, height/2-50);
    textFont(F, 30);
    text("Press Space Bar to Restart", width/2, height/2+50);
  }

  if (lives == 0 && stage == 3) {
    background(color(99, 144, 130));
    textFont(F, 80);
    fill(255);
    text("Game Over...", width/2, height/2);
    textFont(F, 50);
    text("Awwww... Press Space Bar to Restart?", width/2, height/2+50);
  }

  //show lives to player
  textSize(24);
  fill(color(90, 167, 247));
  text("LIVES:", width -120, height - 50);
  text(lives, width - 60, height - 50);

  //show lives to player
  fill(color(255));
  text("STARS:", 90, 60);
  text(stars, 160, 60);

  //frame
  noStroke();
  rectMode(CENTER);
  fill(frame);
  rect(width/2, 10, width, 20);
  rect(width/2, height-10, width, 20);
  rect(10, height/2, 20, height);
  rect(width-10, height/2, 20, height);
}

void keyPressed() {
  if (keyCode == LEFT) {
    goLeft = true;
  } 
  else if (keyCode == RIGHT) {
    goRight = true;
  }
  if (X <= basketWidth/2 + 10) {
    goLeft = false;
    X = basketWidth/2;
  }
  if (X >= width - basketWidth/2 - 10) {
    goRight = false;
    X = width - basketWidth/2;
  }
}
6. CLASS for Fallen Objects:
//VARIABLE
boolean goodtouch = false;
boolean badtouch = false;
boolean startouch = false;

class Fall {
  float posX, posY;
  float objectWidth;
  float objectHeight;
  color fallColor;
  float speed;

  //CONSTRUCTER
  Fall(float _posX, float _posY, float _speed, color _colorFall) {
    posX = _posX;
    posY = _posY;
    objectWidth = objectHeight = 20;
    fallColor = _colorFall;
    speed = _speed;
  }

  //FUNCTIONALITY
  void runFall() {
    colorFall();
    beginFall();
  }

  void colorFall() {
    fill(fallColor);
    noStroke();
    rect(posX, posY, objectWidth, objectHeight);
  }

  void beginFall() {
    posY += speed;
    if (posY > height+objectHeight/2) {
      posY = -objectHeight/2;
      reset();
    }
  }

  void reset() {
    posX = random(0, width);
  }

  void goodcollision() {
    if (posY + (objectHeight+basketHeight)/2 > Y && posY - (objectHeight+basketHeight)/2 < Y &&
      posX - (objectHeight+basketHeight)/2 < X && posX + (objectHeight+basketHeight)/2 > X && !goodtouch) {
      goodtouch = true;
      lives ++;
    }
    if (posY > height && goodtouch ==true) {
      goodtouch = false;
    }
    if (lives > 3) {
      lives = 3;
    }
  }

  void badcollision() {
    if (posY + (objectHeight+basketHeight)/2 > Y && posY - (objectHeight+basketHeight)/2 < Y
      && posX - (objectHeight+basketHeight)/2 < X && posX + (objectHeight+basketHeight)/2 > X && !badtouch) {
      badtouch =true;
      lives --;
    }
    if (posY > height && badtouch ==true) {
      badtouch = false;
    }
    if (lives < 0) {
      lives = 0;
    }
  }

  void starcollision() {
    if (posY + (objectHeight+basketHeight)/2 > Y && posY - (objectHeight+basketHeight)/2 < Y
      && posX - (objectHeight+basketHeight)/2 < X && posX + (objectHeight+basketHeight)/2 > X && !startouch) {
      startouch = true;
      stars ++;
    }
    if (posY > height && startouch ==true) {
      startouch = false;
    }
  }
  
  void restart() {
    stage = 3;
    lives = 3;
    stars = 0;
    posY = 0;
  }
}

 

Midterm In Progress

Catching fallen stars(Taiwanese Version)

INSPIRATION:

There is a Taiwanese myth about catching fallen stars to make a wish come true. I intend to create a game that consists of a traditional Taiwanese bamboo woven basket and white stars falling from the night sky.

RULES:

The way to win is to collect a set number of stars. The player would be faced with fallen meteoroids, plastic trash, and satellite remains. They have three lives in total and loses the game when all three lives are wasted. However, players can catch Taiwanese street food to restore lost lives.

OBJECTS:
Array to store these objects
  • Background: import an image of Taiwanese famous night sky
  • Sound:
    1. Background music: summer night time in Taiwanese mountains
    2. Fallen objects: all have their respective sounds
  • Object behavior:
    1. Meteoroids: will look like a fallen star at first, but will enlarge and transform into a disastrous meteoroid
    2. Plastic trash: if it hits the basket, the player would be paralyzed for 1-2 second
    3. Satellite: falling with extremely fast speed
    4. Food: will be moving from side to side
STORYBOARD:
  1. MENU (START/RESTART)
  2. RULES
  3. STORYTIME
  4. GAME
CODES (FOR NOW):
PImage sky;
  
void setup(){
  size (512,1024);
  //drag image into processing and it creates a file in the folder
  sky = loadImage("pinxi sky lantern.jpeg");
  noStroke();
}

void draw (){
image (sky,0,0);
}
VISUALS: 

Should extend the photo to cover the vertical interface!

P.S:

Will attempt to add a lot of Taiwanese related elements (images, sounds, stories…)