an mbed tile music game using a capacitive touchpad and uLCD

Dependencies:   SDFileSystem mbed wave_player

Revision:
0:a1c374b9a4fe
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Mon Mar 14 00:26:24 2016 +0000
@@ -0,0 +1,397 @@
+//ECE 4180 Piano Tiles
+//Spring 2016 Georgia Tech
+//Kushagra Brahmbhatt
+//Christopher Lu
+
+#include "mbed.h"
+#include "uLCD_4DGL.h"
+#include <mpr121.h>
+#include "SongPlayer.h"
+#include "SDFileSystem.h"
+#include "wave_player.h"
+
+//LCD better
+uLCD_4DGL uLCD(p28,p27,p29);
+
+//Speaker 
+SongPlayer mySpeaker(p21);
+AnalogOut Speaker(p18); 
+
+// Setup the i2c bus on pins 9 and 10
+I2C i2c(p9, p10);
+
+// Setup the Mpr121:
+// Create the interrupt receiver object on pin 26
+InterruptIn interrupt(p26);
+// constructor(i2c object, i2c address of the mpr121)
+Mpr121 mpr121(&i2c, Mpr121::ADD_VSS);
+
+// the pinout on the mbed Cool Components workshop board
+SDFileSystem sd(p5, p6, p7, p8, "sd"); 
+
+//timer
+Timer t;
+
+//bool key0Press, key4Press, key8Press;
+int vals;
+bool interruptBool;
+int score, timer;
+
+// Key hit/release interrupt routine
+void fallInterrupt() { //void
+
+  int value=mpr121.read(0x00);
+  
+  //wait(2);
+  value +=mpr121.read(0x01)<<8;
+  interruptBool = true;
+  vals = value;
+}  
+
+
+int press() {
+    int value=mpr121.read(0x00);
+    value +=mpr121.read(0x01)<<8;
+    //1(key 0)  2(key 1)  4  8  16 32 64 128 256 512 1024 2048(key 11)
+    return value;
+}
+
+bool check(int value) {
+    if (value == 1) { //key0
+        if(uLCD.read_pixel(15,90)==BLACK) {
+            return true;    
+        }
+    }
+    if (value == 16) { //key4
+        if(uLCD.read_pixel(50,90)==BLACK) {
+            return true;    
+        }
+    }
+    if (value == 256) { //key8
+        if(uLCD.read_pixel(90,90)==BLACK) {
+            return true;    
+        }    
+    }
+    return false;
+}
+
+//initialize the graphics for the game
+void startGame(){
+    uLCD.background_color(WHITE);
+    uLCD.cls();
+    //draw walls 
+    uLCD.filled_rectangle(0,103,10,0, BLUE);
+    uLCD.filled_rectangle(117,103,127,0, BLUE); 
+    uLCD.filled_rectangle(10,78,117,103, 0xFDF983);
+    uLCD.locate(0,13);
+    uLCD.textbackground_color(WHITE);
+    uLCD.color(RED);
+    uLCD.printf("Score: "); 
+    uLCD.locate(9,13);
+    uLCD.printf("Time:");
+    uLCD.locate(4,14);
+    uLCD.text_width(1); //4X size text
+    uLCD.text_height(2);
+    uLCD.printf("Piano Tiles");
+    
+     
+    //draw the lines
+    uLCD.line(10, 26, 117, 26, BLACK);
+    uLCD.line(10, 52, 117, 52, BLACK);
+    uLCD.line(10, 78, 117, 78, BLACK);
+    uLCD.line(10, 103, 117, 103, BLACK);
+    
+    uLCD.line(46, 0, 46, 103, BLACK);
+    uLCD.line(82, 0, 82, 103, BLACK);
+    
+}
+
+//moves block down
+int updateBlockY1(int y) {
+    y = y + 26;
+    if (y > 81) {
+        y = 3;
+    }
+    return y;
+}
+
+int updateBlockY2(int y) {
+    y = y + 26;
+    if (y > 101) {
+        y = 23;
+    }
+    return y;
+}
+
+//Frequency of notes for Fur Elise 
+float note[85]= {329.63,311.13,329.63,311.13,329.63,246.94,293.66,261.63,220.00,
+                 146.83,174.61,220.0,246.94,174.61,233.08,246.94,261.63, 329.63, 
+                 311.13, 329.63, 246.94, 293.66, 261.63, 220.00, 146.83, 174.61, 
+                 220.00, 246.94, 174.61, 261.63, 246.94, 220.00, 246.94, 261.63, 
+                 293.66, 329.63, 196.00, 329.23, 329.23, 293.63, 164.81, 329.63, 
+                 293.63, 261.63, 146.83, 293.63, 261.63, 246.94, 329.63, 311.13, 
+                 329.63, 311.13, 329.63, 246.94, 293.66, 261.63, 220.00, 146.83, 
+                 174.61, 220.00, 246.94, 174.61, 233.08, 246.94, 261.63, 329.63, 
+                 311.13, 329.63, 311.13, 329.63, 311.13, 329.63, 246.94, 293.66, 
+                 261.63, 220.00, 146.83, 174.61, 220.00, 246.94, 174.61, 261.63, 
+                 246.94, 220.0, 0.0};
+//How long each note plays for
+float duration[85]= {0.3,0.3,0.3,0.3,0.30,0.30,0.30,0.30,0.30,
+                     0.30,0.30,0.30,0.30,0.30,0.30,0.30,0.30,
+                     0.30, 0.30, 0.30, 0.30, 0.30, 0.30, 0.30, 
+                     0.30, 0.30, 0.30, 0.30, 0.30, 0.30, 0.30, 
+                     0.30, 0.30, 0.30, 0.30, 0.30, 0.30, 0.30, 
+                     0.30, 0.30, 0.30, 0.30, 0.30, 0.30, 0.30, 
+                     0.30, 0.30, 0.30, 0.30, 0.30, 0.30, 0.30, 
+                     0.30, 0.30, 0.30, 0.30, 0.30, 0.30, 0.30, 
+                     0.30, 0.30, 0.30, 0.30, 0.30, 0.30, 0.30, 
+                     0.30, 0.30, 0.30, 0.30, 0.30, 0.30, 0.30, 
+                     0.30, 0.30, 0.30, 0.30, 0.30, 0.30, 0.30, 
+                     0.30, 0.30, 0.30, 0.30, 0.0};
+
+
+int main() {
+    
+    //wait 4 seconds then moves on to graphics of the game
+    uLCD.locate(3,4);
+    uLCD.text_width(1); 
+    uLCD.text_height(2);
+    uLCD.printf("Piano Tiles!!!\n");
+    uLCD.text_height(1);
+    uLCD.locate(5,8);
+    uLCD.printf("Playing:");
+    uLCD.locate(5,9);
+    uLCD.printf("Beethoven");
+    uLCD.locate(5,10);
+    uLCD.printf("Fur Elise");
+    uLCD.locate(0,12);
+    uLCD.printf("Get a score above ");
+    uLCD.locate(4,13);
+    uLCD.printf("100 to win!");
+    wait(4);
+    
+    interrupt.fall(&fallInterrupt);
+    interrupt.mode(PullUp);
+    startGame();
+    
+    //initialization to track tiles
+    int a[16];
+    int y1 = 81; //starting y coordinate to fill in rectangle from the bottom
+    int y2 = 101;
+    int position = 1; //tracks placement of the previous tile for tone so tiles are placed by tones
+    
+    
+    //initializing the first four set of piano tiles
+    for (int i = 0; i < 4; i++) {
+        if (note[i] < note[i-1] && i != 0){    //if (note<previousnote) then next tile is to the left
+            uLCD.filled_rectangle(49,y1,79,y2, BLACK);
+            a[4*i + 0] = 49;
+            a[4*i + 1] = y1;
+            a[4*i + 2] = 79;
+            a[4*i + 3] = y2; 
+            position = 2;
+        } 
+        else if (i == 0 || note[i] > note[i-1]) {    //initial start is on right side of screen
+            uLCD.filled_rectangle(85,y1,115,y2, BLACK);
+            a[4*i + 0] = 85;
+            a[4*i + 1] = y1;
+            a[4*i + 2] = 115;
+            a[4*i + 3] = y2; 
+            position = 3;
+        }
+        //move from bottom of the screen to the top
+        y1 = y1 - 26; 
+        y2 = y2 - 26;
+    }
+    //array used for holding all the tiles
+    int block1_x1 = a[0];
+    int block1_y1 = a[1];
+    int block1_x2 = a[2];
+    int block1_y2 = a[3];
+    int block2_x1 = a[4];
+    int block2_y1 = a[5];
+    int block2_x2 = a[6];
+    int block2_y2 = a[7];
+    int block3_x1 = a[8];
+    int block3_y1 = a[9];
+    int block3_x2 = a[10];
+    int block3_y2 = a[11];
+    int block4_x1 = a[12];
+    int block4_y1 = a[13];
+    int block4_x2 = a[14];
+    int block4_y2 = a[15];
+
+    t.start();
+    
+    //starting the game
+    while(1) {
+        if (interruptBool) { //key is pressed
+        uLCD.locate(0,0);
+        bool checkTrue = check(vals);
+        uLCD.locate(0,0);
+
+        if (checkTrue) { //if right correct key is pressed, tiles are replaced and move down
+            uLCD.filled_rectangle(block1_x1, block1_y1, block1_x2, block1_y2, WHITE);
+            uLCD.filled_rectangle(block2_x1, block2_y1, block2_x2, block2_y2, WHITE);
+            uLCD.filled_rectangle(block3_x1, block3_y1, block3_x2, block3_y2, WHITE);
+            uLCD.filled_rectangle(block4_x1, block4_y1, block4_x2, block4_y2, WHITE);
+            block1_y1 = updateBlockY1(block1_y1);
+            block1_y2 = updateBlockY2(block1_y2);
+            block2_y1 = updateBlockY1(block2_y1);
+            block2_y2 = updateBlockY2(block2_y2);
+            block3_y1 = updateBlockY1(block3_y1);
+            block3_y2 = updateBlockY2(block3_y2);
+            block4_y1 = updateBlockY1(block4_y1);
+            block4_y2 = updateBlockY2(block4_y2);
+            
+            //the following if statements determine position of the following tiles based on the
+            //frequencies of the note that is being played
+            if(block1_y1 == 3) 
+            {
+                if (note[score%85+4] < note[score%85+3] && (position == 1 || position == 2)) {
+                    block1_x1 = 13;
+                    block1_x2 = 43;
+                    position = 1;
+                } else if ((note[score%85+4] < note[score%85+3] && position == 3) || (note[score%85+4] > note[score%85+3] && position == 1 )) {
+                    block1_x1 = 49;
+                    block1_x2 = 79;  
+                    position = 2;
+                } else if (note[score%85+4] > note[score%85+3] && (position == 2 || position == 3))  {
+                    block1_x1 = 85;
+                    block1_x2 = 115;  
+                    position = 3;
+                }
+            }
+            if(block2_y1 == 3) 
+            {
+                if (note[score%85+4] < note[score%85+3] && (position == 1 || position == 2)) {
+                    block2_x1 = 13;
+                    block2_x2 = 43;
+                    position = 1;
+                } else if ((note[score%85+4] < note[score%85+3] && position == 3) || (note[score%85+4] > note[score%85+3] && position == 1 )) {
+                    block2_x1 = 49;
+                    block2_x2 = 79;  
+                    position = 2;
+                } else if (note[score%85+4] > note[score%85+3] && (position == 2 || position == 3))  {
+                    block2_x1 = 85;
+                    block2_x2 = 115;  
+                    position = 3;
+                }
+            }
+            if(block3_y1 == 3) 
+            {
+                if (note[score%85+4] < note[score%85+3] && (position == 1 || position == 2)) {
+                    block3_x1 = 13;
+                    block3_x2 = 43;
+                    position = 1;
+                } else if ((note[score%85+4] < note[score%85+3] && position == 3) || (note[score%85+4] > note[score%85+3] && position == 1 )) {
+                    block3_x1 = 49;
+                    block3_x2 = 79;  
+                    position = 2;
+                } else if (note[score%85+4] > note[score%85+3] && (position == 2 || position == 3))  {
+                    block3_x1 = 85;
+                    block3_x2 = 115;  
+                    position = 3;
+                }
+            }
+            if(block4_y1 == 3) 
+            {
+                if (note[score%85+4] < note[score%85+3] && (position == 1 || position == 2)) {
+                    block4_x1 = 13;
+                    block4_x2 = 43;
+                    position = 1;
+                } else if ((note[score%85+4] < note[score%85+3] && position == 3) || (note[score%85+4] > note[score%85+3] && position == 1 )) {
+                    block4_x1 = 49;
+                    block4_x2 = 79;  
+                    position = 2;
+                } else if (note[score%85+4] > note[score%85+3] && (position == 2 || position == 3))  {
+                    block4_x1 = 85;
+                    block4_x2 = 115;  
+                    position = 3;
+                }
+            }
+            
+            //fill in the tiles
+            uLCD.filled_rectangle(block1_x1, block1_y1, block1_x2, block1_y2, BLACK);
+            uLCD.filled_rectangle(block2_x1, block2_y1, block2_x2, block2_y2, BLACK);
+            uLCD.filled_rectangle(block3_x1, block3_y1, block3_x2, block3_y2, BLACK);
+            uLCD.filled_rectangle(block4_x1, block4_y1, block4_x2, block4_y2, BLACK);
+            interruptBool = false;
+            
+            //plays the note as the keypad is being pressed
+            float note1[] = {note[score%85]};
+            float duration1[] = {duration[score%85]};
+            mySpeaker.PlaySong(note1,duration1);
+            score++;
+            
+            //updates the time and score
+            uLCD.text_width(1);
+            uLCD.text_height(1);
+            uLCD.locate(0,13);
+            uLCD.textbackground_color(WHITE);
+            uLCD.color(RED);
+            uLCD.printf("Score:%d", score); 
+            uLCD.locate(9,13);
+            uLCD.printf("Time:%0.1f", t.read());
+
+            
+        } 
+        else { //while loop breaks when the wrong key is pressed
+            break;
+            //Game Over Screen outside while loop    
+            }
+        } //end of interruptBool
+    }//end of while loop
+    
+
+        //win or lose music
+        wave_player waver(&Speaker);
+        //vector<string> filenames; //filenames are stored in a vector string
+        bool  PLAY = true;
+        bool  *PlayStopPtr = &PLAY;
+        FILE *wave_file;
+ 
+ //victory and game over screen
+    if (score >= 100)
+    {
+        uLCD.cls();
+        uLCD.locate(0,4);
+        uLCD.text_width(2); //4X size text
+        uLCD.text_height(2);
+        uLCD.printf("Victory!!");
+        uLCD.text_width(1); //4X size text
+        uLCD.text_height(1);
+        uLCD.locate(4,7);
+        uLCD.printf("SCORE:%d", score);
+        t.stop();
+        uLCD.locate(4,8);
+        uLCD.printf("Time:%0.2f", t.read());
+        uLCD.locate(0,10);
+        uLCD.printf("Thanks for playing");
+        
+        FILE *wave_file;
+        wave_file=fopen("/sd/wavfiles/victory.wav","r");
+        waver.play(wave_file,PlayStopPtr);
+    }
+    else
+    {
+        uLCD.cls();
+        uLCD.locate(0,4);
+        uLCD.text_width(2); //4X size text
+        uLCD.text_height(2);
+        uLCD.printf("Game Over");
+        uLCD.text_width(1); //4X size text
+        uLCD.text_height(1);
+        uLCD.locate(4,7);
+        uLCD.printf("SCORE:%d", score);
+        t.stop();
+        uLCD.locate(4,8);
+        uLCD.printf("Time:%0.2f", t.read());
+        uLCD.locate(0,10);
+        uLCD.printf("Thanks for playing");
+        
+        FILE *wave_file;
+        wave_file=fopen("/sd/wavfiles/defeat.wav","r");
+        waver.play(wave_file,PlayStopPtr);
+    }
+}