Zafran Kamaludin / Mbed 2 deprecated Final_Project_2645

Dependencies:   el14hzbm_Final_Project mbed

Fork of el14hzbm_FinalProject by ELEC2645 (2015/16)

Revision:
0:211360300ec1
Child:
1:58b4f9dda460
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Tue May 03 10:37:41 2016 +0000
@@ -0,0 +1,734 @@
+#include "mbed.h"
+#include "N5110.h"
+#include "tone.h"
+
+#define PI 3.14159265359
+#define PAUSE 1
+#define PLAY 0
+
+//connection for Nokia LCD
+N5110 lcd(PTE26,PTA0,PTC4,PTD0,PTD2,PTD1,PTC3);
+
+// connections for joystick
+InterruptIn button(PTB11);
+AnalogIn yPot(PTB2);
+AnalogIn xPot(PTB3);
+// Serial for debug
+Serial serial(USBTX,USBRX);
+
+// struct for state
+struct State {
+    int output;  // output value for current state
+    float time;  // wait time for state
+    int next_state[4]; // next state (depending on direction 0 - UP, 1 - DOWN)
+};
+typedef const struct State STyp;
+
+// array of states in the FSM, each element is the output of the counter, wait time, next state(s)
+STyp fsm[4] = {
+    {1,0.2,{1,0}},
+    {2,0.2,{2,1}},
+    {4,0.2,{3,2}},
+    {8,0.2,{0,3}}
+};
+
+void intro();
+void firstView();
+void firstViewPointer();
+void gameView();
+void initialGameInterface();
+void crash(int carValue[],int opponent_y,int g_score,int g_level,int k,int l,int delay);
+void game_interface(int g_score,int g_level,int g_liveleft);
+void live(int liveleft);
+void roadline(int moving);
+void playermovement(int g_level);
+void checkLastCar(int g_level);
+void finishLevel(int g_level);
+void optionView();
+void optionPointer();
+void finishView(int g_level);
+void brightnessController();
+void brightnessView();
+void instructionView();
+void button_isr();
+void gameplaysound(float duration);
+void crashsound();
+void pausesound();
+void score(int m,int my);
+void level(int x1,int y1);
+
+// all the stuff for tone creation
+DigitalOut buzzer(PTA2);
+DigitalOut green_led(PTC2);
+Timer noteTimer;
+void initArray();  // function to initialise sample array
+void tone(float frequency,float duration);  // play a tone of set frequency for given duration
+int n = 32;  // number of samples
+float y[32]; // array to store samples
+float BPM = 73.0;  // beats per minute
+
+int pointer_x=20;
+int pointer_y=40;
+int loop=0;
+int output=0;
+int state=0;
+float brightness_adjuster=0.0;
+volatile int g_button_flag=0;
+int g_crash=0;
+int g_liveleft=3;
+float duration=0;
+int playerSpeed=0;
+int g_level=1;
+int g_score=0;
+int carValue[10000];
+int car_x=22;          //initiate car position_x
+int car_y=38;          //initiate car position_y
+int delay=0;
+int lastCar=0;
+int game = PLAY;
+
+int main()
+{
+    lcd.init();
+    initArray();
+    button.rise(&button_isr);
+    button.mode(PullDown);
+    int output=0;
+    int state=0;
+    intro();
+
+    while(1)    {
+        // set output of current state (use dot syntax to access struct members)
+        output = fsm[state].output;
+        // implement required delay
+        //wait(fsm[state].time);
+        // set the next state depending on direction
+        //state = fsm[state].next_state[direction];
+
+        firstView();
+        gameView();
+        optionView();
+        brightnessView();
+        instructionView();
+    }
+}
+
+void intro()
+{
+    for(int k=90; k>5; k--)   {
+        lcd.printString("KAMIKAZE",k,1);
+        lcd.printString("RACE",k,2);
+        lcd.refresh();
+        wait(0.1);
+        lcd.clear();
+        if(g_button_flag==1)    {
+            g_button_flag=0;
+            break;
+        }
+    }
+}
+void firstView()
+{
+    if(state==0)    {
+        pointer_x=20;
+        pointer_y=35;
+        while(loop==0) {
+            lcd.printString("KAMIKAZE",5,1);
+            lcd.printString("RACE",5,2);
+            lcd.printString("START",25,4);
+            lcd.printString("OPTION",25,5);
+            firstViewPointer();
+            lcd.drawCircle(20,pointer_y,2,1);
+            lcd.refresh();
+            wait(0.1);
+            lcd.clear();
+            if(g_button_flag==1)    {
+                g_button_flag=0;
+                loop=1;
+                if(pointer_y==35)   {
+                    state=1;//task for game
+                } else {
+                    state=2;
+                }
+            }
+        }
+        loop=0;
+    }
+}
+
+void firstViewPointer()
+{
+    if(yPot>0.7f)    {
+        pointer_y=35;
+    }
+    if(yPot<0.3f)    {
+        pointer_y=43;
+    }
+}
+
+void gameView()
+{
+    if(state==1)    {
+
+        initialGameInterface();
+
+        while(g_crash==0)    {
+
+            for(int i=1; i<=g_level*20; i++)    {
+                carValue[i]=9*((rand()%6)+1)-5;                                     //generate all opponent car
+            }
+
+            for(int y_move=-5; y_move<100000; y_move++)  {
+
+                if(game==PLAY) {
+                    crash(carValue,y_move,g_score,g_level,car_x,car_y,delay);    //function to check whether crash occur
+                    playermovement(g_level);
+                    lcd.refresh();
+                    checkLastCar(g_level);
+                    if((y_move-(lastCar))>40)   {
+                        finishLevel(g_level);
+                        break;
+                    }
+                    if(g_crash==1)    {
+                        crashsound();                               //play sound when crush happened
+                        wait(2);                                    //delay to give time for new game
+
+                        if(g_liveleft<=1)   {                       //check if live is zero after crash occured
+                            lcd.clear();                            // if zero, game stop
+                            break;
+                        } else    {                                                 //if not zero
+                            g_crash=0;                                              //reduce the live,and continue the game
+                            g_liveleft=g_liveleft-1;                                //return the car back to initial position
+                            g_level=g_level-1;
+                            car_x=22;
+                            car_y=38;
+                            break;
+                        }
+                    }
+                    lcd.clear();
+                    g_score=g_score+1;                                  //increase the score by 1 after every loop
+                } else {
+                    y_move=y_move-1;
+                    game_interface(g_score,g_level,g_liveleft);
+                    lcd.printString("Paused",15,1);
+                    lcd.refresh();
+                }
+                if (g_button_flag==1) {
+                    g_button_flag=0;
+                    pausesound();
+                    wait(0.1);
+                    if(game == PLAY) {
+                        game = PAUSE;
+                    } else {
+                        game=PLAY;
+                    }
+                }
+            }
+            g_level=g_level+1;
+            //game coding here
+            /*if(g_button_flag==1)    {
+                g_button_flag=0;
+                loop=1;
+                state=3;
+            }*/
+        }
+        finishView(g_score);
+        g_crash=0;
+        g_liveleft=3;
+        g_level=1;
+    }
+}
+
+void crash(int carValue[],int opponent_y,int g_score,int g_level,int k,int l,int delay)
+{
+    float carPixel[84][48];
+    float enemyPixel[84][48];
+
+    lcd.clear();
+    lcd.drawCar(k,l,1);
+    lcd.refresh();
+    for(int i=0; i<=54; i++) {
+        for(int j=0; j<=48; j++) {
+            carPixel[i][j]=lcd.getPixel(i,j);
+        }
+    }
+    lcd.clear();
+
+
+    for(int i=1; i<=(g_level*20); i++)    {
+
+        if (g_level>=9) {
+            lcd.drawCar(carValue[i],opponent_y-delay,1);
+            if(i%3==0) {
+                delay=delay+20;
+            }
+        } else if(g_level>=5) {
+            lcd.drawCar(carValue[i],opponent_y-delay,1);
+            if(i%2==0) {
+                delay=delay+20;
+            }
+        } else {
+            lcd.drawCar(carValue[i],opponent_y-delay,1);
+            delay=delay+20;
+        }
+    }
+    /*if(opponent_x0==22) {
+        lcd.printString("+",opponent_x1,2);
+        lcd.drawCircle(opponent_x1+2,opponent_y,3,0);
+        lcd.printString("x",opponent_x1,2);
+        lcd.drawCircle(opponent_x1+2,opponent_y,3,0);
+    }*/
+    lcd.refresh();
+    for(int i=0; i<=54; i++) {
+        for(int j=0; j<=48; j++)  {
+            enemyPixel[i][j]=lcd.getPixel(i,j);
+        }
+    }
+
+    for(int i=0; i<=54; i++) {
+        for(int j=0; j<=48; j++)  {
+            if(enemyPixel[i][j]!=0 && carPixel[i][j]!=0)    {
+                lcd.printString("!!CRASH!!",2,2);
+                g_crash=1;
+
+            }
+        }
+    }
+    game_interface(g_score,g_level,g_liveleft);
+    lcd.drawCar(k,l,1);
+    lcd.refresh();
+    double ki=-((g_level));
+    duration=(0.02*exp(ki))+0.005;                //0.03*exp(ki))+0.005
+    if(opponent_y%5==0)  {
+        gameplaysound(duration);
+    } else {
+        wait(duration); //0.05*pow(0.9,time)+0.004
+    }
+    //lcd.clear();
+}
+
+void game_interface(int g_score,int g_level,int g_liveleft)
+{
+    score(61,2);
+    level(61,18);
+    char buffer[14];
+    int length = sprintf(buffer,"%2d",g_score/10);
+    lcd.printString(buffer,62,1);
+    int length1 = sprintf(buffer,"%2d",g_level);
+    lcd.printString(buffer,62,3);
+    live(g_liveleft);
+    roadline(g_score);
+    lcd.drawRect(59,33,22,4,1);
+}
+
+void live(int liveleft)
+{
+    lcd.drawHeart(59,40,liveleft,1);
+    lcd.refresh();
+}
+
+void roadline(int moving)
+{
+    lcd.drawLine(11,46,11,2,2);
+    lcd.drawLine(20,46,20,2,2);
+    lcd.drawLine(29,46,29,2,2);
+    lcd.drawLine(38,45,38,2,1);
+    lcd.drawLine(47,46,47,2,2);
+
+    lcd.drawLine(0,47,0,0,1);
+    lcd.drawLine(83,47,83,0,1);
+    lcd.drawLine(83,0,0,0,1);
+    lcd.drawLine(83,47,0,47,1);
+
+    if(moving%2!=0) {
+        lcd.drawLine(2,46,2,2,2);
+        lcd.drawLine(56,46,56,2,2);
+        lcd.refresh();
+    } else    {
+        lcd.drawLine(2,45,2,1,2);
+        lcd.drawLine(56,45,56,1,2);
+        lcd.refresh();
+    }
+}
+
+void playermovement(int g_level)
+{
+    if (g_level<3)  {
+        playerSpeed=3;
+    } else if(g_level<6) {
+        playerSpeed=1;
+    }
+
+    if(xPot>=0.7f)    {
+        if(car_x>-3 && car_x<49) {
+            car_x=car_x+playerSpeed;
+        }
+    }
+    if(xPot<=0.3f)    {
+        if(car_x>5 && car_x<57) {
+            car_x=car_x-playerSpeed;
+        }
+    }
+    if(yPot>0.7f)    {
+        if(car_y>5 && car_y<48) {
+            car_y=car_y-playerSpeed;
+        }
+    }
+    if(yPot<0.3f)    {
+
+        if(car_y>-3 && car_y<38) {
+            car_y=car_y+playerSpeed;
+        }
+    }
+}
+
+void checkLastCar(int g_level)
+{
+    if(g_level>=9)   {
+        lastCar=g_level*33*4;
+    } else if(g_level>=5) {
+        lastCar=g_level*50*4;
+    } else {
+        lastCar=g_level*100*4;
+    }
+}
+
+void finishLevel(int g_level)
+{
+    char buffer[48];
+    int length = sprintf(buffer,"%2d",g_level);
+    lcd.printString(buffer,24,3);
+    lcd.printString("Finish",10,1);
+    lcd.printString("Level",14,2);
+    lcd.refresh();
+    wait(2);
+    lcd.clear();
+    delay=0;
+    car_x=22;
+    car_y=38;
+}
+
+void initialGameInterface()
+{
+    for(int countdown=5; countdown>=1; countdown--)  {
+        score(62,2);
+        level(62,18);
+        lcd.printString("0",62,1);
+        lcd.printString("1",62,3);
+        lcd.drawHeart(59,40,3,1);
+
+        lcd.drawLine(0,47,0,0,1);
+        lcd.drawLine(83,47,83,0,1);
+        lcd.drawLine(83,0,0,0,1);
+        lcd.drawLine(83,47,0,47,1);
+
+        lcd.drawRect(59,33,22,4,1);
+        lcd.printString("Game",15,1);
+        lcd.printString("Start",14,2);
+        lcd.printString("In",12,3);
+        char buffer[14];
+        int length = sprintf(buffer,"%2d",countdown);
+        lcd.printString(buffer,30,3);
+
+        lcd.refresh();
+        wait(1);
+        lcd.clear();
+    }
+}
+
+void optionView()
+{
+    if(state==2)    {
+        pointer_x=5;
+        pointer_y=11;
+        while(loop==0)    {
+            lcd.printString("INSTRUCTION",10,1);
+            lcd.printString("BRIGHTNESS",10,2);
+            lcd.printString("ACHIEVEMENT",10,3);
+            lcd.printString("BACK",10,4);
+            optionPointer();
+            lcd.drawCircle(5,pointer_y,2,1);
+            lcd.refresh();
+            wait(0.1);
+            lcd.clear();
+            if(g_button_flag==1)    {
+                g_button_flag=0;
+                loop=1;
+                if(pointer_y==11)   {
+                    state=5;//task for instruction
+                } else if(pointer_y==19)   {
+                    state=4;//task for high score
+                } else if(pointer_y==35)   {
+                    state=0;//task for go back
+                } else {
+                    //state=2;
+                }
+            }
+        }
+        loop=0;
+    }
+}
+
+void optionPointer()
+{
+    if(yPot>0.7f)    {
+        if(pointer_y>11 && pointer_y<38) {
+            pointer_y=pointer_y-8;
+        }
+    }
+    if(yPot<0.3f)    {
+        if(pointer_y>5 && pointer_y<35) {
+            pointer_y=pointer_y+8;
+        }
+    }
+}
+
+void button_isr()
+{
+    g_button_flag=1;
+}
+
+void finishView(int g_score)
+{
+    char buffer[14];
+    int length = sprintf(buffer,"%2d",g_score/10);
+    lcd.printString("Your",30,1);
+    lcd.printString("Final Score",10,2);
+    lcd.printString("Is",34,3);
+    lcd.printString(buffer,34,4);
+    lcd.refresh();
+    wait(3.0);
+    lcd.clear();
+    state=0;
+    g_score=0;
+}
+
+void brightnessView()
+{
+    if(state==4)    {
+        brightness_adjuster=5;
+        while(loop==0)    {
+            brightnessController();
+            lcd.setBrightness(brightness_adjuster/10);
+            char buffer[14];
+            int length = sprintf(buffer,"%2f",brightness_adjuster);
+            lcd.printString(buffer,20,2);
+            lcd.refresh();
+            wait(0.1);
+            lcd.clear();
+            if(g_button_flag==1)    {
+                g_button_flag=0;
+                loop=1;
+                state=2;
+            }
+        }
+        loop=0;
+    }
+}
+void brightnessController()
+{
+    if(yPot>0.7f)    {
+        if(brightness_adjuster>=0 && brightness_adjuster<=9) {
+            brightness_adjuster=brightness_adjuster+1;
+        }
+    }
+    if(yPot<0.3f)    {
+        if(brightness_adjuster>=1 && brightness_adjuster<=10) {
+            brightness_adjuster=brightness_adjuster-1;
+        }
+    }
+}
+
+void achievementView()
+{
+    lcd.printString("Your",30,1);
+    lcd.printString("Final Score",10,2);
+    lcd.printString("Is",34,3);
+    lcd.printString("40000",25,4);
+}
+
+
+void instructionView()
+{
+    if(state==5)    {
+        while(loop==0)    {
+            lcd.printString("Pass Through",0,0);
+            lcd.printString("The Traffic",0,1);
+            lcd.printString("As Many As You",0,2);
+            lcd.printString("Can You Will",0,3);
+            lcd.printString("Be Given",0,4);
+            lcd.printString("Three Life",0,5);
+            lcd.refresh();
+            wait(0.1);
+            lcd.clear();
+            if(g_button_flag==1)    {
+                g_button_flag=0;
+                loop=1;
+                state=2;
+            }
+        }
+        loop=0;
+    }
+}
+
+void gameplaysound(float duration)
+{
+    float noteArray[] = {
+        // provide sound during the time game is played
+        NOTE_G3,
+    };
+
+    int notes = sizeof(noteArray)/sizeof(float);
+    for(int i=0; i < notes; i++) {
+        tone(noteArray[i],duration);
+
+    }
+}
+
+void initArray()
+{
+    // create LUT - loop through array and calculate sine wave samples
+    for (int i = 0; i < n ; i++) {
+        y[i] = 60 + 60*sin(i*2*PI/n);
+    }
+
+}
+
+void tone(float frequency,float duration)
+{
+    green_led=1;        //turn on LED
+
+    if (frequency > 0) {  // a frequency of 0 indicates no note played so only play a note if frequency is not 0
+
+        float dt = 1.0f/(frequency*n) - (1.34e-6 + 1e-6);  // calculate time step - take into account DAC time and wait() offset
+
+        noteTimer.start(); // start timer
+
+        while(noteTimer.read() < duration) { // keep looping while timer less than duration
+
+            for (int i = 0; i < n ; i++) {  // loop through samples and output analog waveform
+                buzzer = y[i];
+                wait(dt); // leave appropriate delay for frequency
+            }
+        }
+
+        noteTimer.stop();  // stop the timer
+        noteTimer.reset(); // reset to 0
+
+    } else { // if no note played, have a simple delay
+        wait(duration);
+    }
+
+    green_led = 0;   // turn off LEDs
+}
+
+void crashsound()
+{
+    float noteArray[] = {
+        // provide sound during the time game is played
+        NOTE_G5, NOTE_F6,0,NOTE_F6,NOTE_F6,NOTE_E6,0,NOTE_D6,NOTE_C6,NOTE_G5,0,NOTE_E5,NOTE_C5
+    };
+    float noteDuration[] = {
+        4,4,4,4,4,4,4,4,4,4,4,4,4
+    };
+    int notes = sizeof(noteArray)/sizeof(float);
+    for(int i=0; i < notes; i++) {
+        tone(noteArray[i],60.0f/(BPM*noteDuration[i]));
+
+    }
+}
+
+void pausesound()
+{
+    float noteArray[] = {
+        // provide sound during the time game is played
+        NOTE_E6,NOTE_C6,NOTE_E6,NOTE_C6,
+    };
+    float noteDuration[] = {
+        8,8,8,8
+    };
+    int notes = sizeof(noteArray)/sizeof(float);
+    for(int i=0; i < notes; i++) {
+        tone(noteArray[i],60.0f/(BPM*noteDuration[i]));
+
+    }
+}
+
+void score(int m,int my)
+{
+    //show score title
+    lcd.setPixel(m,my);
+    lcd.setPixel(m,my+1);
+    lcd.setPixel(m,my+2);
+    lcd.setPixel(m,my+4);
+    lcd.setPixel(m+1,my);
+    lcd.setPixel(m+1,my+2);
+    lcd.setPixel(m+1,my+4);
+    lcd.setPixel(m+2,my);
+    lcd.setPixel(m+2,my+2);
+    lcd.setPixel(m+2,my+3);
+    lcd.setPixel(m+2,my+4);
+    lcd.setPixel(m+4,my);
+    lcd.setPixel(m+4,my+1);
+    lcd.setPixel(m+4,my+2);
+    lcd.setPixel(m+4,my+3);
+    lcd.setPixel(m+4,my+4);
+    lcd.setPixel(m+5,my);
+    lcd.setPixel(m+5,my+4);
+    lcd.setPixel(m+6,my);
+    lcd.setPixel(m+6,my+4);
+    lcd.setPixel(m+8,my);
+    lcd.setPixel(m+8,my+1);
+    lcd.setPixel(m+8,my+2);
+    lcd.setPixel(m+8,my+3);
+    lcd.setPixel(m+8,my+4);
+    lcd.setPixel(m+9,my);
+    lcd.setPixel(m+9,my+4);
+    lcd.setPixel(m+10,my);
+    lcd.setPixel(m+10,my+1);
+    lcd.setPixel(m+10,my+2);
+    lcd.setPixel(m+10,my+3);
+    lcd.setPixel(m+10,my+4);
+    lcd.setPixel(m+12,my);
+    lcd.setPixel(m+12,my+1);
+    lcd.setPixel(m+12,my+2);
+    lcd.setPixel(m+12,my+3);
+    lcd.setPixel(m+12,my+4);
+    lcd.setPixel(m+13,my);
+    lcd.setPixel(m+13,my+2);
+    lcd.setPixel(m+14,my);
+    lcd.setPixel(m+14,my+1);
+    lcd.setPixel(m+14,my+3);
+    lcd.setPixel(m+14,my+4);
+    lcd.setPixel(m+16,my);
+    lcd.setPixel(m+16,my+1);
+    lcd.setPixel(m+16,my+2);
+    lcd.setPixel(m+16,my+3);
+    lcd.setPixel(m+16,my+4);
+    lcd.setPixel(m+17,my);
+    lcd.setPixel(m+17,my+2);
+    lcd.setPixel(m+17,my+4);
+    lcd.setPixel(m+18,my);
+    lcd.setPixel(m+18,my+4);
+}
+
+void level(int x1,int y1)
+{
+    int x0=x1;
+    int y0=y1;
+    lcd.drawLine(x1,y1+4,x0,y0,1);
+    lcd.drawLine(x1+2,y1+4,x0,y0+4,1);
+    lcd.drawLine(x1+4,y1+4,x0+4,y0,1);
+    lcd.drawLine(x1+6,y1,x0+4,y0,1);
+    lcd.drawLine(x1+6,y1+4,x0+4,y0+4,1);
+    lcd.setPixel(x1+5,y1+2);
+    lcd.drawLine(x1+8,y1+3,x0+8,y0,1);
+    lcd.drawLine(x1+10,y1+3,x0+10,y0,1);
+    lcd.setPixel(x1+9,y1+4);
+    lcd.drawLine(x1+12,y1+4,x0+12,y0,1);
+    lcd.drawLine(x1+14,y1,x0+12,y0,1);
+    lcd.drawLine(x1+14,y1+4,x0+12,y0+4,1);
+    lcd.setPixel(x1+13,y1+2);
+    lcd.drawLine(x1+16,y1+4,x0+16,y0,1);
+    lcd.drawLine(x1+18,y1+4,x0+16,y0+4,1);
+}
\ No newline at end of file