Kaif Kutchwala 201267448 ELEC2645 Project

Dependencies:   mbed

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?

UserRevisionLine numberNew 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