Kaif Kutchwala 201267448 ELEC2645 Project
Dependencies: mbed
Game/Game.cpp@20:c697902b844f, 2020-05-24 (annotated)
- Committer:
- KaifK
- Date:
- Sun May 24 17:40:56 2020 +0000
- Revision:
- 20:c697902b844f
- Parent:
- 17:2fbe40177b9c
- Child:
- 21:d5b1160f349f
music added, high shot bug fixed
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
KaifK | 4:08a0ff6668df | 1 | #include "Game.h" |
KaifK | 20:c697902b844f | 2 | Ticker ticker; |
KaifK | 20:c697902b844f | 3 | |
KaifK | 20:c697902b844f | 4 | volatile int sound_timer_flag = 0; |
KaifK | 20:c697902b844f | 5 | volatile int sound_sample = 0; |
KaifK | 20:c697902b844f | 6 | |
KaifK | 20:c697902b844f | 7 | void timer_isr(); |
KaifK | 8:5ede90f99a27 | 8 | |
KaifK | 9:e6566d09f087 | 9 | Game::Game(N5110 &lcd, Gamepad &pad, Ball &ball) { |
KaifK | 9:e6566d09f087 | 10 | _lcd = &lcd; |
KaifK | 9:e6566d09f087 | 11 | _pad = &pad; |
KaifK | 9:e6566d09f087 | 12 | _ball = &ball; |
KaifK | 9:e6566d09f087 | 13 | } |
KaifK | 4:08a0ff6668df | 14 | Game::~Game() {} |
KaifK | 4:08a0ff6668df | 15 | |
KaifK | 4:08a0ff6668df | 16 | void Game::init() { |
KaifK | 4:08a0ff6668df | 17 | _is_goal = false; |
KaifK | 8:5ede90f99a27 | 18 | _lives = 3; |
KaifK | 16:1f196a0e12be | 19 | _new_lives_threshold = 0; |
KaifK | 12:ca7329a41fc5 | 20 | _level = 1; |
KaifK | 8:5ede90f99a27 | 21 | _score = 0; |
KaifK | 16:1f196a0e12be | 22 | _highscore = 0; |
KaifK | 9:e6566d09f087 | 23 | _speed = 0.30f; |
KaifK | 16:1f196a0e12be | 24 | _new_speed_threshold = 0.00f; |
KaifK | 9:e6566d09f087 | 25 | _x_val = 42.00f; |
KaifK | 9:e6566d09f087 | 26 | _y_val = 0.00f; |
KaifK | 7:2a3b566aedd3 | 27 | _shot_x = 0; |
KaifK | 7:2a3b566aedd3 | 28 | _shot_y = 0; |
KaifK | 4:08a0ff6668df | 29 | } |
KaifK | 9:e6566d09f087 | 30 | void Game::play() { |
KaifK | 16:1f196a0e12be | 31 | // if all live are lost game ends |
KaifK | 17:2fbe40177b9c | 32 | while(_lives > 0) { |
KaifK | 17:2fbe40177b9c | 33 | updateSpeed(); |
KaifK | 17:2fbe40177b9c | 34 | updateLives(); |
KaifK | 17:2fbe40177b9c | 35 | updateLevel(); |
KaifK | 17:2fbe40177b9c | 36 | readInput(); |
KaifK | 16:1f196a0e12be | 37 | if(_is_goal) { |
KaifK | 12:ca7329a41fc5 | 38 | _score++; |
KaifK | 12:ca7329a41fc5 | 39 | } |
KaifK | 15:5bf3f951d337 | 40 | else { |
KaifK | 15:5bf3f951d337 | 41 | // ball should not go through obstacle hence y value limited to 21 |
KaifK | 15:5bf3f951d337 | 42 | // this is done after calculations to ensure accurate results |
KaifK | 17:2fbe40177b9c | 43 | if(_shot_y >= 9) { _shot_y = 21; } |
KaifK | 20:c697902b844f | 44 | if(_shot_y <= 5) {_shot_y = 3; } |
KaifK | 15:5bf3f951d337 | 45 | _lives--; |
KaifK | 15:5bf3f951d337 | 46 | } |
KaifK | 16:1f196a0e12be | 47 | _ball->playShot(_shot_x, _shot_y); |
KaifK | 16:1f196a0e12be | 48 | print_goal_message((int)_is_goal); |
KaifK | 20:c697902b844f | 49 | playGoalSound((int)_is_goal + 1); |
KaifK | 12:ca7329a41fc5 | 50 | } |
KaifK | 20:c697902b844f | 51 | if(_score > _highscore) { set_highscore(_score);} |
KaifK | 16:1f196a0e12be | 52 | _pad->leds(0.0); //turn of all leds |
KaifK | 8:5ede90f99a27 | 53 | } |
KaifK | 7:2a3b566aedd3 | 54 | |
KaifK | 9:e6566d09f087 | 55 | void Game::readInput() { |
KaifK | 17:2fbe40177b9c | 56 | _pad->reset_buttons(); //forced debounce/reset |
KaifK | 9:e6566d09f087 | 57 | _x_val = 42; //reset x_val |
KaifK | 9:e6566d09f087 | 58 | _y_val = 0; //reset y_val |
KaifK | 9:e6566d09f087 | 59 | while(!_pad->A_pressed()) { |
KaifK | 9:e6566d09f087 | 60 | pointer_input(); |
KaifK | 7:2a3b566aedd3 | 61 | } |
KaifK | 17:2fbe40177b9c | 62 | _pad->reset_buttons(); //forced debounce/reset |
KaifK | 9:e6566d09f087 | 63 | while(!_pad->B_pressed()) { |
KaifK | 9:e6566d09f087 | 64 | power_meter_input(); |
KaifK | 6:09a555c0d997 | 65 | } |
KaifK | 8:5ede90f99a27 | 66 | convert_to_shot_x(); |
KaifK | 7:2a3b566aedd3 | 67 | convert_to_shot_y(); |
KaifK | 17:2fbe40177b9c | 68 | _is_goal = _ball->isGoal(_level, _shot_x, _shot_y); |
KaifK | 20:c697902b844f | 69 | //printf("x val = %.2f \n",_x_val); |
KaifK | 20:c697902b844f | 70 | //printf("shot_x val = %d \n",_shot_x); |
KaifK | 20:c697902b844f | 71 | //printf("y val = %.2f \n",_y_val); |
KaifK | 20:c697902b844f | 72 | //printf("shot_y val = %d \n",_shot_y); |
KaifK | 6:09a555c0d997 | 73 | } |
KaifK | 9:e6566d09f087 | 74 | void Game::updateLives() { |
KaifK | 17:2fbe40177b9c | 75 | int val [6] = {0,0,0,0,0,0}; |
KaifK | 16:1f196a0e12be | 76 | // +1 life if score hits a multiple of 5 provided less than 3 lives left |
KaifK | 16:1f196a0e12be | 77 | //update threshold so lives don't increase if score stays same |
KaifK | 16:1f196a0e12be | 78 | if(_score % 5 == 0 && _score != _new_lives_threshold && _lives != 3) { |
KaifK | 16:1f196a0e12be | 79 | _lives++; |
KaifK | 16:1f196a0e12be | 80 | _new_lives_threshold = _score; |
KaifK | 16:1f196a0e12be | 81 | } |
KaifK | 20:c697902b844f | 82 | //printf("Lives = %d \n", _lives); |
KaifK | 5:ed71996c0534 | 83 | switch(_lives){ |
KaifK | 14:652fd55aebcf | 84 | case 0: |
KaifK | 14:652fd55aebcf | 85 | break; |
KaifK | 17:2fbe40177b9c | 86 | case 1: //red leds only |
KaifK | 17:2fbe40177b9c | 87 | val[0] = val[3] = 1; |
KaifK | 5:ed71996c0534 | 88 | break; |
KaifK | 17:2fbe40177b9c | 89 | case 2: //red and yellow leds |
KaifK | 17:2fbe40177b9c | 90 | val[0] = val[1] = val[3] = val[4] = 1; |
KaifK | 5:ed71996c0534 | 91 | break; |
KaifK | 17:2fbe40177b9c | 92 | case 3: //all leds on |
KaifK | 17:2fbe40177b9c | 93 | for (int i = 0; i < 6; i++) {val[i] = 1;} |
KaifK | 5:ed71996c0534 | 94 | break; |
KaifK | 5:ed71996c0534 | 95 | default: |
KaifK | 7:2a3b566aedd3 | 96 | error("Invalid Number of Lives"); |
KaifK | 5:ed71996c0534 | 97 | break; |
KaifK | 5:ed71996c0534 | 98 | } |
KaifK | 17:2fbe40177b9c | 99 | updateLeds(val); |
KaifK | 5:ed71996c0534 | 100 | } |
KaifK | 9:e6566d09f087 | 101 | void Game::updateScore() { |
KaifK | 5:ed71996c0534 | 102 | char buffer[12]; |
KaifK | 5:ed71996c0534 | 103 | sprintf(buffer,"%d",_score); |
KaifK | 9:e6566d09f087 | 104 | _lcd->printString(buffer,2,5); |
KaifK | 9:e6566d09f087 | 105 | } |
KaifK | 9:e6566d09f087 | 106 | void Game::updateSpeed() { |
KaifK | 17:2fbe40177b9c | 107 | if(abs(_speed) <= 3) { // max speed = 3 |
KaifK | 16:1f196a0e12be | 108 | if(_score % 3 == 0 && _score != _new_speed_threshold) { |
KaifK | 16:1f196a0e12be | 109 | _speed = abs(_speed) + 0.20f; |
KaifK | 16:1f196a0e12be | 110 | //update threshold so speed does not increase if score stays same |
KaifK | 16:1f196a0e12be | 111 | _new_speed_threshold = _score; |
KaifK | 9:e6566d09f087 | 112 | } |
KaifK | 9:e6566d09f087 | 113 | } |
KaifK | 20:c697902b844f | 114 | //printf("speed = %.2f \n", _speed); |
KaifK | 20:c697902b844f | 115 | //printf("score = %d \n", _score); |
KaifK | 5:ed71996c0534 | 116 | } |
KaifK | 17:2fbe40177b9c | 117 | void Game::updateLevel() { |
KaifK | 17:2fbe40177b9c | 118 | _level = random_level_gen(10); //generate random level |
KaifK | 17:2fbe40177b9c | 119 | _ball->set_level(_level); //set level |
KaifK | 20:c697902b844f | 120 | //printf("Level (in game) = %d \n", _level); |
KaifK | 17:2fbe40177b9c | 121 | } |
KaifK | 17:2fbe40177b9c | 122 | void Game::updateLeds( int val[6]) { |
KaifK | 17:2fbe40177b9c | 123 | _pad->led(1,val[0]); |
KaifK | 17:2fbe40177b9c | 124 | _pad->led(2,val[1]); |
KaifK | 17:2fbe40177b9c | 125 | _pad->led(3,val[2]); |
KaifK | 17:2fbe40177b9c | 126 | _pad->led(4,val[3]); |
KaifK | 17:2fbe40177b9c | 127 | _pad->led(5,val[4]); |
KaifK | 17:2fbe40177b9c | 128 | _pad->led(6,val[5]); |
KaifK | 17:2fbe40177b9c | 129 | } |
KaifK | 20:c697902b844f | 130 | void Game::playGoalSound(int sound) { |
KaifK | 20:c697902b844f | 131 | sound_sample = 0; |
KaifK | 20:c697902b844f | 132 | float val = 0.0f; |
KaifK | 20:c697902b844f | 133 | int NUM_ELEMENTS = 0; |
KaifK | 20:c697902b844f | 134 | ticker.attach(&timer_isr,226e-7); |
KaifK | 20:c697902b844f | 135 | if(sound == 1) {NUM_ELEMENTS = NUM_ELEMENTS_1;} |
KaifK | 20:c697902b844f | 136 | else if(sound == 2) {NUM_ELEMENTS = NUM_ELEMENTS_3;} |
KaifK | 20:c697902b844f | 137 | else if(sound == 3) {NUM_ELEMENTS = NUM_ELEMENTS_2;} |
KaifK | 20:c697902b844f | 138 | while(sound_sample <= NUM_ELEMENTS) { |
KaifK | 20:c697902b844f | 139 | if (sound_timer_flag == 1) { |
KaifK | 20:c697902b844f | 140 | sound_timer_flag = 0; |
KaifK | 20:c697902b844f | 141 | // convert from 0 to 255 to 0.0 to 1.0 |
KaifK | 20:c697902b844f | 142 | if(sound == 1) {val = float(miss[sound_sample])/ 256.0f;} |
KaifK | 20:c697902b844f | 143 | else if(sound == 2) {val = float(goall[sound_sample])/ 256.0f;} |
KaifK | 20:c697902b844f | 144 | else if(sound == 3) {val = float(over[sound_sample])/ 256.0f;} |
KaifK | 20:c697902b844f | 145 | // write to DAC |
KaifK | 20:c697902b844f | 146 | _pad->write_dac(val); |
KaifK | 20:c697902b844f | 147 | // move onto next sample |
KaifK | 20:c697902b844f | 148 | sound_sample++; |
KaifK | 20:c697902b844f | 149 | } |
KaifK | 20:c697902b844f | 150 | } |
KaifK | 20:c697902b844f | 151 | } |
KaifK | 16:1f196a0e12be | 152 | void Game::set_highscore (int score) { |
KaifK | 16:1f196a0e12be | 153 | _highscore = score; |
KaifK | 16:1f196a0e12be | 154 | } |
KaifK | 16:1f196a0e12be | 155 | int Game::get_highscore() { |
KaifK | 16:1f196a0e12be | 156 | int val = _highscore; |
KaifK | 16:1f196a0e12be | 157 | return val; |
KaifK | 16:1f196a0e12be | 158 | } |
KaifK | 9:e6566d09f087 | 159 | void Game::pointer_input() { |
KaifK | 9:e6566d09f087 | 160 | updateScore(); |
KaifK | 12:ca7329a41fc5 | 161 | _ball->displayBackground(); |
KaifK | 9:e6566d09f087 | 162 | _ball->init(); |
KaifK | 7:2a3b566aedd3 | 163 | //draw aim pointer |
KaifK | 9:e6566d09f087 | 164 | _lcd->drawLine(WIDTH / 2 - 5, 41, _x_val, HEIGHT / 2 + 7, 1);//left side |
KaifK | 9:e6566d09f087 | 165 | _lcd->drawLine(WIDTH / 2 + 5, 41, _x_val, HEIGHT / 2 + 7, 1);//right side |
KaifK | 12:ca7329a41fc5 | 166 | _lcd->drawLine(WIDTH / 2 + 5, 41, WIDTH / 2 - 5, 41, 1); //base |
KaifK | 7:2a3b566aedd3 | 167 | _x_val += _speed; |
KaifK | 9:e6566d09f087 | 168 | //printf("dir = %d \n", _speed); |
KaifK | 9:e6566d09f087 | 169 | if((int)_x_val >= 70) { _speed = (-1 * _speed); } |
KaifK | 9:e6566d09f087 | 170 | //pointer points out of screen i.e. 70=84 therefore, switch direction |
KaifK | 7:2a3b566aedd3 | 171 | //value found through trial and error using print statement |
KaifK | 9:e6566d09f087 | 172 | else if((int)_x_val <= 12) { _speed = abs(_speed); } |
KaifK | 9:e6566d09f087 | 173 | _lcd->refresh(); |
KaifK | 9:e6566d09f087 | 174 | _lcd->clear(); |
KaifK | 7:2a3b566aedd3 | 175 | wait(0.01); |
KaifK | 7:2a3b566aedd3 | 176 | } |
KaifK | 9:e6566d09f087 | 177 | void Game::power_meter_input() { |
KaifK | 9:e6566d09f087 | 178 | updateScore(); |
KaifK | 12:ca7329a41fc5 | 179 | _ball->displayBackground(); |
KaifK | 12:ca7329a41fc5 | 180 | _ball->init(); |
KaifK | 7:2a3b566aedd3 | 181 | //keep direction of pointer |
KaifK | 9:e6566d09f087 | 182 | _lcd->drawLine(WIDTH / 2 - 5, 41, _x_val, HEIGHT / 2 + 7, 1); |
KaifK | 9:e6566d09f087 | 183 | _lcd->drawLine(WIDTH / 2 + 5, 41, _x_val, HEIGHT / 2 + 7, 1); |
KaifK | 12:ca7329a41fc5 | 184 | _lcd->drawLine(WIDTH / 2 + 5, 41, WIDTH / 2 - 5, 41, 1); |
KaifK | 7:2a3b566aedd3 | 185 | //fill and empty power meter |
KaifK | 9:e6566d09f087 | 186 | _lcd->drawRect(77,27,6,_y_val,FILL_BLACK); |
KaifK | 9:e6566d09f087 | 187 | _y_val += _speed/2; |
KaifK | 9:e6566d09f087 | 188 | if((int)_y_val >= 20) { _speed = (-1 * _speed); } //power meter full |
KaifK | 9:e6566d09f087 | 189 | else if((int)_y_val <= 0) { _speed = abs(_speed); } // power meter empty |
KaifK | 9:e6566d09f087 | 190 | _lcd->refresh(); |
KaifK | 9:e6566d09f087 | 191 | _lcd->clear(); |
KaifK | 7:2a3b566aedd3 | 192 | wait(0.01); |
KaifK | 7:2a3b566aedd3 | 193 | } |
KaifK | 7:2a3b566aedd3 | 194 | void Game::convert_to_shot_x() { |
KaifK | 9:e6566d09f087 | 195 | //convert from range 12-70 (range of pointer) to 0-84 (range of screen) |
KaifK | 9:e6566d09f087 | 196 | _shot_x = ((((int)_x_val - 12) * (84)) / (70 - 12)); |
KaifK | 8:5ede90f99a27 | 197 | //ball misses goal completely |
KaifK | 17:2fbe40177b9c | 198 | if(_shot_x <=7) { _shot_x = 0;} |
KaifK | 17:2fbe40177b9c | 199 | else if(_shot_x >=77) { _shot_x = 84;} |
KaifK | 7:2a3b566aedd3 | 200 | } |
KaifK | 7:2a3b566aedd3 | 201 | void Game::convert_to_shot_y() { |
KaifK | 9:e6566d09f087 | 202 | _shot_y = ((((int)_y_val) * (24)) / (20)); |
KaifK | 17:2fbe40177b9c | 203 | if (_shot_y >= 19) {_shot_y = 19; }//shot is low, but must enter goal |
KaifK | 9:e6566d09f087 | 204 | } |
KaifK | 9:e6566d09f087 | 205 | int Game::random_level_gen(int limit) { |
KaifK | 15:5bf3f951d337 | 206 | int number = (rand() % limit) + 1; //random level between 1-10 |
KaifK | 15:5bf3f951d337 | 207 | return number; |
KaifK | 15:5bf3f951d337 | 208 | } |
KaifK | 15:5bf3f951d337 | 209 | void Game::print_goal_message(int n) { |
KaifK | 15:5bf3f951d337 | 210 | _ball->displayBackground(); |
KaifK | 15:5bf3f951d337 | 211 | _lcd->drawRect(0,14,84,11,FILL_WHITE);//white background |
KaifK | 17:2fbe40177b9c | 212 | _lcd->drawRect(0,14,84,11,FILL_TRANSPARENT);//black outline |
KaifK | 15:5bf3f951d337 | 213 | |
KaifK | 15:5bf3f951d337 | 214 | switch(n) { |
KaifK | 15:5bf3f951d337 | 215 | case 0: |
KaifK | 15:5bf3f951d337 | 216 | _lcd->printString("MISS!",30,2); |
KaifK | 15:5bf3f951d337 | 217 | break; |
KaifK | 15:5bf3f951d337 | 218 | case 1: |
KaifK | 15:5bf3f951d337 | 219 | _lcd->printString("GOAL!",30,2); |
KaifK | 15:5bf3f951d337 | 220 | break; |
KaifK | 15:5bf3f951d337 | 221 | } |
KaifK | 15:5bf3f951d337 | 222 | _lcd->refresh(); |
KaifK | 15:5bf3f951d337 | 223 | wait(1.5); |
KaifK | 7:2a3b566aedd3 | 224 | } |
KaifK | 20:c697902b844f | 225 | void timer_isr() { |
KaifK | 20:c697902b844f | 226 | sound_timer_flag = 1; // set flag in the isr |
KaifK | 20:c697902b844f | 227 | } |
KaifK | 7:2a3b566aedd3 | 228 | |
KaifK | 8:5ede90f99a27 | 229 |