Erts

Dependencies:   BSP_DISCO_F413ZH

Committer:
ajdincatic
Date:
Sun Feb 06 10:16:50 2022 +0100
Revision:
0:a3870e86460b
init

Who changed what in which revision?

UserRevisionLine numberNew contents of line
ajdincatic 0:a3870e86460b 1 #include "mbed.h"
ajdincatic 0:a3870e86460b 2 #include "stm32f413h_discovery_lcd.h"
ajdincatic 0:a3870e86460b 3
ajdincatic 0:a3870e86460b 4 #define SCREEN_REFRESH_PERIOD 0.15
ajdincatic 0:a3870e86460b 5 #define START_SNAKE_LENGTH 4
ajdincatic 0:a3870e86460b 6 #define GAME_BG (uint16_t)0x010200
ajdincatic 0:a3870e86460b 7
ajdincatic 0:a3870e86460b 8 enum Mode{
ajdincatic 0:a3870e86460b 9 MAIN_MENU,
ajdincatic 0:a3870e86460b 10 GAME,
ajdincatic 0:a3870e86460b 11 END_GAME
ajdincatic 0:a3870e86460b 12 };
ajdincatic 0:a3870e86460b 13
ajdincatic 0:a3870e86460b 14 enum Dirrection {
ajdincatic 0:a3870e86460b 15 LEFT, UP, RIGHT, DOWN
ajdincatic 0:a3870e86460b 16 };
ajdincatic 0:a3870e86460b 17
ajdincatic 0:a3870e86460b 18 // simulator
ajdincatic 0:a3870e86460b 19 // InterruptIn bLeft(p5);
ajdincatic 0:a3870e86460b 20 // InterruptIn bUp(p6);
ajdincatic 0:a3870e86460b 21 // InterruptIn bRight(p7);
ajdincatic 0:a3870e86460b 22 // InterruptIn bDown(p8);
ajdincatic 0:a3870e86460b 23 // PwmOut speaker(p21);
ajdincatic 0:a3870e86460b 24 // PwmOut led(p9);
ajdincatic 0:a3870e86460b 25 // DigitalIn toggglePause(p10);
ajdincatic 0:a3870e86460b 26 // real device
ajdincatic 0:a3870e86460b 27 InterruptIn bLeft(PA_1);
ajdincatic 0:a3870e86460b 28 InterruptIn bUp(PA_2);
ajdincatic 0:a3870e86460b 29 InterruptIn bRight(PA_3);
ajdincatic 0:a3870e86460b 30 InterruptIn bDown(PA_4);
ajdincatic 0:a3870e86460b 31 PwmOut speaker(PA_5);
ajdincatic 0:a3870e86460b 32 PwmOut led(PA_6);
ajdincatic 0:a3870e86460b 33 DigitalIn toggglePause(PA_7);
ajdincatic 0:a3870e86460b 34
ajdincatic 0:a3870e86460b 35 Timeout alertTimeout;
ajdincatic 0:a3870e86460b 36 Ticker gameTicker;
ajdincatic 0:a3870e86460b 37 Ticker mainTicker;
ajdincatic 0:a3870e86460b 38
ajdincatic 0:a3870e86460b 39 Mode mode = MAIN_MENU;
ajdincatic 0:a3870e86460b 40 Dirrection direction = UP;
ajdincatic 0:a3870e86460b 41
ajdincatic 0:a3870e86460b 42 #define MAX_X 34
ajdincatic 0:a3870e86460b 43 #define MAX_Y 34
ajdincatic 0:a3870e86460b 44
ajdincatic 0:a3870e86460b 45 int X[MAX_X*MAX_Y] = {5, 5, 5, 5};
ajdincatic 0:a3870e86460b 46 int Y[MAX_X*MAX_Y] = {30, 29, 28, 27};
ajdincatic 0:a3870e86460b 47
ajdincatic 0:a3870e86460b 48 int targetX, targetY;
ajdincatic 0:a3870e86460b 49
ajdincatic 0:a3870e86460b 50 int snakeLength = START_SNAKE_LENGTH;
ajdincatic 0:a3870e86460b 51 int score = 0;
ajdincatic 0:a3870e86460b 52
ajdincatic 0:a3870e86460b 53 bool isEndGame = true;
ajdincatic 0:a3870e86460b 54
ajdincatic 0:a3870e86460b 55 void drawSquare(int x, int y){
ajdincatic 0:a3870e86460b 56 BSP_LCD_FillRect(x*231/MAX_X+1, y*231/MAX_Y+1, 5, 5);
ajdincatic 0:a3870e86460b 57 }
ajdincatic 0:a3870e86460b 58
ajdincatic 0:a3870e86460b 59 void drawTarget(int x, int y){
ajdincatic 0:a3870e86460b 60 BSP_LCD_FillRect(x*231/MAX_X+1, y*231/MAX_Y+1, 5, 5);
ajdincatic 0:a3870e86460b 61 }
ajdincatic 0:a3870e86460b 62
ajdincatic 0:a3870e86460b 63 void turnOffToneAndLed(void) {
ajdincatic 0:a3870e86460b 64 led = 0;
ajdincatic 0:a3870e86460b 65 speaker = 0;
ajdincatic 0:a3870e86460b 66 }
ajdincatic 0:a3870e86460b 67
ajdincatic 0:a3870e86460b 68 void playToneAndLed(float frequency, float volume) {
ajdincatic 0:a3870e86460b 69 led = 1.0;
ajdincatic 0:a3870e86460b 70 speaker.period(1.0 / frequency);
ajdincatic 0:a3870e86460b 71 speaker = volume;
ajdincatic 0:a3870e86460b 72 }
ajdincatic 0:a3870e86460b 73
ajdincatic 0:a3870e86460b 74 void turnOnForTime(float time) {
ajdincatic 0:a3870e86460b 75 playToneAndLed(400.0, 0.5);
ajdincatic 0:a3870e86460b 76 alertTimeout.attach(&turnOffToneAndLed,time);
ajdincatic 0:a3870e86460b 77 }
ajdincatic 0:a3870e86460b 78
ajdincatic 0:a3870e86460b 79 void initGame(){
ajdincatic 0:a3870e86460b 80 direction = UP;
ajdincatic 0:a3870e86460b 81 snakeLength = START_SNAKE_LENGTH;
ajdincatic 0:a3870e86460b 82 score = 0;
ajdincatic 0:a3870e86460b 83 mode = GAME;
ajdincatic 0:a3870e86460b 84 }
ajdincatic 0:a3870e86460b 85
ajdincatic 0:a3870e86460b 86 void initMainMenuScreen(){
ajdincatic 0:a3870e86460b 87 snakeLength = START_SNAKE_LENGTH;
ajdincatic 0:a3870e86460b 88 score = 0;
ajdincatic 0:a3870e86460b 89
ajdincatic 0:a3870e86460b 90 BSP_LCD_Clear(GAME_BG);
ajdincatic 0:a3870e86460b 91 BSP_LCD_SetBackColor (GAME_BG);
ajdincatic 0:a3870e86460b 92 BSP_LCD_SetTextColor(LCD_COLOR_GRAY);
ajdincatic 0:a3870e86460b 93
ajdincatic 0:a3870e86460b 94 BSP_LCD_SetTextColor (LCD_COLOR_YELLOW);
ajdincatic 0:a3870e86460b 95 BSP_LCD_SetFont(&Font20);
ajdincatic 0:a3870e86460b 96 BSP_LCD_DisplayStringAt(0, 40, (uint8_t*)"SNAKE GAME", CENTER_MODE);
ajdincatic 0:a3870e86460b 97 BSP_LCD_SetFont(&Font16);
ajdincatic 0:a3870e86460b 98 BSP_LCD_DisplayStringAt(0, 80, (uint8_t*)"Start game", CENTER_MODE);
ajdincatic 0:a3870e86460b 99 BSP_LCD_DisplayStringAt(0, 100, (uint8_t*)"Press any key", CENTER_MODE);
ajdincatic 0:a3870e86460b 100
ajdincatic 0:a3870e86460b 101 BSP_LCD_SetTextColor(LCD_COLOR_GRAY);
ajdincatic 0:a3870e86460b 102 BSP_LCD_FillRect (130, 155, 5, 5);
ajdincatic 0:a3870e86460b 103
ajdincatic 0:a3870e86460b 104 BSP_LCD_SetTextColor(LCD_COLOR_GRAY);
ajdincatic 0:a3870e86460b 105 BSP_LCD_FillRect (112, 155, 5, 5);
ajdincatic 0:a3870e86460b 106 BSP_LCD_SetTextColor(LCD_COLOR_YELLOW);
ajdincatic 0:a3870e86460b 107 BSP_LCD_FillRect (100, 155, 5, 5);
ajdincatic 0:a3870e86460b 108 BSP_LCD_FillRect (106, 155, 5, 5);
ajdincatic 0:a3870e86460b 109 BSP_LCD_FillRect (100, 162, 5, 5);
ajdincatic 0:a3870e86460b 110 BSP_LCD_FillRect (100, 169, 5, 5);
ajdincatic 0:a3870e86460b 111 BSP_LCD_FillRect (100, 176, 5, 5);
ajdincatic 0:a3870e86460b 112 BSP_LCD_FillRect (94, 176, 5, 5);
ajdincatic 0:a3870e86460b 113 BSP_LCD_FillRect (88, 176, 5, 5);
ajdincatic 0:a3870e86460b 114 BSP_LCD_FillRect (82, 176, 5, 5);
ajdincatic 0:a3870e86460b 115 BSP_LCD_FillRect (76, 176, 5, 5);
ajdincatic 0:a3870e86460b 116 BSP_LCD_FillRect (70, 176, 5, 5);
ajdincatic 0:a3870e86460b 117 BSP_LCD_FillRect (64, 176, 5, 5);
ajdincatic 0:a3870e86460b 118 BSP_LCD_FillRect (58, 176, 5, 5);
ajdincatic 0:a3870e86460b 119 BSP_LCD_FillRect (52, 176, 5, 5);
ajdincatic 0:a3870e86460b 120 BSP_LCD_FillRect (52, 183, 5, 5);
ajdincatic 0:a3870e86460b 121 BSP_LCD_FillRect (52, 190, 5, 5);
ajdincatic 0:a3870e86460b 122 }
ajdincatic 0:a3870e86460b 123
ajdincatic 0:a3870e86460b 124 void initGameScreen(){
ajdincatic 0:a3870e86460b 125 BSP_LCD_Clear(GAME_BG);
ajdincatic 0:a3870e86460b 126 BSP_LCD_SetBackColor(GAME_BG);
ajdincatic 0:a3870e86460b 127 BSP_LCD_SetTextColor(LCD_COLOR_GRAY);
ajdincatic 0:a3870e86460b 128 BSP_LCD_SetFont(&Font8);
ajdincatic 0:a3870e86460b 129
ajdincatic 0:a3870e86460b 130 BSP_LCD_SetTextColor(LCD_COLOR_YELLOW);
ajdincatic 0:a3870e86460b 131
ajdincatic 0:a3870e86460b 132 for(int i = 0; i < snakeLength - 1; i++)
ajdincatic 0:a3870e86460b 133 drawSquare(X[i], Y[i]);
ajdincatic 0:a3870e86460b 134
ajdincatic 0:a3870e86460b 135 char buffer[64];
ajdincatic 0:a3870e86460b 136 sprintf(buffer, "Score: %d", score);
ajdincatic 0:a3870e86460b 137 BSP_LCD_DisplayStringAt(10, 10, (uint8_t*)buffer, LEFT_MODE);
ajdincatic 0:a3870e86460b 138
ajdincatic 0:a3870e86460b 139 BSP_LCD_SetTextColor(LCD_COLOR_GRAY);
ajdincatic 0:a3870e86460b 140 drawSquare(X[snakeLength - 1], Y[snakeLength - 1]);
ajdincatic 0:a3870e86460b 141
ajdincatic 0:a3870e86460b 142 drawTarget(targetX, targetY);
ajdincatic 0:a3870e86460b 143 }
ajdincatic 0:a3870e86460b 144
ajdincatic 0:a3870e86460b 145
ajdincatic 0:a3870e86460b 146 void initEndGameScreen(){
ajdincatic 0:a3870e86460b 147 BSP_LCD_Clear(GAME_BG);
ajdincatic 0:a3870e86460b 148 BSP_LCD_SetBackColor (GAME_BG);
ajdincatic 0:a3870e86460b 149 BSP_LCD_SetTextColor(LCD_COLOR_GRAY);
ajdincatic 0:a3870e86460b 150
ajdincatic 0:a3870e86460b 151 BSP_LCD_SetFont(&Font24);
ajdincatic 0:a3870e86460b 152 BSP_LCD_SetTextColor(LCD_COLOR_RED);
ajdincatic 0:a3870e86460b 153 BSP_LCD_DisplayStringAt(0, 20, (uint8_t*)"GAME OVER", CENTER_MODE);
ajdincatic 0:a3870e86460b 154
ajdincatic 0:a3870e86460b 155 BSP_LCD_SetFont(&Font16);
ajdincatic 0:a3870e86460b 156 BSP_LCD_SetTextColor(LCD_COLOR_YELLOW);
ajdincatic 0:a3870e86460b 157 char buffer[64];
ajdincatic 0:a3870e86460b 158 sprintf(buffer, "Score: %d", score);
ajdincatic 0:a3870e86460b 159 BSP_LCD_DisplayStringAt(0, 80, (uint8_t*)buffer, CENTER_MODE);
ajdincatic 0:a3870e86460b 160
ajdincatic 0:a3870e86460b 161 BSP_LCD_SetFont(&Font16);
ajdincatic 0:a3870e86460b 162 BSP_LCD_SetTextColor(LCD_COLOR_YELLOW);
ajdincatic 0:a3870e86460b 163 BSP_LCD_DisplayStringAt(120, 215, (uint8_t*)"Play again",LEFT_MODE);
ajdincatic 0:a3870e86460b 164 BSP_LCD_DisplayStringAt(8, 215, (uint8_t*)"Home", LEFT_MODE);
ajdincatic 0:a3870e86460b 165 }
ajdincatic 0:a3870e86460b 166
ajdincatic 0:a3870e86460b 167 void initScreen(){
ajdincatic 0:a3870e86460b 168 switch (mode) {
ajdincatic 0:a3870e86460b 169 case MAIN_MENU:
ajdincatic 0:a3870e86460b 170 initMainMenuScreen();
ajdincatic 0:a3870e86460b 171 break;
ajdincatic 0:a3870e86460b 172 case GAME:
ajdincatic 0:a3870e86460b 173 initGameScreen();
ajdincatic 0:a3870e86460b 174 break;
ajdincatic 0:a3870e86460b 175 case END_GAME:
ajdincatic 0:a3870e86460b 176 initEndGameScreen();
ajdincatic 0:a3870e86460b 177 break;
ajdincatic 0:a3870e86460b 178 }
ajdincatic 0:a3870e86460b 179 }
ajdincatic 0:a3870e86460b 180
ajdincatic 0:a3870e86460b 181 void initTarget(){
ajdincatic 0:a3870e86460b 182 bool isSet = true;
ajdincatic 0:a3870e86460b 183 do{
ajdincatic 0:a3870e86460b 184 isSet = true;
ajdincatic 0:a3870e86460b 185 srand (time(NULL));
ajdincatic 0:a3870e86460b 186 targetX = (rand() % (MAX_X - 2)) + 1;
ajdincatic 0:a3870e86460b 187 targetY = (rand() % (MAX_Y - 2)) + 1;
ajdincatic 0:a3870e86460b 188
ajdincatic 0:a3870e86460b 189 for(int i = 0; i < snakeLength; i++)
ajdincatic 0:a3870e86460b 190 if(X[i] == targetX && Y[i] == targetY)
ajdincatic 0:a3870e86460b 191 isSet = false;
ajdincatic 0:a3870e86460b 192 }while(!isSet);
ajdincatic 0:a3870e86460b 193 }
ajdincatic 0:a3870e86460b 194
ajdincatic 0:a3870e86460b 195 void initPause(){
ajdincatic 0:a3870e86460b 196 BSP_LCD_SetTextColor (LCD_COLOR_YELLOW);
ajdincatic 0:a3870e86460b 197 BSP_LCD_SetFont(&Font16);
ajdincatic 0:a3870e86460b 198 BSP_LCD_DisplayStringAt(0, 100, (uint8_t*)"Game paused", CENTER_MODE);
ajdincatic 0:a3870e86460b 199 }
ajdincatic 0:a3870e86460b 200
ajdincatic 0:a3870e86460b 201 void gameTick(){
ajdincatic 0:a3870e86460b 202 if(!toggglePause){
ajdincatic 0:a3870e86460b 203 if(mode != GAME) return;
ajdincatic 0:a3870e86460b 204
ajdincatic 0:a3870e86460b 205 int headX = X[snakeLength - 1];
ajdincatic 0:a3870e86460b 206 int headY = Y[snakeLength - 1];
ajdincatic 0:a3870e86460b 207
ajdincatic 0:a3870e86460b 208 switch(direction){
ajdincatic 0:a3870e86460b 209 case UP:
ajdincatic 0:a3870e86460b 210 Y[snakeLength - 1] = Y[snakeLength - 1] - 1;
ajdincatic 0:a3870e86460b 211 if(Y[snakeLength - 1] == 0)
ajdincatic 0:a3870e86460b 212 Y[snakeLength - 1] = MAX_Y - 1;
ajdincatic 0:a3870e86460b 213 break;
ajdincatic 0:a3870e86460b 214 case DOWN:
ajdincatic 0:a3870e86460b 215 Y[snakeLength - 1] = (Y[snakeLength - 1] + 1) % MAX_Y;
ajdincatic 0:a3870e86460b 216 if(Y[snakeLength - 1] == 0) Y[snakeLength - 1] = 1;
ajdincatic 0:a3870e86460b 217 break;
ajdincatic 0:a3870e86460b 218 case LEFT:
ajdincatic 0:a3870e86460b 219 X[snakeLength - 1] = X[snakeLength - 1] - 1;
ajdincatic 0:a3870e86460b 220 if(X[snakeLength - 1] == 0)
ajdincatic 0:a3870e86460b 221 X[snakeLength - 1] = MAX_X - 1;
ajdincatic 0:a3870e86460b 222 break;
ajdincatic 0:a3870e86460b 223 case RIGHT:
ajdincatic 0:a3870e86460b 224 X[snakeLength - 1] = (X[snakeLength - 1] + 1) % MAX_X;
ajdincatic 0:a3870e86460b 225 if(X[snakeLength - 1] == 0) X[snakeLength - 1] = 1;
ajdincatic 0:a3870e86460b 226 break;
ajdincatic 0:a3870e86460b 227 }
ajdincatic 0:a3870e86460b 228
ajdincatic 0:a3870e86460b 229 if(X[snakeLength - 1] == targetX && Y[snakeLength - 1] == targetY){
ajdincatic 0:a3870e86460b 230 turnOnForTime(0.5);
ajdincatic 0:a3870e86460b 231 score++;
ajdincatic 0:a3870e86460b 232 snakeLength++;
ajdincatic 0:a3870e86460b 233 X[snakeLength - 1] = X[snakeLength - 2];
ajdincatic 0:a3870e86460b 234 Y[snakeLength - 1] = Y[snakeLength - 2];
ajdincatic 0:a3870e86460b 235 initTarget();
ajdincatic 0:a3870e86460b 236 }else
ajdincatic 0:a3870e86460b 237 for(int i = 0; i < snakeLength - 2; i++){
ajdincatic 0:a3870e86460b 238 X[i] = X[i+1];
ajdincatic 0:a3870e86460b 239 Y[i] = Y[i+1];
ajdincatic 0:a3870e86460b 240 }
ajdincatic 0:a3870e86460b 241 X[snakeLength - 2] = headX;
ajdincatic 0:a3870e86460b 242 Y[snakeLength - 2] = headY;
ajdincatic 0:a3870e86460b 243
ajdincatic 0:a3870e86460b 244 for(int i = 0; i < snakeLength; i++){
ajdincatic 0:a3870e86460b 245 if(X[snakeLength - 1] == X[i] && Y[snakeLength - 1] == Y[i] && i != snakeLength - 1){
ajdincatic 0:a3870e86460b 246 isEndGame = false;
ajdincatic 0:a3870e86460b 247 mode = END_GAME;
ajdincatic 0:a3870e86460b 248 break;
ajdincatic 0:a3870e86460b 249 }
ajdincatic 0:a3870e86460b 250 }
ajdincatic 0:a3870e86460b 251 }
ajdincatic 0:a3870e86460b 252 else{
ajdincatic 0:a3870e86460b 253 if(mode != GAME) return;
ajdincatic 0:a3870e86460b 254 initPause();
ajdincatic 0:a3870e86460b 255 }
ajdincatic 0:a3870e86460b 256 }
ajdincatic 0:a3870e86460b 257
ajdincatic 0:a3870e86460b 258 void controller(Dirrection newDirection){
ajdincatic 0:a3870e86460b 259 switch (mode) {
ajdincatic 0:a3870e86460b 260 case MAIN_MENU:
ajdincatic 0:a3870e86460b 261 mode = GAME;
ajdincatic 0:a3870e86460b 262 break;
ajdincatic 0:a3870e86460b 263 case GAME:
ajdincatic 0:a3870e86460b 264 if(abs(direction - newDirection) != 2)
ajdincatic 0:a3870e86460b 265 direction = newDirection;
ajdincatic 0:a3870e86460b 266 break;
ajdincatic 0:a3870e86460b 267 case END_GAME:
ajdincatic 0:a3870e86460b 268 if(newDirection == LEFT)
ajdincatic 0:a3870e86460b 269 mode = MAIN_MENU;
ajdincatic 0:a3870e86460b 270 else if(newDirection == RIGHT)
ajdincatic 0:a3870e86460b 271 initGame();
ajdincatic 0:a3870e86460b 272 break;
ajdincatic 0:a3870e86460b 273 }
ajdincatic 0:a3870e86460b 274 }
ajdincatic 0:a3870e86460b 275
ajdincatic 0:a3870e86460b 276 void clickLeft(){
ajdincatic 0:a3870e86460b 277 controller(LEFT);
ajdincatic 0:a3870e86460b 278 }
ajdincatic 0:a3870e86460b 279
ajdincatic 0:a3870e86460b 280 void clickUp(){
ajdincatic 0:a3870e86460b 281 controller(UP);
ajdincatic 0:a3870e86460b 282 }
ajdincatic 0:a3870e86460b 283
ajdincatic 0:a3870e86460b 284 void clickRight(){
ajdincatic 0:a3870e86460b 285 controller(RIGHT);
ajdincatic 0:a3870e86460b 286 }
ajdincatic 0:a3870e86460b 287
ajdincatic 0:a3870e86460b 288 void clickDown(){
ajdincatic 0:a3870e86460b 289 controller(DOWN);
ajdincatic 0:a3870e86460b 290 }
ajdincatic 0:a3870e86460b 291
ajdincatic 0:a3870e86460b 292 int main() {
ajdincatic 0:a3870e86460b 293 BSP_LCD_Init();
ajdincatic 0:a3870e86460b 294
ajdincatic 0:a3870e86460b 295 bLeft.rise(&clickLeft);
ajdincatic 0:a3870e86460b 296 bUp.rise(&clickUp);
ajdincatic 0:a3870e86460b 297 bRight.rise(&clickRight);
ajdincatic 0:a3870e86460b 298 bDown.rise(&clickDown);
ajdincatic 0:a3870e86460b 299 gameTicker.attach(&gameTick, SCREEN_REFRESH_PERIOD);
ajdincatic 0:a3870e86460b 300 mainTicker.attach(&initScreen, SCREEN_REFRESH_PERIOD);
ajdincatic 0:a3870e86460b 301
ajdincatic 0:a3870e86460b 302 initTarget();
ajdincatic 0:a3870e86460b 303 }
ajdincatic 0:a3870e86460b 304