An implementation of "BrickBreaker" for the mbed platform using the uLCD-4DGL display and a 5-Way joystick
Dependencies: 4DGL-uLCD-SE SDFileSystem mbed-rtos mbed wave_player
main.cpp
- Committer:
- nini1294
- Date:
- 2016-10-31
- Revision:
- 1:b20b76acf0ed
- Parent:
- 0:c9df12bcc92d
File content as of revision 1:b20b76acf0ed:
#include "mbed.h" #include "uLCD_4DGL.h" #include "Nav_Switch.h" #include "rtos.h" #include "SDFileSystem.h" #include "wave_player.h" #define BALL_RADIUS 2 #define MOVE_AMT 5 #define BLOCK_HEIGHT 12 #define BLOCK_WIDTH 16 #define PADDLE_COLOR 0xFF0000 #define EXPLOSION_RED 0xFF0000 #define EXPLOSION_YELLOW 0xFFFF00 Nav_Switch myNav( p9, p6, p7, p5, p8); //pin order on Sparkfun breakout uLCD_4DGL uLCD(p28,p27,p22); SDFileSystem sd(p11, p12, p13, p21, "sd"); //SD card AnalogOut DACout(p18); wave_player waver(&DACout); struct Paddle { int x1, x2, y1, y2; }; struct Ball { float x, y, xvel, yvel; }; struct Block { int x1, y1, x2, y2; bool active; int color; }; struct Explosion { int x, y; bool active; int tick; }; Paddle p1; Ball b1; struct Block blocks[24]; struct Explosion explosions[5]; int gameover = 0; bool redrawExplosions = true; bool sound = false; int old_bx, old_by; int old_x1, old_x2; int blocksBroken; Ticker speedTimeout; int speedIncreases; Mutex splosions; void brickBreak(int, int); void drawBlocks(); void playPaddle() { printf("Paddle1\n"); FILE *wave_file; wave_file=fopen("/sd/mydir/paddle.wav","r"); waver.play(wave_file); fclose(wave_file); } void playWall() { FILE *wave_file; wave_file=fopen("/sd/mydir/wall.wav","r"); waver.play(wave_file); fclose(wave_file); } void playExplosion() { printf("Boom\n"); FILE *wave_file; bool check; while (1) { splosions.lock(); check = sound; splosions.unlock(); if (check) { printf("Explosion1\n"); wave_file=fopen("/sd/mydir/explosion.wav","r"); waver.play(wave_file); fclose(wave_file); Thread::wait(250); printf("Explosion2\n"); } Thread::wait(250); } } void playGO() { printf("GO\n"); FILE *wave_file; wave_file=fopen("/sd/mydir/go.wav","r"); waver.play(wave_file); fclose(wave_file); } void createExplosion(int x, int y) { for (int i = 0; i < 5; i++) { if (!explosions[i].active) { explosions[i].active = true; explosions[i].x = x; explosions[i].y = y; explosions[i].tick = 0; redrawExplosions = true; Thread t2(playExplosion); return; } } } void drawExplosions() { redrawExplosions = false; for (int i = 0; i < 5; i++) { if (explosions[i].active) { redrawExplosions = true; splosions.lock(); sound = true; splosions.unlock(); if (explosions[i].tick > 5) { uLCD.filled_circle(explosions[i].x, explosions[i].y, explosions[i].tick + 5, EXPLOSION_RED); } uLCD.filled_circle(explosions[i].x, explosions[i].y, explosions[i].tick, EXPLOSION_YELLOW); explosions[i].tick++; if (explosions[i].tick > 10) { uLCD.filled_circle(explosions[i].x, explosions[i].y, explosions[i].tick + 8, BLACK); explosions[i].tick = 0; explosions[i].active = false; drawBlocks(); splosions.lock(); sound = false; splosions.unlock(); } } } } void movePaddle(int amt) { if (p1.x1 + amt <= 0) { p1.x1 = 0; p1.x2 = 13; } else { p1.x1 = p1.x1 + amt; p1.x2 = p1.x2 + amt; } if (p1.x2 + amt > 127) { p1.x1 = 114; p1.x2 = 127; } else { p1.x1 = p1.x1 + amt; p1.x2 = p1.x2 + amt; } } void drawPaddle() { uLCD.filled_rectangle(old_x1, p1.y1, old_x2, p1.y2, BLACK); uLCD.filled_rectangle(p1.x1, p1.y1, p1.x2, p1.y2, PADDLE_COLOR); old_x1 = p1.x1; old_x2 = p1.x2; } void moveBall() { int newx = b1.x + b1.xvel; int newy = b1.y - b1.yvel; // printf("x: %d xvel: %d y: %d yvel: %d\n",newx, b1.xvel, newy, b1.yvel); if (newx < 2 || newx > 125) { b1.xvel = - b1.xvel; } if (newy <= 2) { b1.yvel = -b1.yvel; } if (newy > 122) { if (newx >= p1.x1 && newx < p1.x2) { b1.yvel = - b1.yvel; } else { gameover = -1; } } brickBreak(newx, newy); b1.x = b1.x + b1.xvel; b1.y = b1.y - b1.yvel; } void decrementIncreases() { if (speedIncreases > 0) { speedIncreases--; } } void incSpeed() { if (speedIncreases < 4) { b1.xvel += b1.xvel * 1.1; b1.yvel += b1.yvel * 1.1; } printf("x:%f y:%f", b1.xvel, b1.yvel); } void checkWin() { if (blocksBroken == 24) { gameover = 1; } } void brickBreak(int nx, int ny) { for (int i = 0; i < 24; i++) { if (blocks[i].active) { if (nx > blocks[i].x1 && nx < blocks[i].x2) { if (ny < blocks[i].y2) { blocks[i].active = false; b1.yvel = -b1.yvel; uLCD.filled_rectangle(blocks[i].x1, blocks[i].y1, blocks[i].x2, blocks[i].y2, BLACK); createExplosion(nx, ny); blocksBroken++; checkWin(); } } } } } void drawBall() { uLCD.filled_circle(old_bx, old_by, BALL_RADIUS, BLACK); uLCD.filled_circle(b1.x, b1.y, BALL_RADIUS, WHITE); old_bx = b1.x; old_by = b1.y; } void initBlocks() { for (int i = 0; i < 8; i++) { for (int j = 0; j < 3; j++) { // printf("%d\n", j * 8 + i); blocks[j * 8 + i].x1 = i * BLOCK_WIDTH; blocks[j * 8 + i].y1 = j * BLOCK_HEIGHT; blocks[j * 8 + i].x2 = i * BLOCK_WIDTH + BLOCK_WIDTH; blocks[j * 8 + i].y2 = j * BLOCK_HEIGHT + BLOCK_HEIGHT; blocks[j * 8 + i].active = true; blocks[j * 8 + i].color = (i + j) % 2 == 0 ? GREEN : BLUE; } } } void drawBlocks() { for (int i = 0; i < 24 ; i++) { Block tmp = blocks[i]; if (tmp.active) { // printf("%d %d %d %d\n", tmp.x1, tmp.y1, tmp.x2, tmp.y2); uLCD.filled_rectangle(tmp.x1, tmp.y1, tmp.x2, tmp.y2, tmp.color); } } } void startGame() { p1.x1 = 56; p1.x2 = 70; p1.y1 = 124; p1.y2 = 127; b1.x = 63; b1.y = 121; b1.xvel = 0; b1.yvel = 0; blocksBroken = 0; speedIncreases = 0; splosions.lock(); sound = false; splosions.unlock(); drawPaddle(); drawBall(); initBlocks(); drawBlocks(); while(gameover == 0) { myNav.read(); if(myNav.right()) { movePaddle(MOVE_AMT); drawPaddle(); if (b1.xvel == 0 && b1.yvel == 0) { b1.x = (p1.x1 + p1.x2) / 2; drawBall(); } // printf("%d\n", p1.x1); } if (myNav.left()) { movePaddle(-MOVE_AMT); drawPaddle(); if (b1.xvel == 0 || b1.yvel == 0) { b1.x = (p1.x1 + p1.x2) / 2; drawBall(); } // printf("%d\n", p1.x1); } if (myNav.fire()) { b1.xvel = 1 + rand() % 7 - 4; b1.yvel = 1 + rand() % 3; } if (myNav.down()) { gameover = 1; } if (myNav.up()) { incSpeed(); } moveBall(); if (b1.xvel != 0 || b1.yvel != 0) { drawBall(); } if (redrawExplosions) { drawExplosions(); } wait(0.1); } } int main() { uLCD.baudrate(3000000); Thread t2(playExplosion); Thread t1(playPaddle); speedTimeout.attach(&decrementIncreases, 5.0); while(1) { startGame(); printf("Over\n"); if (gameover == -1) { uLCD.text_string("GAME OVER", 5, 8, 1, RED); } else if (gameover == 1) { uLCD.text_string("YOU WIN!", 5, 8, 1, RED); } playGO(); wait(2); uLCD.cls(); printf("Out\n"); gameover = 0; } }