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:
- Title Page
- Rules
- Practice: plays demo melody
- Test
- 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:
- Adding visual cues with the demo melody
- 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




Should extend the photo to cover the vertical interface!