Racing Cars game using N5110 LCD and thumb Joystick
Dependencies: N5110 PowerControl beep mbed
Diff: main.cpp
- 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; +} +