Racing Cars game using N5110 LCD and thumb Joystick

Dependencies:   N5110 PowerControl beep mbed

Revision:
4:f9a899c6ac50
Child:
5:243718c3cd8b
diff -r a26563b41f35 -r f9a899c6ac50 main.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Sat May 02 17:32:04 2015 +0000
@@ -0,0 +1,695 @@
+#include "N5110.h"
+#include "mbed.h"
+#include "PowerControl.h"
+#include "beep.h"
+
+
+// change this to alter tolerance of joystick direction
+#define DIRECTION_TOLERANCE 0.05
+
+// connections for joystick
+DigitalIn button(p17);
+DigitalIn select(p25);
+InterruptIn start(p24);
+
+AnalogIn yPot(p18);
+AnalogIn xPot(p19);
+Beep buzzer(p21);
+
+
+//nokia display connections
+N5110 lcd(p7,p8,p9,p10,p11,p13,p26);
+
+// timer to regularly read the joystick
+Ticker pollJoystick;
+Ticker timer;
+Ticker randomize;
+
+
+// create enumerated type (0,1,2,3 etc. for direction)
+// could be extended for diagonals etc.
+enum DirectionName {
+    UP,
+    DOWN,
+    LEFT,
+    RIGHT,
+    CENTRE,
+    UNKNOWN
+};
+
+// struct for Joystick
+typedef struct JoyStick Joystick;
+struct JoyStick {
+    float x;    // current x value
+    float x0;   // 'centred' x value
+    float y;    // current y value
+    float y0;   // 'centred' y value
+    int button; // button state (assume pull-down used, so 1 = pressed, 0 = unpressed)
+    DirectionName direction;  // current direction
+};
+// create struct variable
+Joystick joystick;
+
+//flag pointers when interrupt comes in
+int printFlag = 0;
+int buttonFlag=0;
+
+//initial enemies Y positions (p,q,c)
+int p=-20;
+int q=-100;
+int c=0;
+int j=0;
+
+//enemies X positions (p,q,c)
+int enemy1x=46;
+int enemy2x=6;
+int enemy3x=26;
+
+
+//initial player's Car position and its dimensions(w,h)
+int x=26; //x-position
+int v=30; //y-position
+int w=8; // width
+int h=12; // height
+
+//initial Coin Xposition
+int xPos=6;
+
+int lives=5;
+int coins=0;
+int round=1;
+
+float brightness=0.9;
+int brightnessDisplay=9;
+
+int table[84][48];
+
+// function prototypes
+void calibrateJoystick();
+void updateJoystick();
+void ClearCar(int x,int v,int w,int h);
+void gameInitial();
+void enemy1MovesDown();
+void enemy2MovesDown();
+void enemy3MovesDown();
+
+void movePlayer();
+void initTable();
+void loose();
+void resetPlayer();
+void checkPlayerPos();
+void coinMoves();
+void drawCoin(int c);
+void clearCoin(int c);
+void randomizeCoin();
+void setCircleCells(int x0,int y0,int radius);
+void clearCircleCells(int x0,int y0,int radius);
+void buttonPressed();
+void clearCells(int x,int y);
+void setCells(int x,int v,int w,int h);
+
+int gamePlays=1;
+int coinAppear=1;
+int enemiesMoving=1;
+int optionsPointer=1;
+int pointerSelect;
+int sounds=1;
+
+float joystickCheckTime=1.0/30.0;
+
+
+
+int main()
+
+{
+    char soundString[3];
+    sprintf(soundString,"%s","YES");
+    calibrateJoystick();  // get centred values of joystick
+    pollJoystick.attach(&updateJoystick,joystickCheckTime);  // read joystick 0 times per second
+    lcd.setXYAddress(0,0);
+    initTable();
+    lcd.init();
+    lcd.refresh();
+    start.rise(&buttonPressed);
+
+
+MainMenu:
+    buttonFlag=0;
+    pointerSelect=1;
+    clearCells(84,48);
+    lcd.drawCircle(22,19,2,1); //draw pointer around Play submenu when selected
+    lcd.drawCircle(53,19,2,1); //draw pointer around Play submenu when selected
+    lcd.printString("MAIN MENU",15,0); //print title
+    lcd.printString("Play",26,2); //print submenu title
+    lcd.printString("Options",20,3); //print submenu title
+    lcd.drawLine(15,9,65,9,1);//underline main menu title
+
+    while(buttonFlag==0) {
+
+        if (joystick.direction==DOWN) {
+            lcd.drawCircle(16,27,2,1); //draw pointer around Options submenu when selected
+            lcd.drawCircle(64,27,2,1); //draw pointer around Options submenu when selected
+
+            lcd.clearCircle(53,19,2,1);
+            lcd.clearCircle(22,19,2,1);
+
+            pointerSelect=2;
+
+        }
+        wait(0.1);
+        if(joystick.direction==UP) {
+            lcd.drawCircle(22,19,2,1); //draw pointer around Play submenu when selected
+            lcd.drawCircle(53,19,2,1); //draw pointer around Play submenu when selected
+
+            lcd.clearCircle(16,27,2,1); //draw pointer around Options submenu when selected
+            lcd.clearCircle(64,27,2,1);
+            pointerSelect=1;
+        }
+
+
+
+    }
+
+    switch(pointerSelect) {
+
+        case 1:
+        //GameBegins:
+        
+            buttonFlag=0;
+            clearCells(84,48);
+            wait(2);
+            lcd.refresh();
+            lcd.drawRect(x,v,w,h,0);
+            timer.attach(&movePlayer,0.1);
+            gameInitial();
+            char buffer[1];
+            sprintf(buffer,"%d",lives);
+            lcd.printString(buffer,74,1);
+
+
+            char buffer1[1];
+            sprintf(buffer1,"%d",round);
+            lcd.printString(buffer1,74,3);
+
+            char buffer2[2];
+            sprintf(buffer2,"%d",coins);
+            lcd.printString(buffer2,72,5);
+
+
+            //int pointerSelect;
+
+            while(gamePlays) {
+                
+                int a=select.read();
+                if(a){
+                    gamePlays=0;
+                    goto MainMenu;}
+
+                enemiesMoving=1;
+                sprintf(buffer,"%d",lives);
+                lcd.printString(buffer,74,1);
+
+                sprintf(buffer2,"%d",coins);
+                lcd.printString(buffer2,72,5);
+
+                checkPlayerPos();
+                lcd.refresh();
+                enemy1MovesDown();
+                lcd.refresh();
+                enemy2MovesDown();
+                lcd.refresh();
+                enemy3MovesDown();
+                lcd.refresh();
+                coinMoves();
+            }
+            break;
+
+        case 2:
+
+            int optionsMenu=1;
+
+            buttonFlag=0;
+
+            clearCells(84,48);
+            lcd.refresh();
+            wait(0.02);
+            lcd.printString("OPTIONS",18,0);
+            lcd.printString("Exit",23,5);
+            lcd.printString("Brightness",6,3);
+            lcd.printString("Sound",6,2);
+            lcd.drawLine(15,8,61,8,1);//underline Options Menu title
+
+            char buffer3[2];
+            sprintf(buffer3,"%d",brightnessDisplay);
+            lcd.printString(buffer3,68,3);
+
+
+            lcd.printString(soundString,40,2);
+
+            while(optionsMenu) {
+                char pointerbuffer[2];
+                sprintf(pointerbuffer,"%d",optionsPointer);
+                lcd.printString(pointerbuffer,0,0);
+
+                if (joystick.direction==UP) {
+                    optionsPointer--;
+                    if(optionsPointer==0) {
+                        optionsPointer=1;
+                    }
+                }
+                wait(0.1);
+
+                if(joystick.direction==DOWN) {
+                    optionsPointer++;
+                    if(optionsPointer>3) {
+                        optionsPointer=3;
+                    }
+
+                }
+
+
+                if (optionsPointer==1) {
+                    lcd.drawCircle(2,19,2,1);
+                    lcd.clearCircle(2,27,2,1);
+                    lcd.clearCircle(19,44,2,1);
+                    if(joystick.direction==LEFT) {
+                        sounds=1;
+                        lcd.refresh();
+                        sprintf(soundString,"%s","YES");
+                        lcd.printString(soundString,40,2);
+                    }
+                    if(joystick.direction==RIGHT) {
+                        sounds=0;
+                        lcd.refresh();
+                        sprintf(soundString,"%s","NO ");
+                        lcd.printString(soundString,40,2);
+                    }
+
+                }
+                if (optionsPointer==2) {
+                    lcd.drawCircle(2,27,2,1);
+                    lcd.clearCircle(2,19,2,1);
+                    lcd.clearCircle(19,44,2,1);
+
+                    if(joystick.direction==LEFT) {
+                        brightness=brightness-.1;
+                        brightnessDisplay=brightnessDisplay-1;
+                        if(brightness<0.1||brightnessDisplay<0) {
+                            brightnessDisplay=1;
+                            brightness=0.1;
+                        }
+                        lcd.setBrightness(brightness);
+
+                        char buffer3[2];
+                        sprintf(buffer3,"%d",brightnessDisplay);
+                        lcd.printString(buffer3,68,3);
+                    }
+
+                    if(joystick.direction==RIGHT) {
+                        brightness=brightness+.1;
+                        brightnessDisplay=brightnessDisplay+1;
+                        if(brightness>0.9||brightnessDisplay>9) {
+                            brightnessDisplay=9;
+                            brightness=0.9;
+                        }
+                        lcd.setBrightness(brightness);
+
+                        char buffer4[2];
+                        sprintf(buffer4,"%d",brightnessDisplay);
+                        lcd.printString(buffer4,68,3);
+                    }
+
+                }
+                if (optionsPointer==3) {
+                    lcd.drawCircle(19,44,2,1);
+                    lcd.clearCircle(2,19,2,1);
+                    lcd.clearCircle(2,27,2,1);
+
+                    if(buttonFlag) {
+                        goto MainMenu;
+                    }
+                }
+            wait(0.1);
+
+            }
+            break;
+    }
+}
+
+void buttonPressed()
+{
+    buttonFlag=!buttonFlag;
+}
+
+void movePlayer()
+{
+    if (gamePlays) {
+        //lcd.refresh();
+        if (joystick.direction==RIGHT&&x+w<58) {
+
+            ClearCar(x,v,w,h);
+            x=x+4;
+            lcd.drawRect(x,v,w,h,0);
+            lcd.refresh();
+            if (table[x+w][v+h]==1||table[x+w][v]==1) {
+                loose();
+            }
+
+
+        }
+
+        if (joystick.direction==LEFT&&x+w>10) {
+
+            ClearCar(x,v,w,h);
+            x=x-4;
+            lcd.refresh();
+            lcd.drawRect(x,v,w,h,0);
+            if (table[x][v]==1||table[x][v+h]==1) {
+                loose();
+            }
+
+        }
+
+        if (joystick.direction==UP && v>2) {
+
+            ClearCar(x,v,w,h);
+            v=v-4;
+            lcd.refresh();
+            lcd.drawRect(x,v,w,h,0);
+            if (table[x][v]==1||table[x+w][v]==1) {
+                loose();
+            }
+
+        }
+        if (joystick.direction==DOWN && v<32) {
+            ClearCar(x,v,w,h);
+            v=v+4;
+            lcd.refresh();
+            lcd.drawRect(x,v,w,h,0);
+            if (table[x][v+h]==1||table[x+w][v+h]==1) {
+                loose();
+            }
+
+        }
+
+    }
+}
+
+// read default positions of the joystick to calibrate later readings
+void calibrateJoystick()
+{
+    button.mode(PullDown);
+    // must not move during calibration
+    joystick.x0 = xPot;  // initial positions in the range 0.0 to 1.0 (0.5 if centred exactly)
+    joystick.y0 = yPot;
+}
+void updateJoystick()
+{
+    // read current joystick values relative to calibrated values (in range -0.5 to 0.5, 0.0 is centred)
+    joystick.x = xPot - joystick.x0;
+    joystick.y = yPot - joystick.y0;
+    // read button state
+    joystick.button = button;
+
+    // calculate direction depending on x,y values
+    // tolerance allows a little lee-way in case joystick not exactly in the stated direction
+    if ( fabs(joystick.y) < DIRECTION_TOLERANCE && fabs(joystick.x) < DIRECTION_TOLERANCE) {
+        joystick.direction = CENTRE;
+    } else if ( joystick.y > DIRECTION_TOLERANCE && fabs(joystick.x) < DIRECTION_TOLERANCE) {
+        joystick.direction = UP;
+    } else if ( joystick.y < DIRECTION_TOLERANCE && fabs(joystick.x) < DIRECTION_TOLERANCE) {
+        joystick.direction = DOWN;
+    } else if ( joystick.x > DIRECTION_TOLERANCE && fabs(joystick.y) < DIRECTION_TOLERANCE) {
+        joystick.direction = LEFT;
+    } else if ( joystick.x < DIRECTION_TOLERANCE && fabs(joystick.y) < DIRECTION_TOLERANCE) {
+        joystick.direction = RIGHT;
+    } else {
+        joystick.direction = UNKNOWN;
+    }
+
+    // set flag for printing
+    printFlag = 1;
+}
+
+
+void ClearCar(int x,int v,int w,int h)
+{
+    for(int i=x; i<=x+w; i++) {
+        for(int j=v; j<=v+h; j++) {
+            lcd.clearPixel(i,j);
+            table[i][j]=0;
+        }
+    }
+}
+
+void gameInitial()
+{
+    lcd.drawLine(60,0,60,48,1);
+    lcd.drawLine(60,16,84,16,1);
+    lcd.drawLine(60,32,84,32,1);
+    lcd.drawLine(20,0,20,48,2);
+    lcd.drawLine(40,0,40,48,2);
+}
+
+
+
+
+void enemy1MovesDown()
+{
+    ClearCar(enemy1x,(j-4),w,h);
+    lcd.drawRect(enemy1x,j,w,h,1);
+    setCells(enemy1x,j,w,h);
+    wait(0.05);
+    lcd.refresh();
+
+
+    j=j+4;
+    lcd.refresh();
+
+    if(j>60) {
+        j=-(rand()%100+80);
+    }
+
+}
+
+
+
+void enemy2MovesDown()
+{
+    ClearCar(enemy2x,(p-4),w,h);
+    lcd.drawRect(enemy2x,p,w,h,1);
+    setCells(enemy2x,p,w,h);
+    wait(0.05);
+    lcd.refresh();
+    p=p+4;
+    lcd.refresh();
+
+    if(p>60) {
+        p=-(rand()%40+20);
+    }
+    while(p==q) {
+        p=-(rand()%40+20);
+    }
+
+}
+
+void enemy3MovesDown()
+{
+    ClearCar(enemy3x,(q-4),w,h);
+    lcd.drawRect(enemy3x,q,w,h,1);
+    setCells(enemy3x,q,w,h);
+    wait(0.05);
+    lcd.refresh();
+    q=q+4;
+    lcd.refresh();
+    if (q>70) {
+        q=-(rand()%10+1);
+    }
+
+}
+
+void setCells(int x,int v,int w,int h)
+{
+
+    for(int i=x; i<=x+w; i++) {
+        for(int j=v; j<=v+h; j++) {
+            if(j>0&&j<48) {
+                table[i][j]=1;
+            }
+        }
+    }
+}
+
+void initTable()
+{
+    for (int i=0; i<=84; i++) {
+        for(int j=0; j<=48; j++) {
+            table[i][j]=0;
+        }
+    }
+}
+
+void checkPlayerPos()
+{
+    if (table[x+w][v+h]==1||table[x][v+h]==1||table[x][v]==1||table[x+w][v]==1) {
+        loose();
+
+    }
+    if (table[x+w][v+h]==2||table[x][v+h]==2||table[x][v]==2||table[x+w][v]==2) {
+        coins=coins+10;
+        coinAppear=0;
+        if(sounds) {
+            buzzer.beep(2200,0.4);
+            buzzer.beep(1000,0.2);
+        }
+    }
+
+}
+
+
+void coinMoves()
+{
+    clearCoin(c);
+    c=c+2;
+    drawCoin(c);
+
+    wait(0.05);
+    if(c>70) {
+        randomizeCoin();
+        coinAppear=1;
+        c=-100;
+    }
+}
+
+void drawCoin(int c)
+{
+    if (table[xPos][c+4]==0&&table[xPos][c-4]==0&&coinAppear) {
+        lcd.drawCircle(xPos,c,4,0);
+        setCircleCells(xPos,c,4);
+
+        lcd.setPixel(xPos,c-1);
+        lcd.setPixel(xPos,c+2);
+
+        lcd.setPixel(xPos+1,c-1);
+        lcd.setPixel(xPos+1,c+2);
+
+        lcd.setPixel(xPos-1,c);
+        lcd.setPixel(xPos-1,c+1);
+        lcd.refresh();
+    }
+}
+
+void clearCoin(int c)
+{
+    lcd.clearCircle(xPos,c,4,0);
+    clearCircleCells(xPos,c,4);
+
+    lcd.clearPixel(xPos,c-1);
+    lcd.clearPixel(xPos,c+2);
+
+    lcd.clearPixel(xPos+1,c-1);
+    lcd.clearPixel(xPos+1,c+2);
+
+    lcd.clearPixel(xPos-1,c);
+    lcd.clearPixel(xPos-1,c+1);
+    lcd.refresh();
+
+}
+
+void randomizeCoin()
+{
+int randX;
+
+    randX=rand()%3+1;
+
+    if (randX==1) {
+        xPos=6;
+    }
+    if (randX==2) {
+        xPos=26;
+    }
+    if (randX==3) {
+        xPos=46;
+    }
+}
+
+void setCircleCells(int x0,int y0,int radius)
+{
+    int x = radius;
+    int y = 0;
+    if(y0>0) {
+        while(x >= y) {
+
+            table[x+x0][y+y0]=2;
+            table[-x+x0][y+y0]=2;
+            table[y+x0][x+y0]=2;
+
+            table[-y+x0][x+y0]=2;
+            table[-y+x0][-x+y0]=2;
+
+            table[y+x0][-x+y0]=2;
+            table[-x+x0][-y+y0]=2;
+            table[-x+x0][-y+y0]=2;
+            y++;
+        }
+    }
+}
+
+void clearCircleCells(int x0,int y0,int radius)
+{
+    int x = radius;
+    int y = 0;
+
+    while(x >= y) {
+
+        // if transparent, just draw outline
+        table[x+x0][y+y0]=0;
+        table[-x+x0][y+y0]=0;
+        table[y+x0][x+y0]=0;
+
+        table[-y+x0][x+y0]=0;
+        table[-y+x0][-x+y0]=0;
+
+        table[y+x0][-x+y0]=0;
+        table[-x+x0][-y+y0]=0;
+        table[-x+x0][-y+y0]=0;
+        y++;
+    }
+}
+
+void clearCells(int x,int y)
+{
+    for(int i=0; i<=x; i++) {
+        for (int j=0; j<=y; j++) {
+            lcd.clearPixel(i,j);
+            table[i][j]=0;
+        }
+    }
+
+}
+
+void loose()
+{
+    if (sounds) {
+        buzzer.beep(500,0.1);
+    }
+    lives=lives-1;
+    gamePlays=0;
+    wait(0.5);
+    ClearCar(x,v,w,h);
+    lcd.refresh();
+    clearCells(60,48);
+    lcd.setXYAddress(0,0);
+
+    wait(1);
+    lcd.refresh();
+    x=26;
+    v=30;
+    lcd.drawRect(x,v,w,h,0);
+    wait(0.5);
+    gamePlays=1;
+    j=-100;
+    p=-50;
+    q=-40;
+}
+