Zafran Kamaludin / Mbed 2 deprecated Final_Project_2645

Dependencies:   el14hzbm_Final_Project mbed

Fork of el14hzbm_FinalProject by ELEC2645 (2015/16)

main.cpp

Committer:
Zafranhernandez
Date:
2016-05-03
Revision:
0:211360300ec1
Child:
1:58b4f9dda460

File content as of revision 0:211360300ec1:

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