Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: N5110 PinDetect PowerControl mbed
BrickBreaker.cpp
- Committer:
- el13cj
- Date:
- 2015-05-10
- Revision:
- 10:19c6aba3beec
- Parent:
- 9:8447ce6f51ae
- Child:
- 11:d9d5bad8f5e2
File content as of revision 10:19c6aba3beec:
/** * @file BrickBreaker.cpp * * @brief Function implementations * @brief Credits to Craig A. Evans for his implementation of the 2-axis Joystick. * */ #include "BrickBreaker.h" #include "mbed.h" // Initialise the N5110 screen // VCC,SCE,RST,D/C,MOSI,SCLK,LED // \ \ | | / / / N5110 lcd(p7,p8,p9,p10,p11,p13,p26); int main() { PHY_PowerDown(); int result = semihost_powerdown(); lcd.init(); calibrateJoystick(); initBricks(0); readHighScores(); pollJoystick.attach(&updateJoystick,1.0/10); // read joystick 10 times per second select.attach(&getMenuSelect,0.15); movePaddle.attach(&paddle,0.025); initBricks(0); button.attach_asserted(&newScreen); button.setSampleFrequency(); playPause.mode(PullUp); playPause.attach_asserted(&pause); playPause.setSampleFrequency(); while(1) { while(displayMenu == 1) { menu(); } while(displayGame == 1) { game(startStop); if (lives < 0) { displayGame = 0; displayGameOver = 1; } if (getNumBricks() == 0) { newLevel(); } } while(displayHelp == 1) { help(); } while(displayHighScores == 1) { highScores(); } while(displayGameOver == 1) { gameOver(); } lcd.refresh(); } } void readHighScores() { FILE *fp = fopen("/local/scores.txt","r"); fscanf(fp,"%i",&highscore1); fscanf(fp,"%i",&highscore2); fscanf(fp,"%i",&highscore3); fclose(fp); } void writeHighScores() { FILE *fp = fopen("/local/scores.txt","w"); fprintf(fp,"%i\r\n",highscore1); fprintf(fp,"%i\r\n",highscore2); fprintf(fp,"%i\r\n",highscore3); fclose(fp); } void newLevel() { lcd.clear(); level++; initBricks(level); by = 30; bx = 42; px = 38; d = 8; lcd.refresh(); } void pause() { if (displayGame == 1) { startStop = !startStop; } } int getNumBricks() { int sum = 0; for (int i = 0; i < 8; i++) { for (int j = 0; j < 4; j++) { sum+=bricks[j][i]; } } return sum; } int lifeLost() { if (by >= 48 && by <= 50) { lives-=1; by = 30; bx = 42; px = 38; d = 8; startStop = 0; return 1; } else { return 0; } } void game(int g) { if (g == 1) { lifeLost(); borderInit(); dispScore(); dispLives(); ball(); } else if (g == 0) { } } void highScores() { readHighScores(); lcd.clear(); lcd.printString("HIGH SCORES",10,0); lcd.printString("1/",10,1); lcd.printNum(highscore1,30,1); lcd.printString("2/",10,2); lcd.printNum(highscore2,30,2); lcd.printString("3/",10,3); lcd.printNum(highscore3,30,3); lcd.printString("menu",10,5); lcd.printString(">",5,5); lcd.refresh(); Sleep(); } void help() { //menuSelect = 35; if (helpScreen == 0) { lcd.clear(); lcd.printString("HELP",10,0); lcd.printString("Destroy bricks",0,1); lcd.printString("to reach the",0,2); lcd.printString("next level",0,3); lcd.printString("more",40,5); lcd.printString("menu",10,5); lcd.printString(">",helpSelect,5); lcd.refresh(); Sleep(); } else if (helpScreen == 1) { lcd.clear(); lcd.printString("HELP",10,0); lcd.printString("Use joystick",0,1); lcd.printString("to control",0,2); lcd.printString("the paddle",0,3); lcd.printString("more",40,5); lcd.printString("menu",10,5); lcd.printString(">",helpSelect,5); lcd.refresh(); Sleep(); } else if (helpScreen == 2) { lcd.clear(); lcd.printString("HELP",10,0); lcd.printString("Pause the game",0,1); lcd.printString("using the >/||",0,2); lcd.printString("button",0,3); lcd.printString("more",40,5); lcd.printString("menu",10,5); lcd.printString(">",helpSelect,5); lcd.refresh(); Sleep(); } else if (helpScreen == 3) { lcd.clear(); lcd.printString("HELP",10,0); lcd.printString("Control volume",0,1); lcd.printString("using the blue",0,2); lcd.printString("potentiometer",0,3); lcd.printString("more",40,5); lcd.printString("menu",10,5); lcd.printString(">",helpSelect,5); lcd.refresh(); Sleep(); } } void gameOver() { lcd.clear(); lcd.printString("GAME OVER",10,0); lcd.printString("score",10,1); lcd.printNum(score,42,1); lcd.printString(">menu",10,5); if ((score >= highscore1) && scoreFlag) { highscore3 = highscore2; highscore2 = highscore1; highscore1 = score; writeHighScores(); scoreFlag = 0; } else if ((score >= highscore2) && scoreFlag) { highscore3 = highscore2; highscore2 = score; writeHighScores(); scoreFlag = 0; } else if ((score >= highscore3) && scoreFlag) { highscore3 = score; writeHighScores(); scoreFlag = 0; } if (score >= highscore3) { lcd.printString("NEW HIGH SCORE",0,3); } lcd.refresh(); Sleep(); } void newScreen() { if (displayMenu) { switch (menuSelect) { case 1: lcd.clear(); displayMenu = 0; displayGame = 1; break; case 2: displayMenu = 0; displayHelp = 1; break; case 3: displayMenu = 0; displayHighScores = 1; break; } } else if (displayHelp) { switch (helpSelect) { case 5: displayMenu = 1; displayHelp = 0; break; case 35: helpScreen++; if (helpScreen > 3) { helpScreen = 0; } break; } } else if (displayHighScores) { displayMenu = 1; displayHighScores = 0; } else if (displayGame) { startStop = !startStop; } else if (displayGameOver) { displayMenu = 1; displayGameOver = 0; } } void getMenuSelect() { if (displayMenu) { if (joystick.direction == DOWN) { lcd.clearRect(5,(menuSelect*8),5,8); if (menuSelect < 3) { menuSelect++; } else if (menuSelect == 3) { menuSelect = 1; } } else if (joystick.direction == UP) { lcd.clearRect(5,(menuSelect*8),5,8); if (menuSelect > 1) { menuSelect-=1; } else if (menuSelect == 1) { menuSelect = 3; } } } else if (displayHelp) { if (joystick.direction == RIGHT) { lcd.clearRect(helpSelect,40,5,8); if (helpSelect < 35) { helpSelect+=30; } else if (menuSelect == 35) { helpSelect = 5; } } else if (joystick.direction == LEFT) { lcd.clearRect(helpSelect,40,5,8); if (helpSelect > 5) { helpSelect-=30; } else if (menuSelect == 5) { helpSelect = 35; } } } } void menu() { lcd.clear(); lcd.printString("BRICK BREAKER",0,0); lcd.printString("Start",10,1); lcd.printString("Help",10,2); lcd.printString("Scores",10,3); lcd.printString(">",5,menuSelect); lives = 3; score = 0; initBricks(0); startStop = 1; level = 0; scoreFlag = 1; lcd.refresh(); Sleep(); } void dispLives() { lcd.printNum(lives,77,5); lcd.printChar(0x80,77,4); } void dispScore() { if (score<10) { lcd.printNum(score,77,0); } else if (score<100) { lcd.printNum(((score/10)%10),77,0); lcd.printNum((score%10),77,1); } else if (score<1000) { lcd.printNum(((score/100)%10),77,0); lcd.printNum(((score/10)%10),77,1); lcd.printNum((score%10),77,2); } } void doBricks() { for (int x = 0; x<8; x++) { for (int y = 0; y<4; y++) { getBrickTouch(x,y); } } for (int i = 0; i < 4; i++) { for (int j = 0; j < 8; j++) { if (bricks[i][j] && brickDrawFlag[i][j]) { lcd.drawRect(bricksx[j],bricksy[i], 6, 2, 1); brickDrawFlag[i][j] = 0; } } } clearBricks(); } void initBricks(int l) { int bricksTemp[4][8]; if (l == 0) { for (int i = 0; i < 4; i++) { for (int j = 0; j < 8; j++) { bricks[i][j] = 1; brickDrawFlag[i][j] = 1; } } } else if (l == 1) { for (int i = 0; i < 4; i++) { for (int j = 0; j < 8; j+=2) { bricks[i][j] = 1; brickDrawFlag[i][j] = 1; } } } else if (l > 1) { for (int i = 0; i < 4; i++) { for (int j = 0; j < 8; j++) { int mint = ceil((noise.read() * 100000)); bricksTemp[i][j] = mint%100; if (bricksTemp[i][j] > ((l*57)%73)) { bricks[i][j] = 1; brickDrawFlag[i][j] = 1; } } } } } void clearBricks() { for (int i = 0; i < 8; i++) { for (int j = 0; j < 4; j++) { if (clearFlag[j][i]) { lcd.clearRect(bricksx[i],bricksy[j],7,3); clearFlag[j][i] = 0; score++; } } } } void getBrickTouch(int x, int y) { if (bricks[y][x]) { for (int a = -1; a < 8; a++) { if (lcd.getPixel(bricksx[x]+a,bricksy[y]-1)) { clearFlag[y][x] = 1; bricks[y][x] = 0; } else if (lcd.getPixel(bricksx[x]+a,bricksy[y]+3)) { clearFlag[y][x] = 1; bricks[y][x] = 0; } } for (int b = -1; b < 3; b++) { if (lcd.getPixel(bricksx[x]-1,bricksy[y]+b)) { clearFlag[y][x] = 1; bricks[y][x] = 0; } else if (lcd.getPixel(bricksx[x]+7,bricksy[y]+b)) { clearFlag[y][x] = 1; bricks[y][x] = 0; } } } } // read default positions of the joystick to calibrate later readings void calibrateJoystick() { button.mode(PullUp); // 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() { if (startStop == 1) { // 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 // 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 = RIGHT; } else if ( joystick.x < DIRECTION_TOLERANCE && fabs(joystick.y) < DIRECTION_TOLERANCE) { joystick.direction = LEFT; } else if ( joystick.x > DIRECTION_TOLERANCE && joystick.y < DIRECTION_TOLERANCE) { joystick.direction = UPRIGHT; } else if ( joystick.x > DIRECTION_TOLERANCE && joystick.y > -1*DIRECTION_TOLERANCE) { joystick.direction = DOWNRIGHT; } else if ( joystick.y < DIRECTION_TOLERANCE && joystick.x < -1*DIRECTION_TOLERANCE) { joystick.direction = UPLEFT; } else if ( joystick.x < -1*DIRECTION_TOLERANCE && joystick.y > -1*DIRECTION_TOLERANCE) { joystick.direction = DOWNLEFT; } else { joystick.direction = UNKNOWN; } } else if (startStop == 0) { joystick.direction = CENTRE; } } //function to move the game paddle left and right with the joystick void paddle() { if (!displayGame) return; lcd.clearRect(1,py,74,3); if ((joystick.direction == RIGHT || joystick.direction == UPRIGHT || joystick.direction == DOWNRIGHT) && (px < 67)) { px = px+1; lcd.drawRect(px,py,pw,ph,1); } else if ((joystick.direction == LEFT || joystick.direction == UPLEFT || joystick.direction == DOWNLEFT) && (px > 0)) { px = px-1; lcd.drawRect(px,py,pw,ph,1); } else { lcd.drawRect(px,py,pw,ph,1); } } //set the touchFlag if any of the pixels touching the ball are set //store which pixels are set in an array void getTouchFlag() { if (lcd.getPixel(bx-1,by)) {//11 touchFlag = 1; surround[11] = 1; } if (lcd.getPixel(bx-1,by-1)) {//0 touchFlag = 1; surround[0] = 1; } if (lcd.getPixel(bx,by-1)) {//1 touchFlag = 1; surround[1] = 1; } if (lcd.getPixel(bx+1,by-1)) {//2 touchFlag = 1; surround[2] = 1; } if (lcd.getPixel(bx+2,by-1)) {//3 touchFlag = 1; surround[3] = 1; } if (lcd.getPixel(bx+2,by)) {//4 touchFlag = 1; surround[4] = 1; } if (lcd.getPixel(bx+2,by+1)) {//5 touchFlag = 1; surround[5] = 1; } if (lcd.getPixel(bx+2,by+2)) {//6 touchFlag = 1; surround[6] = 1; } if (lcd.getPixel(bx+1,by+2)) {//7 touchFlag = 1; surround[7] = 1; } if (lcd.getPixel(bx,by+2)) {//8 touchFlag = 1; surround[8] = 1; } if (lcd.getPixel(bx-1,by+2)) {//9 touchFlag = 1; surround[9] = 1; } if (lcd.getPixel(bx-1,by+1)) {//10 touchFlag = 1; surround[10] = 1; } } //work out what the ball has hit and calculate/set the new angle accordingly int setAngle() { getTouchFlag(); if (touchFlag) { //FOR 3 CORNER SQUARES if (surround[11] && surround[0] && surround[1]) { //top right corner d = 6; } else if (surround[2] && surround[3] && surround[4]) { //bottom right corner d = 10; } else if (surround[5] && surround[6] && surround[7]) { //bottom left corner d = 14; } else if (surround[8] && surround[9] && surround[10]) { //top left corner d = 2; } //FOR 3 TOUCHING OFFCENTRE EDGE SQUARES else if (surround[0] && surround[1] && surround[2] && !surround[3]) { //top edge left d = 5; } else if (surround[3] && surround[1] && surround[2] && !surround[0]) { //top edge right d = 11; } else if (surround[6] && surround[7] && surround[8] && !surround[9]) { // low edge right d = 13; } else if (surround[7] && surround[8] && surround[9] && !surround[6]) { //low edge left d = 3; } else if (surround[0] && surround[11] && surround[10] && !surround[9]) { //left edge top d = 5; } else if (surround[3] && surround[4] && surround[5] && !surround[6]) { //right edge top d = 11; } else if (surround[11] && surround[10] && surround[9] && !surround[0]) { //left edge low d = 3; } else if (surround[4] && surround[5] && surround[6] && !surround[3]) { //right edge low d = 13; } //FOR CENTRE SQUARES else if (surround[1] && surround[2]) { //top edge switch (d) { case 3: d = 5; break; case 2: d = 6; break; case 1: d = 7; break; case 0: d = 8; break; case 15: d = 9; break; case 14: d = 10; break; case 13: d = 11; break; } } else if (surround[4] && surround[5]) { //RHS edge switch (d) { case 1: d = 15; break; case 2: d = 14; break; case 3: d = 13; break; case 4: d = 12; break; case 5: d = 11; break; case 6: d = 10; break; case 7: d = 9; break; } } else if (surround[10] && surround[11]) { //LHS edge switch (d) { case 9: d = 7; break; case 10: d = 6; break; case 11: d = 5; break; case 12: d = 4; break; case 13: d = 3; break; case 14: d = 2; break; case 15: d = 1; break; } } else if (surround[7] && surround[8]) { //bottom edge switch (d) { case 5: d = 3; break; case 6: d = 2; break; case 7: d = 1; break; case 8: d = 0; break; case 9: d = 15; break; case 10: d = 14; break; case 11: d = 13; break; } } //FOR 2 TOUCHING OFFCENTRE EDGE SQUARES else if (surround[0] && surround[1]) { //top edge left switch (d) { case 0: d = 7; break; case 1: d = 6; break; case 2: d = 5; break; case 3: d = 5; break; case 15: d = 8; break; case 14: d = 9; break; case 13: d = 10; break; } } else if (surround[2] && surround[3]) { //top edge right switch (d) { case 0: d = 9; break; case 1: d = 8; break; case 2: d = 7; break; case 3: d = 6; break; case 15: d = 10; break; case 14: d = 11; break; case 13: d = 11; break; } } else if (surround[9] && surround[8]) { // low edge right switch (d) { case 11: d = 14; break; case 10: d = 15; break; case 9: d = 0; break; case 8: d = 1; break; case 7: d = 2; break; case 6: d = 3; break; case 5: d = 3; break; } } else if (surround[7] && surround[6]) { //low edge left switch (d) { case 11: d = 13; break; case 10: d = 13; break; case 9: d = 14; break; case 8: d = 15; break; case 7: d = 0; break; case 6: d = 1; break; case 5: d = 2; break; } } else if (surround[0] && surround[11]) { //left edge top switch (d) { case 9: d = 8; break; case 10: d = 7; break; case 11: d = 6; break; case 13: d = 5; break; case 14: d = 3; break; case 15: d = 2; break; case 0: d = 1; break; } } else if (surround[3] && surround[4]) { //right edge top switch (d) { case 0: d = 15; break; case 1: d = 14; break; case 2: d = 13; break; case 3: d = 11; break; case 5: d = 10; break; case 6: d = 9; break; case 7: d = 8; break; } } else if (surround[10] && surround[9]) { //left edge low switch (d) { case 8: d = 7; break; case 9: d = 6; break; case 10: d = 5; break; case 11: d = 3; break; case 13: d = 2; break; case 14: d = 1; break; case 15: d = 0; break; } } else if (surround[5] && surround[6]) { //right edge low switch (d) { case 8: d = 9; break; case 1: d = 0; break; case 2: d = 15; break; case 3: d = 14; break; case 5: d = 13; break; case 6: d = 11; break; case 7: d = 10; break; } } // FOR 1 TOUCHING CORNER SQUARE else if (surround[3]) { //top right d = 10; } else if (surround[6]) { // bottom right d = 14; } else if (surround[9]) { //bottom left d = 2; } else if (surround[0]) { //top left d = 6; } touchFlag = 0; //clear the touch flag for (int i = 0; i<12; i++) { //clear the set points surround[i] = 0; } } return d; } void ball() { int e = d; setAngle(); //check what ball is touching get new angle doBricks(); //check what bricks are touching clear all necessary moveBall1(d); //move ball with new angle wait_ms(35); //wait if (d == e) { setAngle(); doBricks(); moveBall2(d); wait_ms(35); } } void moveBall1(int d) //move the ball, quantised into 16 directions of motion { lcd.clearRect(bx,by,bw+1,bh+1); if (d == 0) { //0deg (vertical up) by-=1; lcd.drawRect(bx,by,bw,bh,bf); lcd.refresh(); } else if (d == 1) { //22.5deg by-=1; bx+=1; lcd.drawRect(bx,by,bw,bh,bf); lcd.refresh(); } else if (d == 2) { //45deg by-=1; bx+=1; lcd.drawRect(bx,by,bw,bh,bf); lcd.refresh(); } else if (d == 3) { //62.5deg by-=1; bx+=1; lcd.drawRect(bx,by,bw,bh,bf); lcd.refresh(); } else if (d == 4) { //90deg (right) bx+=1; lcd.drawRect(bx,by,bw,bh,bf); lcd.refresh(); } else if (d == 5) { //112.5deg bx+=1; by+=1; lcd.drawRect(bx,by,bw,bh,bf); lcd.refresh(); } else if (d == 6) { //135deg bx+=1; by+=1; lcd.drawRect(bx,by,bw,bh,bf); lcd.refresh(); } else if (d == 7) { //157.5deg bx+=1; by+=1; lcd.drawRect(bx,by,bw,bh,bf); lcd.refresh(); } else if (d == 8) { //180deg (vertical down) by++; lcd.drawRect(bx,by,bw,bh,bf); lcd.refresh(); } else if (d == 9) { //202.5deg by++; bx-=1; lcd.drawRect(bx,by,bw,bh,bf); lcd.refresh(); } else if (d == 10) { //225deg by+=1; bx-=1; lcd.drawRect(bx,by,bw,bh,bf); lcd.refresh(); } else if (d == 11) { //247.5deg by+=1; bx-=1; lcd.drawRect(bx,by,bw,bh,bf); lcd.refresh(); } else if (d == 12) { //270deg (left) bx-=1; lcd.drawRect(bx,by,bw,bh,bf); lcd.refresh(); } else if (d == 13) { //292.5deg bx-=1; by-=1; lcd.drawRect(bx,by,bw,bh,bf); lcd.refresh(); } else if (d == 14) { //315deg bx-=1; by-=1; lcd.drawRect(bx,by,bw,bh,bf); lcd.refresh(); } else if (d == 15) { //337.5deg bx-=1; by-=1; lcd.drawRect(bx,by,bw,bh,bf); lcd.refresh(); } } void moveBall2(int d) //move the ball, quantised into 16 directions of motion { lcd.clearRect(bx,by,bw+1,bh+1); if (d == 0) { //0deg (vertical up) by-=1; lcd.drawRect(bx,by,bw,bh,bf); lcd.refresh(); } else if (d == 1) { //22.5deg by-=1; lcd.drawRect(bx,by,bw,bh,bf); lcd.refresh(); } else if (d == 2) { //45deg by-=1; bx+=1; lcd.drawRect(bx,by,bw,bh,bf); lcd.refresh(); } else if (d == 3) { //62.5deg bx+=1; lcd.drawRect(bx,by,bw,bh,bf); lcd.refresh(); } else if (d == 4) { //90deg (right) bx+=1; lcd.drawRect(bx,by,bw,bh,bf); lcd.refresh(); } else if (d == 5) { //112.5deg bx+=1; lcd.drawRect(bx,by,bw,bh,bf); lcd.refresh(); } else if (d == 6) { //135deg bx+=1; by+=1; lcd.drawRect(bx,by,bw,bh,bf); lcd.refresh(); } else if (d == 7) { //157.5deg by+=1; lcd.drawRect(bx,by,bw,bh,bf); lcd.refresh(); } else if (d == 8) { //180deg (vertical down) by++; lcd.drawRect(bx,by,bw,bh,bf); lcd.refresh(); } else if (d == 9) { //202.5deg by++; lcd.drawRect(bx,by,bw,bh,bf); lcd.refresh(); } else if (d == 10) { //225deg by+=1; bx-=1; lcd.drawRect(bx,by,bw,bh,bf); lcd.refresh(); } else if (d == 11) { //247.5deg bx-=1; lcd.drawRect(bx,by,bw,bh,bf); lcd.refresh(); } else if (d == 12) { //270deg (left) bx-=1; lcd.drawRect(bx,by,bw,bh,bf); lcd.refresh(); } else if (d == 13) { //292.5deg bx-=1; lcd.drawRect(bx,by,bw,bh,bf); lcd.refresh(); } else if (d == 14) { //315deg bx-=1; by-=1; lcd.drawRect(bx,by,bw,bh,bf); lcd.refresh(); } else if (d == 15) { //337.5deg by-=1; lcd.drawRect(bx,by,bw,bh,bf); lcd.refresh(); } } //set pixels around the edge of the board void borderInit() { if (!displayGame) return; for (int i =0; i<=75; i++) { lcd.setPixel(i,0); } for (int i = 0; i<=48; i++) { lcd.setPixel(0,i); lcd.setPixel(75,i); lcd.setPixel(83,i); } for (int i =75; i<84; i++) { lcd.setPixel(i,31); } borderFlag = 1; }