a flappy bird game demo of the RA8875 display library.
I came across some code for a flappy bird game at www.HowToMechatronics.com. It might entertain little kids for a while, so I did a quick port from arduino to mbed and for the RA8875 display library.
main.cpp@2:e6813d4a983f, 2017-06-13 (annotated)
- Committer:
- WiredHome
- Date:
- Tue Jun 13 23:53:13 2017 +0000
- Revision:
- 2:e6813d4a983f
- Parent:
- 1:e9c260ba5d73
- Child:
- 5:f1fe5ccc4d5b
Improved drawing of bird so it doesn't leave feathers behind.
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
WiredHome | 0:2023707186fe | 1 | /* Arduino Game Proejct |
WiredHome | 0:2023707186fe | 2 | * Program made by Dejan Nedelkovski, |
WiredHome | 0:2023707186fe | 3 | * www.HowToMechatronics.com |
WiredHome | 0:2023707186fe | 4 | * |
WiredHome | 0:2023707186fe | 5 | * Adapted to the RA8875 and mbed by David Smart |
WiredHome | 0:2023707186fe | 6 | * |
WiredHome | 1:e9c260ba5d73 | 7 | * Possible Improvements: |
WiredHome | 1:e9c260ba5d73 | 8 | * - create an in-ram image of the bird(s) and blit them. |
WiredHome | 1:e9c260ba5d73 | 9 | * - use 2-layers and transparency. Put the bird and pillar in front of the sky |
WiredHome | 1:e9c260ba5d73 | 10 | * - use block-move for the bird and the sky |
WiredHome | 1:e9c260ba5d73 | 11 | * - tune the easy/hard configuration values a little more. |
WiredHome | 0:2023707186fe | 12 | */ |
WiredHome | 0:2023707186fe | 13 | |
WiredHome | 0:2023707186fe | 14 | #include "mbed.h" // Last tested: v122 |
WiredHome | 0:2023707186fe | 15 | #include "RA8875.h" // Last tested: v125 |
WiredHome | 0:2023707186fe | 16 | |
WiredHome | 0:2023707186fe | 17 | // Define this for 800x480 panel, undefine for 480x272 |
WiredHome | 0:2023707186fe | 18 | #define BIG_SCREEN |
WiredHome | 0:2023707186fe | 19 | |
WiredHome | 0:2023707186fe | 20 | // Define this for Cap touch panel, undefine for resistive |
WiredHome | 0:2023707186fe | 21 | #define CAP_TOUCH |
WiredHome | 0:2023707186fe | 22 | |
WiredHome | 0:2023707186fe | 23 | #ifdef CAP_TOUCH |
WiredHome | 0:2023707186fe | 24 | RA8875 myGLCD(p5, p6, p7, p12, NC, p9,p10,p13, "tft"); // SPI:{MOSI,MISO,SCK,/ChipSelect,/reset}, I2C:{SDA,SCL,/IRQ}, name |
WiredHome | 0:2023707186fe | 25 | #else |
WiredHome | 0:2023707186fe | 26 | RA8875 myGLCD(p5, p6, p7, p12, NC, "tft"); // SPI:{MOSI,MISO,SCK,/ChipSelect,/reset}, name |
WiredHome | 0:2023707186fe | 27 | #endif |
WiredHome | 0:2023707186fe | 28 | |
WiredHome | 0:2023707186fe | 29 | #define PC_BAUD 460800 // I like the serial communications to be very fast |
WiredHome | 0:2023707186fe | 30 | |
WiredHome | 0:2023707186fe | 31 | // // // // // // // // // // // // // // // // // // // // // // // // |
WiredHome | 0:2023707186fe | 32 | // End of Configuration Section |
WiredHome | 0:2023707186fe | 33 | // // // // // // // // // // // // // // // // // // // // // // // // |
WiredHome | 0:2023707186fe | 34 | |
WiredHome | 0:2023707186fe | 35 | LocalFileSystem local("local"); // access to calibration file for resistive touch. |
WiredHome | 0:2023707186fe | 36 | Serial pc(USBTX, USBRX); // Not required for display |
WiredHome | 0:2023707186fe | 37 | |
WiredHome | 0:2023707186fe | 38 | #ifdef BIG_SCREEN |
WiredHome | 0:2023707186fe | 39 | #define LCD_W 800 |
WiredHome | 0:2023707186fe | 40 | #define LCD_H 480 |
WiredHome | 0:2023707186fe | 41 | #define LCD_C 8 // color - bits per pixel |
WiredHome | 0:2023707186fe | 42 | #define DEF_RADIUS 50 // default radius of the fingerprint |
WiredHome | 0:2023707186fe | 43 | #define BL_NORM 25 // Backlight Normal setting (0 to 255) |
WiredHome | 0:2023707186fe | 44 | #else |
WiredHome | 0:2023707186fe | 45 | #define LCD_W 480 |
WiredHome | 0:2023707186fe | 46 | #define LCD_H 272 |
WiredHome | 0:2023707186fe | 47 | #define LCD_C 8 // color - bits per pixel |
WiredHome | 0:2023707186fe | 48 | #define DEF_RADIUS 20 // default radius of the fingerprint |
WiredHome | 0:2023707186fe | 49 | #define BL_NORM 25 // Backlight Normal setting (0 to 255) |
WiredHome | 0:2023707186fe | 50 | #endif |
WiredHome | 0:2023707186fe | 51 | |
WiredHome | 0:2023707186fe | 52 | |
WiredHome | 0:2023707186fe | 53 | // +----------------------------------------------------------------+------+--------+ |
WiredHome | 0:2023707186fe | 54 | // | | | | |
WiredHome | 0:2023707186fe | 55 | // | | | | |
WiredHome | 0:2023707186fe | 56 | // | (x,y) |Pillar| | |
WiredHome | 0:2023707186fe | 57 | // | +------+ +-----------------------+ +------+ | |
WiredHome | 0:2023707186fe | 58 | // | | Bird h | Tap To Start Easy | (x,y) ^ | |
WiredHome | 0:2023707186fe | 59 | // | +---w--+ +-----------------------+ window | |
WiredHome | 0:2023707186fe | 60 | // | h | |
WiredHome | 0:2023707186fe | 61 | // | +-----------------------+ v | |
WiredHome | 0:2023707186fe | 62 | // | | Tap To Start Hard | +---w--+ | |
WiredHome | 0:2023707186fe | 63 | // | +-----------------------+ | | | |
WiredHome | 0:2023707186fe | 64 | // | | | | |
WiredHome | 0:2023707186fe | 65 | // | | | | |
WiredHome | 0:2023707186fe | 66 | // | | | | |
WiredHome | 0:2023707186fe | 67 | // | | | | |
WiredHome | 0:2023707186fe | 68 | // | | | | |
WiredHome | 0:2023707186fe | 69 | // | | | | |
WiredHome | 0:2023707186fe | 70 | // +----------------------------------------------------------------+------+--------+ Ground |
WiredHome | 0:2023707186fe | 71 | // | From HowToMechatronics.com Adapted by Smartware Computing | |
WiredHome | 0:2023707186fe | 72 | // +--------------------------------------------------------------------------------+ ScoreZone |
WiredHome | 0:2023707186fe | 73 | // | S C O R E : # # # Highest Score: ##### [Reset] | |
WiredHome | 0:2023707186fe | 74 | // | Highest Score: ##### | |
WiredHome | 0:2023707186fe | 75 | // +--------------------------------------------------------------------------------+ |
WiredHome | 0:2023707186fe | 76 | // + |
WiredHome | 0:2023707186fe | 77 | // INFO_X |
WiredHome | 0:2023707186fe | 78 | #define INFO_X (300) |
WiredHome | 0:2023707186fe | 79 | #define GROUND_Y (LCD_H - 60) |
WiredHome | 0:2023707186fe | 80 | #define SCOREZONE_Y (LCD_H - 40) |
WiredHome | 0:2023707186fe | 81 | |
WiredHome | 0:2023707186fe | 82 | #define BIRD_W 35 |
WiredHome | 0:2023707186fe | 83 | #define BIRD_H 30 |
WiredHome | 0:2023707186fe | 84 | #define BIRD_X 50 |
WiredHome | 0:2023707186fe | 85 | #define BIRD_Y 50 |
WiredHome | 0:2023707186fe | 86 | |
WiredHome | 0:2023707186fe | 87 | #define TAP_EASY_Y (GROUND_Y/2 - 64) |
WiredHome | 0:2023707186fe | 88 | #define TAP_EASY_MSG "TAP TO START EASY GAME" // 22 chars |
WiredHome | 0:2023707186fe | 89 | #define TAP_HARD_Y (GROUND_Y/2 - 0) |
WiredHome | 0:2023707186fe | 90 | #define TAP_HARD_MSG "TAP TO START HARD GAME" // 22 chars |
WiredHome | 0:2023707186fe | 91 | #define TAP_LEN 22 // 22 chars |
WiredHome | 0:2023707186fe | 92 | #define TAP_W 16*TAP_LEN |
WiredHome | 0:2023707186fe | 93 | #define TAP_H 32 |
WiredHome | 0:2023707186fe | 94 | #define TAP_X (LCD_W/2 - 16*TAP_LEN/2) // text centered on screen |
WiredHome | 0:2023707186fe | 95 | |
WiredHome | 0:2023707186fe | 96 | #define RESET_X (LCD_W - 2 - 160) |
WiredHome | 0:2023707186fe | 97 | #define RESET_Y SCOREZONE_Y |
WiredHome | 0:2023707186fe | 98 | #define RESET_W (160) |
WiredHome | 0:2023707186fe | 99 | #define RESET_H (LCD_H - 1 - SCOREZONE_Y) |
WiredHome | 0:2023707186fe | 100 | |
WiredHome | 0:2023707186fe | 101 | #define PILLAR_W 50 |
WiredHome | 0:2023707186fe | 102 | #define WINDOW_H_EASY 120 |
WiredHome | 0:2023707186fe | 103 | #define WINDOW_H_HARD 80 |
WiredHome | 0:2023707186fe | 104 | |
WiredHome | 0:2023707186fe | 105 | #define COLOR_SKY RGB(114, 198, 206) |
WiredHome | 0:2023707186fe | 106 | #define COLOR_GROUND RGB(64,248,48) |
WiredHome | 0:2023707186fe | 107 | #define COLOR_SCOREZONE RGB(221, 216, 148) |
WiredHome | 0:2023707186fe | 108 | #define COLOR_PILLAR RGB(0, 200, 20) |
WiredHome | 0:2023707186fe | 109 | |
WiredHome | 0:2023707186fe | 110 | const rect_t r_easy = { |
WiredHome | 0:2023707186fe | 111 | TAP_X,TAP_EASY_Y, TAP_X+TAP_W, TAP_EASY_Y+TAP_H |
WiredHome | 0:2023707186fe | 112 | }; |
WiredHome | 0:2023707186fe | 113 | const rect_t r_hard = { |
WiredHome | 0:2023707186fe | 114 | TAP_X,TAP_HARD_Y, TAP_X+TAP_W, TAP_HARD_Y+TAP_H |
WiredHome | 0:2023707186fe | 115 | }; |
WiredHome | 0:2023707186fe | 116 | |
WiredHome | 0:2023707186fe | 117 | |
WiredHome | 0:2023707186fe | 118 | const rect_t r_Reset = { |
WiredHome | 0:2023707186fe | 119 | RESET_X,RESET_Y, RESET_X+RESET_W,RESET_Y+RESET_H |
WiredHome | 0:2023707186fe | 120 | }; |
WiredHome | 0:2023707186fe | 121 | const rect_t r_Ground = { |
WiredHome | 0:2023707186fe | 122 | 1,GROUND_Y, LCD_W-4,SCOREZONE_Y-1 |
WiredHome | 0:2023707186fe | 123 | }; |
WiredHome | 0:2023707186fe | 124 | const rect_t r_Score = { |
WiredHome | 0:2023707186fe | 125 | 1,SCOREZONE_Y, LCD_W-4,LCD_H-3 |
WiredHome | 0:2023707186fe | 126 | }; |
WiredHome | 0:2023707186fe | 127 | const rect_t r_PlayField = { |
WiredHome | 0:2023707186fe | 128 | 0,0, LCD_W-1, GROUND_Y-1 |
WiredHome | 0:2023707186fe | 129 | }; |
WiredHome | 0:2023707186fe | 130 | |
WiredHome | 0:2023707186fe | 131 | rect_t r_Bird = { |
WiredHome | 0:2023707186fe | 132 | BIRD_X,BIRD_Y, BIRD_X+BIRD_W,BIRD_Y+BIRD_H |
WiredHome | 0:2023707186fe | 133 | }; |
WiredHome | 0:2023707186fe | 134 | rect_t r_PillarUp = { |
WiredHome | 0:2023707186fe | 135 | 0,0, 0+PILLAR_W,GROUND_Y/4 |
WiredHome | 0:2023707186fe | 136 | }; |
WiredHome | 0:2023707186fe | 137 | rect_t r_PillarDn = { |
WiredHome | 0:2023707186fe | 138 | 0,GROUND_Y/4, 0+PILLAR_W,GROUND_Y-1 |
WiredHome | 0:2023707186fe | 139 | }; |
WiredHome | 0:2023707186fe | 140 | |
WiredHome | 0:2023707186fe | 141 | int movingRate = 3; |
WiredHome | 0:2023707186fe | 142 | int fallRateInt = 0; |
WiredHome | 0:2023707186fe | 143 | float fallRate = 0; |
WiredHome | 0:2023707186fe | 144 | int score = 0; |
WiredHome | 0:2023707186fe | 145 | int lastSpeedUpScore = 0; |
WiredHome | 0:2023707186fe | 146 | #define SPEED_UP_EASY 5 |
WiredHome | 0:2023707186fe | 147 | #define SPEED_UP_HARD 2 |
WiredHome | 0:2023707186fe | 148 | int speed_up_threshold = SPEED_UP_EASY; |
WiredHome | 0:2023707186fe | 149 | int highestScore; |
WiredHome | 0:2023707186fe | 150 | bool screenPressed = false; |
WiredHome | 0:2023707186fe | 151 | bool gameStarted = false; |
WiredHome | 0:2023707186fe | 152 | |
WiredHome | 0:2023707186fe | 153 | Timer timer; |
WiredHome | 0:2023707186fe | 154 | int lastPillarTime; |
WiredHome | 0:2023707186fe | 155 | int pillarStepTime = 30; // 50 mSec time between pillar motion to start. |
WiredHome | 0:2023707186fe | 156 | int lastBirdTime; |
WiredHome | 0:2023707186fe | 157 | int birdStepTime = 60; |
WiredHome | 0:2023707186fe | 158 | |
WiredHome | 0:2023707186fe | 159 | int window_h = WINDOW_H_EASY; |
WiredHome | 0:2023707186fe | 160 | |
WiredHome | 0:2023707186fe | 161 | void initiateGame(); |
WiredHome | 0:2023707186fe | 162 | void SetPillarX(int x); |
WiredHome | 0:2023707186fe | 163 | void SetWindowY(int y); |
WiredHome | 0:2023707186fe | 164 | void SetBirdY(int y); |
WiredHome | 0:2023707186fe | 165 | void DrawPillars(); |
WiredHome | 0:2023707186fe | 166 | void DrawBird(); |
WiredHome | 0:2023707186fe | 167 | void gameOver(); |
WiredHome | 0:2023707186fe | 168 | |
WiredHome | 0:2023707186fe | 169 | void setup() { |
WiredHome | 0:2023707186fe | 170 | myGLCD.cls(); |
WiredHome | 0:2023707186fe | 171 | timer.start(); |
WiredHome | 0:2023707186fe | 172 | highestScore = 0; //EEPROM.read(0); // Read the highest score from the EEPROM |
WiredHome | 0:2023707186fe | 173 | initiateGame(); // Initiate the game |
WiredHome | 0:2023707186fe | 174 | } |
WiredHome | 0:2023707186fe | 175 | |
WiredHome | 0:2023707186fe | 176 | void loop() { |
WiredHome | 0:2023707186fe | 177 | int nowTime = timer.read_ms(); |
WiredHome | 0:2023707186fe | 178 | |
WiredHome | 0:2023707186fe | 179 | if ((nowTime - lastPillarTime) > pillarStepTime) { |
WiredHome | 0:2023707186fe | 180 | lastPillarTime = nowTime; |
WiredHome | 0:2023707186fe | 181 | SetPillarX(r_PillarUp.p1.x - movingRate); |
WiredHome | 0:2023707186fe | 182 | DrawPillars(); // Draws the pillars |
WiredHome | 0:2023707186fe | 183 | } |
WiredHome | 0:2023707186fe | 184 | |
WiredHome | 0:2023707186fe | 185 | if ((nowTime - lastBirdTime) > birdStepTime) { |
WiredHome | 0:2023707186fe | 186 | lastBirdTime = nowTime; |
WiredHome | 0:2023707186fe | 187 | SetBirdY(r_Bird.p1.y + fallRateInt); |
WiredHome | 0:2023707186fe | 188 | DrawBird(); // Draws the bird |
WiredHome | 0:2023707186fe | 189 | fallRate = fallRate+0.4; // Each inetration the fall rate increase so that we can the effect of acceleration/ gravity |
WiredHome | 0:2023707186fe | 190 | fallRateInt = int(fallRate); |
WiredHome | 0:2023707186fe | 191 | } |
WiredHome | 0:2023707186fe | 192 | // Checks for collision |
WiredHome | 0:2023707186fe | 193 | if (r_Bird.p2.y >= (GROUND_Y - 1 ) || r_Bird.p1.y <= 0) { // top and bottom |
WiredHome | 0:2023707186fe | 194 | gameOver(); |
WiredHome | 0:2023707186fe | 195 | } |
WiredHome | 0:2023707186fe | 196 | if (myGLCD.Intersect(r_Bird, r_PillarUp) |
WiredHome | 0:2023707186fe | 197 | || myGLCD.Intersect(r_Bird, r_PillarDn)) { |
WiredHome | 0:2023707186fe | 198 | gameOver(); |
WiredHome | 0:2023707186fe | 199 | } |
WiredHome | 0:2023707186fe | 200 | |
WiredHome | 0:2023707186fe | 201 | // After the pillar has passed through the screen |
WiredHome | 0:2023707186fe | 202 | if (r_PillarUp.p2.x <= 0) { |
WiredHome | 0:2023707186fe | 203 | SetPillarX(LCD_W - 2); |
WiredHome | 0:2023707186fe | 204 | SetWindowY(rand() % (GROUND_Y - window_h)); // Random number for the pillars height |
WiredHome | 0:2023707186fe | 205 | score++; // Increase score by one |
WiredHome | 0:2023707186fe | 206 | } |
WiredHome | 0:2023707186fe | 207 | //==== Controlling the bird |
WiredHome | 0:2023707186fe | 208 | point_t p; |
WiredHome | 0:2023707186fe | 209 | if (myGLCD.TouchPanelReadable(&p) && !screenPressed) { |
WiredHome | 0:2023707186fe | 210 | fallRate=-6; // Setting the fallRate negative will make the bird jump |
WiredHome | 0:2023707186fe | 211 | screenPressed = true; |
WiredHome | 0:2023707186fe | 212 | } |
WiredHome | 0:2023707186fe | 213 | // Doesn't allow holding the screen / you must tap it |
WiredHome | 0:2023707186fe | 214 | else if ( !myGLCD.TouchPanelReadable() && screenPressed) { |
WiredHome | 0:2023707186fe | 215 | screenPressed = false; |
WiredHome | 0:2023707186fe | 216 | } |
WiredHome | 0:2023707186fe | 217 | // After each few points, increases the moving rate of the pillars |
WiredHome | 0:2023707186fe | 218 | if ((score - lastSpeedUpScore) == speed_up_threshold) { |
WiredHome | 0:2023707186fe | 219 | lastSpeedUpScore = score; |
WiredHome | 0:2023707186fe | 220 | movingRate++; |
WiredHome | 0:2023707186fe | 221 | } |
WiredHome | 0:2023707186fe | 222 | } |
WiredHome | 0:2023707186fe | 223 | |
WiredHome | 0:2023707186fe | 224 | |
WiredHome | 0:2023707186fe | 225 | void DrawScore(void) { |
WiredHome | 0:2023707186fe | 226 | myGLCD.foreground(Black); |
WiredHome | 0:2023707186fe | 227 | myGLCD.background(COLOR_SCOREZONE); |
WiredHome | 0:2023707186fe | 228 | myGLCD.SetTextFontSize(2); |
WiredHome | 0:2023707186fe | 229 | myGLCD.SetTextCursor(5,SCOREZONE_Y); |
WiredHome | 0:2023707186fe | 230 | myGLCD.printf("Score: %5d", score); |
WiredHome | 0:2023707186fe | 231 | } |
WiredHome | 0:2023707186fe | 232 | |
WiredHome | 0:2023707186fe | 233 | void DrawHighScore(void) { |
WiredHome | 0:2023707186fe | 234 | myGLCD.SetTextFontSize(2); |
WiredHome | 0:2023707186fe | 235 | myGLCD.SetTextCursor(INFO_X,SCOREZONE_Y); |
WiredHome | 0:2023707186fe | 236 | myGLCD.printf("Highest: %5d", highestScore); |
WiredHome | 0:2023707186fe | 237 | } |
WiredHome | 0:2023707186fe | 238 | |
WiredHome | 0:2023707186fe | 239 | void ShowReset(bool showit) { |
WiredHome | 0:2023707186fe | 240 | myGLCD.background(COLOR_SCOREZONE); |
WiredHome | 0:2023707186fe | 241 | myGLCD.rect(r_Reset, COLOR_SCOREZONE); |
WiredHome | 0:2023707186fe | 242 | if (showit) { |
WiredHome | 0:2023707186fe | 243 | myGLCD.foreground(Black); |
WiredHome | 0:2023707186fe | 244 | myGLCD.SetTextCursor(RESET_X,RESET_Y); |
WiredHome | 0:2023707186fe | 245 | myGLCD.SetTextFontSize(2); |
WiredHome | 0:2023707186fe | 246 | myGLCD.printf(">RESET<"); |
WiredHome | 0:2023707186fe | 247 | } |
WiredHome | 0:2023707186fe | 248 | } |
WiredHome | 0:2023707186fe | 249 | |
WiredHome | 0:2023707186fe | 250 | // ===== initiateGame - Custom Function |
WiredHome | 0:2023707186fe | 251 | void initiateGame() { |
WiredHome | 0:2023707186fe | 252 | SetPillarX(LCD_W - PILLAR_W - 30); |
WiredHome | 0:2023707186fe | 253 | SetWindowY(rand() % (GROUND_Y - window_h)); |
WiredHome | 0:2023707186fe | 254 | SetBirdY(BIRD_Y); |
WiredHome | 0:2023707186fe | 255 | fallRate = 0; |
WiredHome | 0:2023707186fe | 256 | score = 0; |
WiredHome | 0:2023707186fe | 257 | lastSpeedUpScore = 0; |
WiredHome | 0:2023707186fe | 258 | movingRate = 3; |
WiredHome | 0:2023707186fe | 259 | |
WiredHome | 0:2023707186fe | 260 | // Blue sky |
WiredHome | 0:2023707186fe | 261 | myGLCD.foreground(White); |
WiredHome | 0:2023707186fe | 262 | myGLCD.background(COLOR_SKY); |
WiredHome | 0:2023707186fe | 263 | myGLCD.cls(); |
WiredHome | 0:2023707186fe | 264 | |
WiredHome | 0:2023707186fe | 265 | // Ground |
WiredHome | 0:2023707186fe | 266 | myGLCD.fillrect(r_Ground, COLOR_GROUND); |
WiredHome | 0:2023707186fe | 267 | myGLCD.foreground(Black); |
WiredHome | 0:2023707186fe | 268 | myGLCD.background(COLOR_GROUND); |
WiredHome | 0:2023707186fe | 269 | myGLCD.SetTextFontSize(1); |
WiredHome | 0:2023707186fe | 270 | myGLCD.SetTextCursor(5,GROUND_Y); |
WiredHome | 0:2023707186fe | 271 | myGLCD.printf("From www.HowToMechatronics.com"); |
WiredHome | 0:2023707186fe | 272 | myGLCD.SetTextCursor(INFO_X,GROUND_Y); |
WiredHome | 0:2023707186fe | 273 | myGLCD.printf("Adapted for RA8875 and mbed by Smartware Computing"); |
WiredHome | 0:2023707186fe | 274 | |
WiredHome | 0:2023707186fe | 275 | // ScoreZone |
WiredHome | 0:2023707186fe | 276 | myGLCD.fillrect(r_Score, COLOR_SCOREZONE); |
WiredHome | 0:2023707186fe | 277 | DrawScore(); |
WiredHome | 0:2023707186fe | 278 | DrawHighScore(); |
WiredHome | 0:2023707186fe | 279 | ShowReset(true); |
WiredHome | 0:2023707186fe | 280 | |
WiredHome | 0:2023707186fe | 281 | // Start buttons |
WiredHome | 0:2023707186fe | 282 | myGLCD.SetTextCursor(r_easy.p1); |
WiredHome | 0:2023707186fe | 283 | myGLCD.SetTextFontSize(2); |
WiredHome | 0:2023707186fe | 284 | myGLCD.foreground(Black); |
WiredHome | 0:2023707186fe | 285 | myGLCD.printf(TAP_EASY_MSG); |
WiredHome | 0:2023707186fe | 286 | myGLCD.rect(r_easy, BrightRed); |
WiredHome | 0:2023707186fe | 287 | |
WiredHome | 0:2023707186fe | 288 | myGLCD.SetTextCursor(r_hard.p1); |
WiredHome | 0:2023707186fe | 289 | myGLCD.SetTextFontSize(2); |
WiredHome | 0:2023707186fe | 290 | myGLCD.foreground(Black); |
WiredHome | 0:2023707186fe | 291 | myGLCD.printf(TAP_HARD_MSG); |
WiredHome | 0:2023707186fe | 292 | myGLCD.rect(r_hard, BrightRed); |
WiredHome | 0:2023707186fe | 293 | |
WiredHome | 0:2023707186fe | 294 | wait(0.5); |
WiredHome | 0:2023707186fe | 295 | DrawBird(); // Draws the bird |
WiredHome | 0:2023707186fe | 296 | DrawPillars(); |
WiredHome | 0:2023707186fe | 297 | |
WiredHome | 0:2023707186fe | 298 | // Wait until we tap the sreen |
WiredHome | 0:2023707186fe | 299 | while (!gameStarted) { |
WiredHome | 0:2023707186fe | 300 | point_t p; |
WiredHome | 0:2023707186fe | 301 | if (myGLCD.TouchPanelReadable(&p)) { |
WiredHome | 0:2023707186fe | 302 | if (myGLCD.Intersect(r_Reset, p)) { |
WiredHome | 0:2023707186fe | 303 | highestScore = 0; |
WiredHome | 0:2023707186fe | 304 | myGLCD.fillrect(r_Reset, COLOR_SCOREZONE); |
WiredHome | 0:2023707186fe | 305 | DrawHighScore(); |
WiredHome | 0:2023707186fe | 306 | } |
WiredHome | 0:2023707186fe | 307 | if (myGLCD.Intersect(r_easy,p)) { |
WiredHome | 0:2023707186fe | 308 | movingRate = 3; |
WiredHome | 0:2023707186fe | 309 | window_h = WINDOW_H_EASY; |
WiredHome | 0:2023707186fe | 310 | speed_up_threshold = SPEED_UP_EASY; |
WiredHome | 0:2023707186fe | 311 | gameStarted = true; |
WiredHome | 0:2023707186fe | 312 | } |
WiredHome | 0:2023707186fe | 313 | if (myGLCD.Intersect(r_hard,p)) { |
WiredHome | 0:2023707186fe | 314 | movingRate = 8; |
WiredHome | 0:2023707186fe | 315 | window_h = WINDOW_H_HARD; |
WiredHome | 0:2023707186fe | 316 | speed_up_threshold = SPEED_UP_HARD; |
WiredHome | 0:2023707186fe | 317 | gameStarted = true; |
WiredHome | 0:2023707186fe | 318 | } |
WiredHome | 0:2023707186fe | 319 | } |
WiredHome | 0:2023707186fe | 320 | } |
WiredHome | 0:2023707186fe | 321 | ShowReset(false); |
WiredHome | 0:2023707186fe | 322 | myGLCD.fillrect(r_easy, COLOR_SKY); |
WiredHome | 0:2023707186fe | 323 | myGLCD.fillrect(r_hard, COLOR_SKY); |
WiredHome | 0:2023707186fe | 324 | wait(0.5); |
WiredHome | 0:2023707186fe | 325 | lastBirdTime = lastPillarTime = timer.read_ms(); |
WiredHome | 0:2023707186fe | 326 | } |
WiredHome | 0:2023707186fe | 327 | |
WiredHome | 0:2023707186fe | 328 | |
WiredHome | 0:2023707186fe | 329 | // ===== DrawPillars - Custom Function |
WiredHome | 0:2023707186fe | 330 | // (x,y) is the bottom left of the top pillar |
WiredHome | 0:2023707186fe | 331 | // |
WiredHome | 0:2023707186fe | 332 | // Set the left side of the pillar |
WiredHome | 0:2023707186fe | 333 | void SetPillarX(int x) { |
WiredHome | 0:2023707186fe | 334 | r_PillarUp.p1.x = r_PillarDn.p1.x = x; |
WiredHome | 0:2023707186fe | 335 | r_PillarUp.p2.x = r_PillarDn.p2.x = x + PILLAR_W; |
WiredHome | 0:2023707186fe | 336 | } |
WiredHome | 0:2023707186fe | 337 | |
WiredHome | 0:2023707186fe | 338 | void SetWindowY(int y) { |
WiredHome | 0:2023707186fe | 339 | r_PillarUp.p2.y = y; |
WiredHome | 0:2023707186fe | 340 | r_PillarDn.p1.y = y + window_h; |
WiredHome | 0:2023707186fe | 341 | } |
WiredHome | 0:2023707186fe | 342 | |
WiredHome | 0:2023707186fe | 343 | void DrawPillars() { |
WiredHome | 0:2023707186fe | 344 | rect_t r; |
WiredHome | 0:2023707186fe | 345 | |
WiredHome | 0:2023707186fe | 346 | for (int i=0; i<2; i++) { |
WiredHome | 0:2023707186fe | 347 | r = (i == 0) ? r_PillarUp : r_PillarDn; |
WiredHome | 0:2023707186fe | 348 | |
WiredHome | 0:2023707186fe | 349 | myGLCD.Intersect(&r, &r_PlayField); // Create a new rect that fits on the screen |
WiredHome | 0:2023707186fe | 350 | myGLCD.fillrect(r, COLOR_PILLAR); |
WiredHome | 0:2023707186fe | 351 | myGLCD.rect(r, Black); |
WiredHome | 0:2023707186fe | 352 | r.p1.x = r.p2.x + 1; // Sky-fill to the right of the pillar |
WiredHome | 0:2023707186fe | 353 | r.p2.x += movingRate; |
WiredHome | 0:2023707186fe | 354 | if (myGLCD.Intersect(&r, &r_PlayField)) { |
WiredHome | 0:2023707186fe | 355 | myGLCD.fillrect(r, COLOR_SKY); |
WiredHome | 0:2023707186fe | 356 | } |
WiredHome | 0:2023707186fe | 357 | } |
WiredHome | 0:2023707186fe | 358 | DrawScore(); |
WiredHome | 0:2023707186fe | 359 | } |
WiredHome | 0:2023707186fe | 360 | |
WiredHome | 0:2023707186fe | 361 | void SetBirdY(int y) { |
WiredHome | 0:2023707186fe | 362 | r_Bird.p1.y = y; |
WiredHome | 0:2023707186fe | 363 | if (r_Bird.p1.y + BIRD_H >= GROUND_Y) |
WiredHome | 0:2023707186fe | 364 | r_Bird.p1.y = GROUND_Y - BIRD_H - 1; |
WiredHome | 0:2023707186fe | 365 | r_Bird.p2.y = y + BIRD_H; |
WiredHome | 0:2023707186fe | 366 | } |
WiredHome | 0:2023707186fe | 367 | |
WiredHome | 0:2023707186fe | 368 | void DrawBird() { |
WiredHome | 0:2023707186fe | 369 | #if 1 |
WiredHome | 0:2023707186fe | 370 | point_t p; |
WiredHome | 2:e6813d4a983f | 371 | rect_t r; |
WiredHome | 2:e6813d4a983f | 372 | |
WiredHome | 2:e6813d4a983f | 373 | r = r_Bird; |
WiredHome | 2:e6813d4a983f | 374 | // Clear space above or below |
WiredHome | 2:e6813d4a983f | 375 | if (fallRateInt > 0) { // Falling |
WiredHome | 2:e6813d4a983f | 376 | r.p1.y -= fallRateInt; |
WiredHome | 2:e6813d4a983f | 377 | if (r.p1.y < 0) |
WiredHome | 2:e6813d4a983f | 378 | r.p1.y = 0; |
WiredHome | 2:e6813d4a983f | 379 | } else if (fallRateInt < 0) { // Rising |
WiredHome | 2:e6813d4a983f | 380 | r.p2.y += -fallRateInt; |
WiredHome | 2:e6813d4a983f | 381 | if (r.p2.y >= GROUND_Y) |
WiredHome | 2:e6813d4a983f | 382 | r.p2.y = GROUND_Y - 1; |
WiredHome | 2:e6813d4a983f | 383 | } |
WiredHome | 2:e6813d4a983f | 384 | myGLCD.fillrect(r, COLOR_SKY); // erase old bird |
WiredHome | 2:e6813d4a983f | 385 | |
WiredHome | 0:2023707186fe | 386 | // center body |
WiredHome | 0:2023707186fe | 387 | p.x = r_Bird.p1.x + BIRD_W/2; |
WiredHome | 0:2023707186fe | 388 | p.y = r_Bird.p1.y + BIRD_H/2; |
WiredHome | 0:2023707186fe | 389 | myGLCD.fillcircle(p, 7*BIRD_H/16, (color_t)(RGB(255,255,0))); |
WiredHome | 0:2023707186fe | 390 | |
WiredHome | 0:2023707186fe | 391 | p.x = r_Bird.p1.x + 3*BIRD_W/4; |
WiredHome | 0:2023707186fe | 392 | p.y = r_Bird.p1.y + 1*BIRD_H/4; |
WiredHome | 0:2023707186fe | 393 | myGLCD.fillcircle(p, BIRD_H/5, White); |
WiredHome | 0:2023707186fe | 394 | myGLCD.circle(p, BIRD_H/5, Black); |
WiredHome | 0:2023707186fe | 395 | myGLCD.fillcircle(p, BIRD_H/8, Black); |
WiredHome | 0:2023707186fe | 396 | // Beak |
WiredHome | 0:2023707186fe | 397 | r.p1.x = r_Bird.p1.x + 9*BIRD_W/16; |
WiredHome | 0:2023707186fe | 398 | r.p1.y = r_Bird.p1.y + BIRD_H/2; |
WiredHome | 0:2023707186fe | 399 | r.p2.x = r_Bird.p1.x + BIRD_W; |
WiredHome | 0:2023707186fe | 400 | r.p2.y = r.p1.y + BIRD_H/5; |
WiredHome | 0:2023707186fe | 401 | myGLCD.fillroundrect(r, 3, 3, BrightRed); |
WiredHome | 0:2023707186fe | 402 | myGLCD.roundrect(r, 3, 3, Black); |
WiredHome | 0:2023707186fe | 403 | // Wing up/down |
WiredHome | 0:2023707186fe | 404 | if (fallRate > 0) { |
WiredHome | 0:2023707186fe | 405 | r.p1.y -= BIRD_H/6; |
WiredHome | 0:2023707186fe | 406 | r.p2.y = r.p1.y + BIRD_H/5; |
WiredHome | 0:2023707186fe | 407 | } else if (fallRate < 0) { |
WiredHome | 0:2023707186fe | 408 | r.p1.y += BIRD_H/6; |
WiredHome | 0:2023707186fe | 409 | r.p2.y = r.p1.y + BIRD_H/5; |
WiredHome | 0:2023707186fe | 410 | } |
WiredHome | 0:2023707186fe | 411 | r.p1.x = r_Bird.p1.x; |
WiredHome | 0:2023707186fe | 412 | r.p2.x = r.p1.x + 3*BIRD_W/8; |
WiredHome | 0:2023707186fe | 413 | myGLCD.fillroundrect(r, 3, 3, White); |
WiredHome | 0:2023707186fe | 414 | myGLCD.roundrect(r, 3, 3, Black); |
WiredHome | 0:2023707186fe | 415 | #else |
WiredHome | 0:2023707186fe | 416 | //printf("DrawBird(%d)\r\n", y); |
WiredHome | 0:2023707186fe | 417 | RetCode_t r = myGLCD.RenderImageFile(BIRD_X, y, "/local/BIRD_01.jpg"); // 35x30 |
WiredHome | 0:2023707186fe | 418 | myGLCD.fillrect(BIRD_X,y,BIRD_X+BIRD_W,y-fallRateInt, COLOR_SKY); // Draws blue rectangles above and below the bird |
WiredHome | 0:2023707186fe | 419 | myGLCD.fillrect(BIRD_X,y+BIRD_H,BIRD_X+BIRD_W,y+BIRD_H+fallRateInt, COLOR_SKY); // in order to clear its previous state |
WiredHome | 0:2023707186fe | 420 | #endif |
WiredHome | 0:2023707186fe | 421 | } |
WiredHome | 0:2023707186fe | 422 | |
WiredHome | 0:2023707186fe | 423 | //======== gameOver() - Custom Function |
WiredHome | 0:2023707186fe | 424 | void gameOver() { |
WiredHome | 0:2023707186fe | 425 | wait(3.000); |
WiredHome | 0:2023707186fe | 426 | // Clears the screen and prints the text |
WiredHome | 0:2023707186fe | 427 | //myGLCD.cls(); |
WiredHome | 0:2023707186fe | 428 | myGLCD.foreground(RGB(255, 255, 255)); |
WiredHome | 0:2023707186fe | 429 | myGLCD.background(RGB(0, 0, 0)); |
WiredHome | 0:2023707186fe | 430 | myGLCD.SetTextFontSize(2); |
WiredHome | 0:2023707186fe | 431 | myGLCD.SetTextCursor(INFO_X, 40); |
WiredHome | 0:2023707186fe | 432 | myGLCD.printf("GAME OVER"); |
WiredHome | 0:2023707186fe | 433 | DrawScore(); |
WiredHome | 0:2023707186fe | 434 | myGLCD.SetTextCursor(INFO_X,120); |
WiredHome | 0:2023707186fe | 435 | myGLCD.printf("Restarting..."); |
WiredHome | 0:2023707186fe | 436 | myGLCD.SetTextFontSize(2); |
WiredHome | 0:2023707186fe | 437 | for (int i=5; i>0; i--) { |
WiredHome | 0:2023707186fe | 438 | myGLCD.SetTextCursor(INFO_X,150); |
WiredHome | 0:2023707186fe | 439 | myGLCD.printf("%d", i); |
WiredHome | 0:2023707186fe | 440 | wait(1.000); |
WiredHome | 0:2023707186fe | 441 | } |
WiredHome | 0:2023707186fe | 442 | |
WiredHome | 0:2023707186fe | 443 | // Writes the highest score in the EEPROM |
WiredHome | 0:2023707186fe | 444 | if (score > highestScore) { |
WiredHome | 0:2023707186fe | 445 | highestScore = score; |
WiredHome | 0:2023707186fe | 446 | //EEPROM.write(0,highestScore); |
WiredHome | 0:2023707186fe | 447 | } |
WiredHome | 0:2023707186fe | 448 | // Resets the variables to start position values |
WiredHome | 0:2023707186fe | 449 | gameStarted = false; |
WiredHome | 0:2023707186fe | 450 | initiateGame(); |
WiredHome | 0:2023707186fe | 451 | } |
WiredHome | 0:2023707186fe | 452 | |
WiredHome | 0:2023707186fe | 453 | |
WiredHome | 0:2023707186fe | 454 | int main(void) |
WiredHome | 0:2023707186fe | 455 | { |
WiredHome | 0:2023707186fe | 456 | pc.baud(PC_BAUD); //I like a snappy terminal, so crank it up! |
WiredHome | 0:2023707186fe | 457 | pc.printf("\r\nFlappy Bird - Build " __DATE__ " " __TIME__ "\r\n"); |
WiredHome | 0:2023707186fe | 458 | myGLCD.init((LCD_W-2),LCD_H,LCD_C); |
WiredHome | 0:2023707186fe | 459 | myGLCD.TouchPanelInit(); |
WiredHome | 0:2023707186fe | 460 | myGLCD.Backlight_u8(BL_NORM); |
WiredHome | 0:2023707186fe | 461 | setup(); |
WiredHome | 0:2023707186fe | 462 | |
WiredHome | 0:2023707186fe | 463 | while(1) { |
WiredHome | 0:2023707186fe | 464 | loop(); |
WiredHome | 0:2023707186fe | 465 | } |
WiredHome | 0:2023707186fe | 466 | } |