an mbed tile music game using a capacitive touchpad and uLCD

Dependencies:   SDFileSystem mbed wave_player

main.cpp

Committer:
clu67
Date:
2016-03-14
Revision:
0:a1c374b9a4fe

File content as of revision 0:a1c374b9a4fe:

//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);
    }
}