Kaif Kutchwala 201267448 ELEC2645 Project

Dependencies:   mbed

Committer:
KaifK
Date:
Mon May 25 13:19:11 2020 +0000
Revision:
24:c110f92fe266
Parent:
23:ad9ac069e751
Child:
25:467d8fd0fec4
fixed first level always level 1 bug

Who changed what in which revision?

UserRevisionLine numberNew contents of line
KaifK 4:08a0ff6668df 1 #include "Game.h"
KaifK 21:d5b1160f349f 2 SDFileSystem sd(PTE3, PTE1, PTE2, PTE4, "sd");
KaifK 20:c697902b844f 3 Ticker ticker;
KaifK 20:c697902b844f 4
KaifK 21:d5b1160f349f 5 FILE *fp;
KaifK 20:c697902b844f 6 volatile int sound_timer_flag = 0;
KaifK 20:c697902b844f 7 volatile int sound_sample = 0;
KaifK 21:d5b1160f349f 8 volatile int level_flag = 1; //initially set
KaifK 20:c697902b844f 9
KaifK 20:c697902b844f 10 void timer_isr();
KaifK 8:5ede90f99a27 11
KaifK 9:e6566d09f087 12 Game::Game(N5110 &lcd, Gamepad &pad, Ball &ball) {
KaifK 9:e6566d09f087 13 _lcd = &lcd;
KaifK 9:e6566d09f087 14 _pad = &pad;
KaifK 9:e6566d09f087 15 _ball = &ball;
KaifK 9:e6566d09f087 16 }
KaifK 4:08a0ff6668df 17 Game::~Game() {}
KaifK 4:08a0ff6668df 18
KaifK 4:08a0ff6668df 19 void Game::init() {
KaifK 24:c110f92fe266 20 level_flag = 1;
KaifK 4:08a0ff6668df 21 _is_goal = false;
KaifK 8:5ede90f99a27 22 _lives = 3;
KaifK 16:1f196a0e12be 23 _new_lives_threshold = 0;
KaifK 12:ca7329a41fc5 24 _level = 1;
KaifK 8:5ede90f99a27 25 _score = 0;
KaifK 9:e6566d09f087 26 _speed = 0.30f;
KaifK 16:1f196a0e12be 27 _new_speed_threshold = 0.00f;
KaifK 9:e6566d09f087 28 _x_val = 42.00f;
KaifK 9:e6566d09f087 29 _y_val = 0.00f;
KaifK 7:2a3b566aedd3 30 _shot_x = 0;
KaifK 7:2a3b566aedd3 31 _shot_y = 0;
KaifK 22:76bb0f52be8b 32 //Initialising Highscore
KaifK 22:76bb0f52be8b 33 fp = fopen("/sd/highscore.txt", "r"); //check for file
KaifK 22:76bb0f52be8b 34 if (fp == NULL) { // if it can't open the file (file does not exist)
KaifK 22:76bb0f52be8b 35 printf("No exisiting highscore!\n");
KaifK 22:76bb0f52be8b 36 set_highscore(0); // initialise highscore to zero
KaifK 22:76bb0f52be8b 37 } else { // if file exists, read highscore and initialise to that value
KaifK 22:76bb0f52be8b 38 fscanf(fp, "%d",&_highscore);
KaifK 22:76bb0f52be8b 39 printf("Initial Highscore found: %d\n",_highscore);
KaifK 22:76bb0f52be8b 40 set_highscore(_highscore);
KaifK 22:76bb0f52be8b 41 fclose(fp); // ensure you close the file after reading
KaifK 24:c110f92fe266 42 }
KaifK 4:08a0ff6668df 43 }
KaifK 9:e6566d09f087 44 void Game::play() {
KaifK 16:1f196a0e12be 45 // if all live are lost game ends
KaifK 17:2fbe40177b9c 46 while(_lives > 0) {
KaifK 17:2fbe40177b9c 47 updateSpeed();
KaifK 17:2fbe40177b9c 48 updateLives();
KaifK 17:2fbe40177b9c 49 updateLevel();
KaifK 17:2fbe40177b9c 50 readInput();
KaifK 16:1f196a0e12be 51 if(_is_goal) {
KaifK 12:ca7329a41fc5 52 _score++;
KaifK 12:ca7329a41fc5 53 }
KaifK 15:5bf3f951d337 54 else {
KaifK 15:5bf3f951d337 55 // ball should not go through obstacle hence y value limited to 21
KaifK 15:5bf3f951d337 56 // this is done after calculations to ensure accurate results
KaifK 17:2fbe40177b9c 57 if(_shot_y >= 9) { _shot_y = 21; }
KaifK 20:c697902b844f 58 if(_shot_y <= 5) {_shot_y = 3; }
KaifK 15:5bf3f951d337 59 _lives--;
KaifK 15:5bf3f951d337 60 }
KaifK 16:1f196a0e12be 61 _ball->playShot(_shot_x, _shot_y);
KaifK 16:1f196a0e12be 62 print_goal_message((int)_is_goal);
KaifK 12:ca7329a41fc5 63 }
KaifK 20:c697902b844f 64 if(_score > _highscore) { set_highscore(_score);}
KaifK 16:1f196a0e12be 65 _pad->leds(0.0); //turn of all leds
KaifK 8:5ede90f99a27 66 }
KaifK 7:2a3b566aedd3 67
KaifK 9:e6566d09f087 68 void Game::readInput() {
KaifK 17:2fbe40177b9c 69 _pad->reset_buttons(); //forced debounce/reset
KaifK 9:e6566d09f087 70 _x_val = 42; //reset x_val
KaifK 9:e6566d09f087 71 _y_val = 0; //reset y_val
KaifK 9:e6566d09f087 72 while(!_pad->A_pressed()) {
KaifK 9:e6566d09f087 73 pointer_input();
KaifK 7:2a3b566aedd3 74 }
KaifK 17:2fbe40177b9c 75 _pad->reset_buttons(); //forced debounce/reset
KaifK 9:e6566d09f087 76 while(!_pad->B_pressed()) {
KaifK 9:e6566d09f087 77 power_meter_input();
KaifK 6:09a555c0d997 78 }
KaifK 8:5ede90f99a27 79 convert_to_shot_x();
KaifK 7:2a3b566aedd3 80 convert_to_shot_y();
KaifK 17:2fbe40177b9c 81 _is_goal = _ball->isGoal(_level, _shot_x, _shot_y);
KaifK 20:c697902b844f 82 //printf("x val = %.2f \n",_x_val);
KaifK 20:c697902b844f 83 //printf("shot_x val = %d \n",_shot_x);
KaifK 20:c697902b844f 84 //printf("y val = %.2f \n",_y_val);
KaifK 20:c697902b844f 85 //printf("shot_y val = %d \n",_shot_y);
KaifK 6:09a555c0d997 86 }
KaifK 9:e6566d09f087 87 void Game::updateLives() {
KaifK 17:2fbe40177b9c 88 int val [6] = {0,0,0,0,0,0};
KaifK 16:1f196a0e12be 89 // +1 life if score hits a multiple of 5 provided less than 3 lives left
KaifK 16:1f196a0e12be 90 //update threshold so lives don't increase if score stays same
KaifK 16:1f196a0e12be 91 if(_score % 5 == 0 && _score != _new_lives_threshold && _lives != 3) {
KaifK 16:1f196a0e12be 92 _lives++;
KaifK 16:1f196a0e12be 93 _new_lives_threshold = _score;
KaifK 22:76bb0f52be8b 94 playGoalSound(4);
KaifK 16:1f196a0e12be 95 }
KaifK 20:c697902b844f 96 //printf("Lives = %d \n", _lives);
KaifK 5:ed71996c0534 97 switch(_lives){
KaifK 14:652fd55aebcf 98 case 0:
KaifK 14:652fd55aebcf 99 break;
KaifK 17:2fbe40177b9c 100 case 1: //red leds only
KaifK 17:2fbe40177b9c 101 val[0] = val[3] = 1;
KaifK 5:ed71996c0534 102 break;
KaifK 17:2fbe40177b9c 103 case 2: //red and yellow leds
KaifK 17:2fbe40177b9c 104 val[0] = val[1] = val[3] = val[4] = 1;
KaifK 5:ed71996c0534 105 break;
KaifK 17:2fbe40177b9c 106 case 3: //all leds on
KaifK 17:2fbe40177b9c 107 for (int i = 0; i < 6; i++) {val[i] = 1;}
KaifK 5:ed71996c0534 108 break;
KaifK 5:ed71996c0534 109 default:
KaifK 7:2a3b566aedd3 110 error("Invalid Number of Lives");
KaifK 5:ed71996c0534 111 break;
KaifK 5:ed71996c0534 112 }
KaifK 17:2fbe40177b9c 113 updateLeds(val);
KaifK 5:ed71996c0534 114 }
KaifK 9:e6566d09f087 115 void Game::updateScore() {
KaifK 5:ed71996c0534 116 char buffer[12];
KaifK 5:ed71996c0534 117 sprintf(buffer,"%d",_score);
KaifK 9:e6566d09f087 118 _lcd->printString(buffer,2,5);
KaifK 9:e6566d09f087 119 }
KaifK 9:e6566d09f087 120 void Game::updateSpeed() {
KaifK 17:2fbe40177b9c 121 if(abs(_speed) <= 3) { // max speed = 3
KaifK 16:1f196a0e12be 122 if(_score % 3 == 0 && _score != _new_speed_threshold) {
KaifK 16:1f196a0e12be 123 _speed = abs(_speed) + 0.20f;
KaifK 16:1f196a0e12be 124 //update threshold so speed does not increase if score stays same
KaifK 16:1f196a0e12be 125 _new_speed_threshold = _score;
KaifK 9:e6566d09f087 126 }
KaifK 9:e6566d09f087 127 }
KaifK 20:c697902b844f 128 //printf("speed = %.2f \n", _speed);
KaifK 20:c697902b844f 129 //printf("score = %d \n", _score);
KaifK 5:ed71996c0534 130 }
KaifK 17:2fbe40177b9c 131 void Game::updateLevel() {
KaifK 17:2fbe40177b9c 132 _level = random_level_gen(10); //generate random level
KaifK 21:d5b1160f349f 133 if( level_flag == 1) { //first level is always level 1
KaifK 21:d5b1160f349f 134 level_flag = 0; //flag always stays 0 after first time
KaifK 21:d5b1160f349f 135 _level = 1;
KaifK 21:d5b1160f349f 136 }
KaifK 17:2fbe40177b9c 137 _ball->set_level(_level); //set level
KaifK 20:c697902b844f 138 //printf("Level (in game) = %d \n", _level);
KaifK 17:2fbe40177b9c 139 }
KaifK 17:2fbe40177b9c 140 void Game::updateLeds( int val[6]) {
KaifK 17:2fbe40177b9c 141 _pad->led(1,val[0]);
KaifK 17:2fbe40177b9c 142 _pad->led(2,val[1]);
KaifK 17:2fbe40177b9c 143 _pad->led(3,val[2]);
KaifK 17:2fbe40177b9c 144 _pad->led(4,val[3]);
KaifK 17:2fbe40177b9c 145 _pad->led(5,val[4]);
KaifK 17:2fbe40177b9c 146 _pad->led(6,val[5]);
KaifK 17:2fbe40177b9c 147 }
KaifK 20:c697902b844f 148 void Game::playGoalSound(int sound) {
KaifK 20:c697902b844f 149 sound_sample = 0;
KaifK 20:c697902b844f 150 float val = 0.0f;
KaifK 20:c697902b844f 151 int NUM_ELEMENTS = 0;
KaifK 20:c697902b844f 152 ticker.attach(&timer_isr,226e-7);
KaifK 20:c697902b844f 153 if(sound == 1) {NUM_ELEMENTS = NUM_ELEMENTS_1;}
KaifK 20:c697902b844f 154 else if(sound == 2) {NUM_ELEMENTS = NUM_ELEMENTS_3;}
KaifK 20:c697902b844f 155 else if(sound == 3) {NUM_ELEMENTS = NUM_ELEMENTS_2;}
KaifK 22:76bb0f52be8b 156 else if(sound == 4) {NUM_ELEMENTS = NUM_ELEMENTS_4;}
KaifK 20:c697902b844f 157 while(sound_sample <= NUM_ELEMENTS) {
KaifK 20:c697902b844f 158 if (sound_timer_flag == 1) {
KaifK 20:c697902b844f 159 sound_timer_flag = 0;
KaifK 20:c697902b844f 160 // convert from 0 to 255 to 0.0 to 1.0
KaifK 20:c697902b844f 161 if(sound == 1) {val = float(miss[sound_sample])/ 256.0f;}
KaifK 20:c697902b844f 162 else if(sound == 2) {val = float(goall[sound_sample])/ 256.0f;}
KaifK 22:76bb0f52be8b 163 else if(sound == 3) {val = float(over[sound_sample])/ 256.0f;}
KaifK 22:76bb0f52be8b 164 else if(sound == 4) {val = float(life[sound_sample])/ 256.0f;}
KaifK 22:76bb0f52be8b 165 _pad->write_dac(val); // write to DAC
KaifK 22:76bb0f52be8b 166 sound_sample++; // move onto next sample
KaifK 20:c697902b844f 167 }
KaifK 20:c697902b844f 168 }
KaifK 20:c697902b844f 169 }
KaifK 16:1f196a0e12be 170 void Game::set_highscore (int score) {
KaifK 21:d5b1160f349f 171 _highscore = score;
KaifK 21:d5b1160f349f 172 fp = fopen("/sd/highscore.txt", "w");
KaifK 21:d5b1160f349f 173 if (fp == NULL) { // if it can't open the file then print error message
KaifK 21:d5b1160f349f 174 printf("Error! Unable to open file!\n");
KaifK 21:d5b1160f349f 175 } else { // opened file so can write
KaifK 23:ad9ac069e751 176 printf("Writing to file highscore: %d", _highscore);
KaifK 21:d5b1160f349f 177 fprintf(fp, "%d",_highscore); // ensure data type matches
KaifK 21:d5b1160f349f 178 printf("Done.\n");
KaifK 21:d5b1160f349f 179 fclose(fp); // ensure you close the file after writing
KaifK 21:d5b1160f349f 180 }
KaifK 16:1f196a0e12be 181 }
KaifK 16:1f196a0e12be 182 int Game::get_highscore() {
KaifK 21:d5b1160f349f 183 fp = fopen("/sd/highscore.txt", "r");
KaifK 21:d5b1160f349f 184 if (fp == NULL) { // if it can't open the file then print error message
KaifK 21:d5b1160f349f 185 printf("Error! Unable to open file!\n");
KaifK 21:d5b1160f349f 186 } else { // opened file so can write
KaifK 21:d5b1160f349f 187 fscanf(fp, "%d",&_highscore); // ensure data type matches - note address operator (&)
KaifK 21:d5b1160f349f 188 //printf("Read %d from file.\n",_highscore);
KaifK 21:d5b1160f349f 189 fclose(fp); // ensure you close the file after reading
KaifK 21:d5b1160f349f 190 }
KaifK 16:1f196a0e12be 191 int val = _highscore;
KaifK 16:1f196a0e12be 192 return val;
KaifK 16:1f196a0e12be 193 }
KaifK 9:e6566d09f087 194 void Game::pointer_input() {
KaifK 9:e6566d09f087 195 updateScore();
KaifK 12:ca7329a41fc5 196 _ball->displayBackground();
KaifK 21:d5b1160f349f 197 _ball->drawBall(BALL_INIT_X, BALL_INIT_Y, 6);
KaifK 7:2a3b566aedd3 198 //draw aim pointer
KaifK 9:e6566d09f087 199 _lcd->drawLine(WIDTH / 2 - 5, 41, _x_val, HEIGHT / 2 + 7, 1);//left side
KaifK 9:e6566d09f087 200 _lcd->drawLine(WIDTH / 2 + 5, 41, _x_val, HEIGHT / 2 + 7, 1);//right side
KaifK 12:ca7329a41fc5 201 _lcd->drawLine(WIDTH / 2 + 5, 41, WIDTH / 2 - 5, 41, 1); //base
KaifK 7:2a3b566aedd3 202 _x_val += _speed;
KaifK 9:e6566d09f087 203 //printf("dir = %d \n", _speed);
KaifK 9:e6566d09f087 204 if((int)_x_val >= 70) { _speed = (-1 * _speed); }
KaifK 9:e6566d09f087 205 //pointer points out of screen i.e. 70=84 therefore, switch direction
KaifK 7:2a3b566aedd3 206 //value found through trial and error using print statement
KaifK 9:e6566d09f087 207 else if((int)_x_val <= 12) { _speed = abs(_speed); }
KaifK 9:e6566d09f087 208 _lcd->refresh();
KaifK 9:e6566d09f087 209 _lcd->clear();
KaifK 7:2a3b566aedd3 210 wait(0.01);
KaifK 7:2a3b566aedd3 211 }
KaifK 9:e6566d09f087 212 void Game::power_meter_input() {
KaifK 9:e6566d09f087 213 updateScore();
KaifK 12:ca7329a41fc5 214 _ball->displayBackground();
KaifK 21:d5b1160f349f 215 _ball->drawBall(BALL_INIT_X, BALL_INIT_Y, 6);
KaifK 7:2a3b566aedd3 216 //keep direction of pointer
KaifK 9:e6566d09f087 217 _lcd->drawLine(WIDTH / 2 - 5, 41, _x_val, HEIGHT / 2 + 7, 1);
KaifK 9:e6566d09f087 218 _lcd->drawLine(WIDTH / 2 + 5, 41, _x_val, HEIGHT / 2 + 7, 1);
KaifK 12:ca7329a41fc5 219 _lcd->drawLine(WIDTH / 2 + 5, 41, WIDTH / 2 - 5, 41, 1);
KaifK 7:2a3b566aedd3 220 //fill and empty power meter
KaifK 21:d5b1160f349f 221 _lcd->drawRect(77, 27, 6, _y_val, FILL_BLACK);
KaifK 9:e6566d09f087 222 _y_val += _speed/2;
KaifK 9:e6566d09f087 223 if((int)_y_val >= 20) { _speed = (-1 * _speed); } //power meter full
KaifK 9:e6566d09f087 224 else if((int)_y_val <= 0) { _speed = abs(_speed); } // power meter empty
KaifK 9:e6566d09f087 225 _lcd->refresh();
KaifK 9:e6566d09f087 226 _lcd->clear();
KaifK 7:2a3b566aedd3 227 wait(0.01);
KaifK 7:2a3b566aedd3 228 }
KaifK 7:2a3b566aedd3 229 void Game::convert_to_shot_x() {
KaifK 9:e6566d09f087 230 //convert from range 12-70 (range of pointer) to 0-84 (range of screen)
KaifK 9:e6566d09f087 231 _shot_x = ((((int)_x_val - 12) * (84)) / (70 - 12));
KaifK 8:5ede90f99a27 232 //ball misses goal completely
KaifK 17:2fbe40177b9c 233 if(_shot_x <=7) { _shot_x = 0;}
KaifK 17:2fbe40177b9c 234 else if(_shot_x >=77) { _shot_x = 84;}
KaifK 7:2a3b566aedd3 235 }
KaifK 7:2a3b566aedd3 236 void Game::convert_to_shot_y() {
KaifK 9:e6566d09f087 237 _shot_y = ((((int)_y_val) * (24)) / (20));
KaifK 17:2fbe40177b9c 238 if (_shot_y >= 19) {_shot_y = 19; }//shot is low, but must enter goal
KaifK 9:e6566d09f087 239 }
KaifK 9:e6566d09f087 240 int Game::random_level_gen(int limit) {
KaifK 15:5bf3f951d337 241 int number = (rand() % limit) + 1; //random level between 1-10
KaifK 15:5bf3f951d337 242 return number;
KaifK 15:5bf3f951d337 243 }
KaifK 15:5bf3f951d337 244 void Game::print_goal_message(int n) {
KaifK 15:5bf3f951d337 245 _ball->displayBackground();
KaifK 15:5bf3f951d337 246 _lcd->drawRect(0,14,84,11,FILL_WHITE);//white background
KaifK 17:2fbe40177b9c 247 _lcd->drawRect(0,14,84,11,FILL_TRANSPARENT);//black outline
KaifK 15:5bf3f951d337 248
KaifK 15:5bf3f951d337 249 switch(n) {
KaifK 15:5bf3f951d337 250 case 0:
KaifK 15:5bf3f951d337 251 _lcd->printString("MISS!",30,2);
KaifK 15:5bf3f951d337 252 break;
KaifK 15:5bf3f951d337 253 case 1:
KaifK 15:5bf3f951d337 254 _lcd->printString("GOAL!",30,2);
KaifK 15:5bf3f951d337 255 break;
KaifK 15:5bf3f951d337 256 }
KaifK 15:5bf3f951d337 257 _lcd->refresh();
KaifK 22:76bb0f52be8b 258 wait(0.5);
KaifK 22:76bb0f52be8b 259 playGoalSound((int)_is_goal + 1);
KaifK 22:76bb0f52be8b 260 wait(1);
KaifK 7:2a3b566aedd3 261 }
KaifK 20:c697902b844f 262 void timer_isr() {
KaifK 20:c697902b844f 263 sound_timer_flag = 1; // set flag in the isr
KaifK 20:c697902b844f 264 }
KaifK 7:2a3b566aedd3 265
KaifK 8:5ede90f99a27 266