ELEC2645 (2018/19) / Mbed 2 deprecated el17ebs

Dependencies:   mbed FATFileSystem

Committer:
ellisbhastroud
Date:
Wed May 08 14:54:19 2019 +0000
Revision:
14:08ac9aaa34c3
Parent:
12:7f7fadb5c106
Child:
15:d855e8c666e7
Doxygen comments added;

Who changed what in which revision?

UserRevisionLine numberNew contents of line
ellisbhastroud 3:a8960004d261 1 #include "Ball.h"
ellisbhastroud 3:a8960004d261 2
ellisbhastroud 3:a8960004d261 3 //constructor
ellisbhastroud 3:a8960004d261 4
ellisbhastroud 3:a8960004d261 5 Ball::Ball()
ellisbhastroud 3:a8960004d261 6 {
ellisbhastroud 3:a8960004d261 7
ellisbhastroud 3:a8960004d261 8 }
ellisbhastroud 3:a8960004d261 9
ellisbhastroud 3:a8960004d261 10 //deconstructor
ellisbhastroud 3:a8960004d261 11
ellisbhastroud 3:a8960004d261 12 Ball::~Ball()
ellisbhastroud 3:a8960004d261 13 {
ellisbhastroud 3:a8960004d261 14
ellisbhastroud 3:a8960004d261 15 }
ellisbhastroud 3:a8960004d261 16
ellisbhastroud 3:a8960004d261 17 //public methods
ellisbhastroud 3:a8960004d261 18
ellisbhastroud 9:bc34f2243e43 19 void Ball::init(Coord start_pos) //ball starts new level stationary in x and y positions given
ellisbhastroud 3:a8960004d261 20 {
ellisbhastroud 12:7f7fadb5c106 21 _x_pos = start_pos.x; //moves ball position to coordinates given
ellisbhastroud 9:bc34f2243e43 22 _y_pos = start_pos.y;
ellisbhastroud 12:7f7fadb5c106 23 _x_vel = 0.0f; //makes ball stationary
ellisbhastroud 4:035448357749 24 _y_vel = 0.0f;
ellisbhastroud 12:7f7fadb5c106 25 _total_shot_count = _total_shot_count + _shot_count; //totals shot count from previous levels
ellisbhastroud 12:7f7fadb5c106 26 _shot_count = 0; //resets in level shot count for the next level
ellisbhastroud 3:a8960004d261 27 }
ellisbhastroud 3:a8960004d261 28
ellisbhastroud 12:7f7fadb5c106 29 void Ball::drawBall(N5110 &lcd) //draws ball into lcd buffer
ellisbhastroud 3:a8960004d261 30 {
ellisbhastroud 5:0b31909caf7f 31 lcd.drawRect(_x_pos,_y_pos,2,2,FILL_BLACK); //draws ball
ellisbhastroud 3:a8960004d261 32 }
ellisbhastroud 3:a8960004d261 33
ellisbhastroud 12:7f7fadb5c106 34 void Ball::printShotCount(N5110 &lcd) //this is tallied for each level to give user an end score
ellisbhastroud 3:a8960004d261 35 {
ellisbhastroud 5:0b31909caf7f 36 char buffer[14];
ellisbhastroud 5:0b31909caf7f 37 sprintf(buffer,"Shot %i",_shot_count);
ellisbhastroud 5:0b31909caf7f 38 lcd.printString(buffer,40,0);
ellisbhastroud 4:035448357749 39 }
ellisbhastroud 4:035448357749 40
ellisbhastroud 12:7f7fadb5c106 41 void Ball::drawPower(N5110 &lcd, float mag) //draws power bar in top left of screen to indicate how hard a shot is hit
ellisbhastroud 5:0b31909caf7f 42 {
ellisbhastroud 10:9f54a6366e94 43 lcd.drawRect(0,1,36,6,FILL_TRANSPARENT);
ellisbhastroud 10:9f54a6366e94 44 lcd.drawRect(0,1,36*mag,6,FILL_BLACK);
ellisbhastroud 3:a8960004d261 45 }
ellisbhastroud 3:a8960004d261 46
ellisbhastroud 3:a8960004d261 47
ellisbhastroud 12:7f7fadb5c106 48 void Ball::drawAim(N5110 &lcd, Vector2D joy_coord, float angle) //draws aim help for ball
ellisbhastroud 12:7f7fadb5c106 49 { //aim indicates path of ball if shot
ellisbhastroud 12:7f7fadb5c106 50 if(angle != -1.0f && abs(_x_vel) < TOL && abs(_y_vel) < TOL) { //if joystick off centre and ball stationary draw shot direction indicator
ellisbhastroud 12:7f7fadb5c106 51 lcd.drawLine(_x_pos,_y_pos,_x_pos-12*joy_coord.x,_y_pos+12*joy_coord.y,2);
ellisbhastroud 8:d410856c6d04 52 }
ellisbhastroud 8:d410856c6d04 53 }
ellisbhastroud 8:d410856c6d04 54
ellisbhastroud 12:7f7fadb5c106 55 void Ball::move_ball() //controls the ball position movement
ellisbhastroud 3:a8960004d261 56 {
ellisbhastroud 10:9f54a6366e94 57 _x_pos = _x_pos + _x_vel*10.0f/_frame_rate; //move ball position at rate proportional to velocity in each direction
ellisbhastroud 10:9f54a6366e94 58 _y_pos = _y_pos + _y_vel*10.0f/_frame_rate;
ellisbhastroud 12:7f7fadb5c106 59 _x_vel = _x_vel*(1.0f-(0.6f/_frame_rate)); //velocity decreases as ball moves
ellisbhastroud 12:7f7fadb5c106 60 _y_vel = _y_vel*(1.0f-(0.6f/_frame_rate)); //inversely proportional to frame rate to ensure ball movement is the same at all frame rates
ellisbhastroud 14:08ac9aaa34c3 61 if(_x_vel != 0 && _y_vel != 0 && abs(_x_vel) < 0.15f && abs(_y_vel) < 0.15f) { //to make ball come to complete stop when velocity is small enough
ellisbhastroud 8:d410856c6d04 62 _x_vel = 0;
ellisbhastroud 8:d410856c6d04 63 _y_vel = 0;
ellisbhastroud 8:d410856c6d04 64 }
ellisbhastroud 3:a8960004d261 65 }
ellisbhastroud 3:a8960004d261 66
ellisbhastroud 14:08ac9aaa34c3 67 void Ball::check_shoot_ball(Gamepad &pad, Vector2D _joy_coord) //checks if shoot coniditons met and A pressed then ball is shot using joystick input
ellisbhastroud 12:7f7fadb5c106 68 { //direction of shot is in opposite direction of joystick direction
ellisbhastroud 14:08ac9aaa34c3 69 if(pad.check_event(Gamepad::A_PRESSED) == true && abs(_x_vel) < TOL && abs(_y_vel) < TOL && pad.get_mag() > 0.05f){ //If ball stationary and A pressed then shoot
ellisbhastroud 12:7f7fadb5c106 70 _x_vel = 6.0f * -_joy_coord.x; //scale x velocity by joystick direction and magnitude
ellisbhastroud 12:7f7fadb5c106 71 _y_vel = 6.0f * _joy_coord.y; //scale y velocity by joystick direction and magnitude
ellisbhastroud 12:7f7fadb5c106 72 _shot_count ++; //increment shot count
ellisbhastroud 14:08ac9aaa34c3 73 pad.tone(392.00 , 0.25); //play note when ball shot (G4)
ellisbhastroud 12:7f7fadb5c106 74 }
ellisbhastroud 4:035448357749 75 }
ellisbhastroud 4:035448357749 76
ellisbhastroud 12:7f7fadb5c106 77 void Ball::set_total_shot_count(int total_shot_count) //used to initialise value to 0
ellisbhastroud 12:7f7fadb5c106 78 {
ellisbhastroud 14:08ac9aaa34c3 79 _total_shot_count = total_shot_count;
ellisbhastroud 3:a8960004d261 80 }
ellisbhastroud 3:a8960004d261 81
ellisbhastroud 12:7f7fadb5c106 82 int Ball::get_total_shot_count() //used at end to add tally to highscore - the lowest shot count is the best score
ellisbhastroud 3:a8960004d261 83 {
ellisbhastroud 9:bc34f2243e43 84 int total_shot_count = _total_shot_count;
ellisbhastroud 9:bc34f2243e43 85 return total_shot_count;
ellisbhastroud 9:bc34f2243e43 86 }
ellisbhastroud 9:bc34f2243e43 87
ellisbhastroud 9:bc34f2243e43 88 bool Ball::check_hole(Coord hole) //returns true when ball is hit in hole and next level begins
ellisbhastroud 9:bc34f2243e43 89 {
ellisbhastroud 9:bc34f2243e43 90 if(_x_pos > hole.x - 1 && _x_pos < hole.x + 2 && _y_pos > hole.y - 1 && _y_pos < hole.y + 2) {
ellisbhastroud 9:bc34f2243e43 91 _x_vel = 0; //stop ball moving
ellisbhastroud 9:bc34f2243e43 92 _y_vel = 0;
ellisbhastroud 9:bc34f2243e43 93 _x_pos = hole.x;
ellisbhastroud 9:bc34f2243e43 94 _y_pos = hole.y;
ellisbhastroud 9:bc34f2243e43 95 return true; //causes next level process to begin
ellisbhastroud 9:bc34f2243e43 96 }
ellisbhastroud 9:bc34f2243e43 97 else {
ellisbhastroud 9:bc34f2243e43 98 return false;
ellisbhastroud 9:bc34f2243e43 99 }
ellisbhastroud 9:bc34f2243e43 100 }
ellisbhastroud 9:bc34f2243e43 101
ellisbhastroud 9:bc34f2243e43 102 void Ball::check_wall_bounce(WallMap map[], int size) //uses information from WallMap array for each level to check for bounces
ellisbhastroud 3:a8960004d261 103 {
ellisbhastroud 12:7f7fadb5c106 104 for(int i = 0; i < size; i ++) { //runs through each element in array of wall types to check if bounce condition is met by ball
ellisbhastroud 3:a8960004d261 105
ellisbhastroud 12:7f7fadb5c106 106 if(map[i].wall == LEFT) {
ellisbhastroud 12:7f7fadb5c106 107 left_bounce(map[i].start,map[i].end);
ellisbhastroud 8:d410856c6d04 108 }
ellisbhastroud 8:d410856c6d04 109 else if(map[i].wall == RIGHT) {
ellisbhastroud 8:d410856c6d04 110 right_bounce(map[i].start,map[i].end);
ellisbhastroud 8:d410856c6d04 111 }
ellisbhastroud 8:d410856c6d04 112 else if(map[i].wall == TOP) {
ellisbhastroud 8:d410856c6d04 113 top_bounce(map[i].start,map[i].end);
ellisbhastroud 8:d410856c6d04 114 }
ellisbhastroud 8:d410856c6d04 115 else if(map[i].wall == BOTTOM) {
ellisbhastroud 8:d410856c6d04 116 bottom_bounce(map[i].start,map[i].end);
ellisbhastroud 8:d410856c6d04 117 }
ellisbhastroud 10:9f54a6366e94 118 else if(map[i].wall == BOTTOMLEFT) {
ellisbhastroud 10:9f54a6366e94 119 bottom_left_bounce(map[i].start,map[i].end);
ellisbhastroud 10:9f54a6366e94 120 }
ellisbhastroud 10:9f54a6366e94 121 else if(map[i].wall == BOTTOMRIGHT) {
ellisbhastroud 10:9f54a6366e94 122 bottom_right_bounce(map[i].start,map[i].end);
ellisbhastroud 10:9f54a6366e94 123 }
ellisbhastroud 10:9f54a6366e94 124 else if(map[i].wall == TOPLEFT) {
ellisbhastroud 10:9f54a6366e94 125 top_left_bounce(map[i].start,map[i].end);
ellisbhastroud 10:9f54a6366e94 126 }
ellisbhastroud 10:9f54a6366e94 127 else if(map[i].wall == TOPRIGHT) {
ellisbhastroud 10:9f54a6366e94 128 top_right_bounce(map[i].start,map[i].end);
ellisbhastroud 10:9f54a6366e94 129 }
ellisbhastroud 8:d410856c6d04 130 }
ellisbhastroud 3:a8960004d261 131 }
ellisbhastroud 5:0b31909caf7f 132
ellisbhastroud 10:9f54a6366e94 133 void Ball::set_frame_rate(int frame_rate)
ellisbhastroud 10:9f54a6366e94 134 {
ellisbhastroud 10:9f54a6366e94 135 _frame_rate = frame_rate;
ellisbhastroud 10:9f54a6366e94 136 }
ellisbhastroud 12:7f7fadb5c106 137
ellisbhastroud 14:08ac9aaa34c3 138 bool Ball::get_bounce_flag()
ellisbhastroud 14:08ac9aaa34c3 139 {
ellisbhastroud 14:08ac9aaa34c3 140 return _bounce_flag;
ellisbhastroud 14:08ac9aaa34c3 141 }
ellisbhastroud 14:08ac9aaa34c3 142
ellisbhastroud 14:08ac9aaa34c3 143 void Ball::reset_bounce_flag()
ellisbhastroud 14:08ac9aaa34c3 144 {
ellisbhastroud 14:08ac9aaa34c3 145 _bounce_flag = false;
ellisbhastroud 14:08ac9aaa34c3 146 }
ellisbhastroud 14:08ac9aaa34c3 147
ellisbhastroud 3:a8960004d261 148 //private methods
ellisbhastroud 3:a8960004d261 149
ellisbhastroud 12:7f7fadb5c106 150 void Ball::left_bounce(Coord start, Coord end) //check for left wall collision
ellisbhastroud 12:7f7fadb5c106 151 {
ellisbhastroud 12:7f7fadb5c106 152 if(_x_pos + _x_vel*10.0f/_frame_rate - 1 < start.x && _x_pos + _x_vel*10.0f/_frame_rate > start.x - 5 && _y_pos >= start.y && _y_pos + 1 <= end.y && _x_vel < 0){
ellisbhastroud 12:7f7fadb5c106 153 _x_pos = start.x + 1;
ellisbhastroud 12:7f7fadb5c106 154 _x_vel = -_x_vel;
ellisbhastroud 14:08ac9aaa34c3 155 _bounce_flag = true;
ellisbhastroud 12:7f7fadb5c106 156 }
ellisbhastroud 12:7f7fadb5c106 157 }
ellisbhastroud 12:7f7fadb5c106 158
ellisbhastroud 12:7f7fadb5c106 159 void Ball::right_bounce(Coord start, Coord end) //check for right wall collision
ellisbhastroud 12:7f7fadb5c106 160 {
ellisbhastroud 12:7f7fadb5c106 161 if(_x_pos + _x_vel*10.0f/_frame_rate + 2 > start.x && _x_pos + _x_vel*10.0f/_frame_rate < start.x + 5 && _y_pos >= start.y && _y_pos + 1 <= end.y && _x_vel > 0){ //right wall x + 1
ellisbhastroud 12:7f7fadb5c106 162 _x_pos = start.x - 1;
ellisbhastroud 12:7f7fadb5c106 163 _x_vel = -_x_vel;
ellisbhastroud 14:08ac9aaa34c3 164 _bounce_flag = true;
ellisbhastroud 12:7f7fadb5c106 165 }
ellisbhastroud 12:7f7fadb5c106 166 }
ellisbhastroud 12:7f7fadb5c106 167
ellisbhastroud 12:7f7fadb5c106 168 void Ball::top_bounce(Coord start, Coord end) //check for top wall collision
ellisbhastroud 12:7f7fadb5c106 169 {
ellisbhastroud 12:7f7fadb5c106 170 if(_y_pos + _y_vel*10.0f/_frame_rate - 1 < start.y && _y_pos + _y_vel*10.0f/_frame_rate > start.y - 5 && _x_pos >= start.x && _x_pos + 1 <= end.x && _y_vel < 0){ //top wall y -1
ellisbhastroud 12:7f7fadb5c106 171 _y_pos = start.y + 1;
ellisbhastroud 12:7f7fadb5c106 172 _y_vel = -_y_vel;
ellisbhastroud 14:08ac9aaa34c3 173 _bounce_flag = true;
ellisbhastroud 12:7f7fadb5c106 174 }
ellisbhastroud 12:7f7fadb5c106 175 }
ellisbhastroud 12:7f7fadb5c106 176
ellisbhastroud 12:7f7fadb5c106 177 void Ball::bottom_bounce(Coord start, Coord end) //check for bottom wall collision
ellisbhastroud 12:7f7fadb5c106 178 {
ellisbhastroud 12:7f7fadb5c106 179 if(_y_pos + _y_vel*10.0f/_frame_rate + 2 > start.y && _y_pos + _y_vel*10.0f/_frame_rate < start.y + 5 && _x_pos >= start.x && _x_pos + 1 <= end.x && _y_vel > 0){ //bottom wall
ellisbhastroud 12:7f7fadb5c106 180 _y_pos = start.y - 1;
ellisbhastroud 12:7f7fadb5c106 181 _y_vel = -_y_vel;
ellisbhastroud 14:08ac9aaa34c3 182 _bounce_flag = true;
ellisbhastroud 12:7f7fadb5c106 183 }
ellisbhastroud 12:7f7fadb5c106 184 }
ellisbhastroud 12:7f7fadb5c106 185
ellisbhastroud 12:7f7fadb5c106 186 void Ball::bottom_left_bounce(Coord start, Coord end) //check for bottom left wall collision
ellisbhastroud 12:7f7fadb5c106 187 {
ellisbhastroud 14:08ac9aaa34c3 188 if((_y_pos + _y_vel*10.0f/_frame_rate + 1) > (_x_pos + _x_vel*10.0f/_frame_rate - 1) + (start.y-start.x) && //bottom left bounce conditions
ellisbhastroud 14:08ac9aaa34c3 189 (_x_pos + _x_vel*10.0f/_frame_rate - 1) >= start.x && (_x_pos + _x_vel*10.0f/_frame_rate - 1) <= end.x &&
ellisbhastroud 14:08ac9aaa34c3 190 (_y_pos + _y_vel*10.0f/_frame_rate + 1) >= start.y && (_y_pos + _y_vel*10.0f/_frame_rate + 1) <= end.y ) {
ellisbhastroud 12:7f7fadb5c106 191 swap(_x_vel, _y_vel); //reflects from wall with velocity directions swapped
ellisbhastroud 14:08ac9aaa34c3 192 _bounce_flag = true;
ellisbhastroud 12:7f7fadb5c106 193 }
ellisbhastroud 12:7f7fadb5c106 194 }
ellisbhastroud 12:7f7fadb5c106 195
ellisbhastroud 12:7f7fadb5c106 196 void Ball::bottom_right_bounce(Coord start, Coord end) //check for bottom right wall collision
ellisbhastroud 12:7f7fadb5c106 197 {
ellisbhastroud 14:08ac9aaa34c3 198 if((_x_pos + _x_vel*10.0f/_frame_rate + 1) > -(_y_pos + _y_vel*10.0f/_frame_rate + 1) + (start.x+start.y) //bottom right bounce conditions
ellisbhastroud 12:7f7fadb5c106 199 && (_x_pos + _x_vel*10.0f/_frame_rate + 1) >= start.x && (_x_pos + _x_vel*10.0f/_frame_rate + 1) <= end.x
ellisbhastroud 12:7f7fadb5c106 200 && (_y_pos + _y_vel*10.0f/_frame_rate + 1) >= end.y && (_y_pos + _y_vel*10.0f/_frame_rate + 1) <= start.y) {
ellisbhastroud 12:7f7fadb5c106 201
ellisbhastroud 12:7f7fadb5c106 202 _x_vel = -_x_vel; //negative wall
ellisbhastroud 12:7f7fadb5c106 203 _y_vel = -_y_vel;
ellisbhastroud 12:7f7fadb5c106 204 swap(_x_vel, _y_vel); //reflects from wall with velocity directions swapped
ellisbhastroud 14:08ac9aaa34c3 205 _bounce_flag = true;
ellisbhastroud 12:7f7fadb5c106 206 }
ellisbhastroud 12:7f7fadb5c106 207 }
ellisbhastroud 12:7f7fadb5c106 208
ellisbhastroud 12:7f7fadb5c106 209 void Ball::top_left_bounce(Coord start, Coord end) //check for top left wall collision
ellisbhastroud 12:7f7fadb5c106 210 {
ellisbhastroud 14:08ac9aaa34c3 211 if((_x_pos + _x_vel*10.0f/_frame_rate - 1) < -(_y_pos + _y_vel*10.0f/_frame_rate + 1) + (start.x+start.y) //top left bounce conditions
ellisbhastroud 12:7f7fadb5c106 212 && (_x_pos + _x_vel*10.0f/_frame_rate - 1) >= start.x && (_x_pos + _x_vel*10.0f/_frame_rate - 1) <= end.x
ellisbhastroud 12:7f7fadb5c106 213 && (_y_pos + _y_vel*10.0f/_frame_rate + 1) >= end.y && (_y_pos + _y_vel*10.0f/_frame_rate + 1) <= start.y) {
ellisbhastroud 12:7f7fadb5c106 214
ellisbhastroud 12:7f7fadb5c106 215 _x_vel = -_x_vel; //negative wall
ellisbhastroud 12:7f7fadb5c106 216 _y_vel = -_y_vel;
ellisbhastroud 12:7f7fadb5c106 217 swap(_x_vel, _y_vel); //reflects from wall with velocity directions swapped
ellisbhastroud 14:08ac9aaa34c3 218 _bounce_flag = true;
ellisbhastroud 12:7f7fadb5c106 219 }
ellisbhastroud 12:7f7fadb5c106 220 }
ellisbhastroud 12:7f7fadb5c106 221
ellisbhastroud 12:7f7fadb5c106 222 void Ball::top_right_bounce(Coord start, Coord end) //check for top right wall collision
ellisbhastroud 12:7f7fadb5c106 223 {
ellisbhastroud 14:08ac9aaa34c3 224 if((_y_pos + _y_vel*10.0f/_frame_rate - 1) < (_x_pos + _x_vel*10.0f/_frame_rate + 1) + (start.y-start.x) //top right bounce conditions
ellisbhastroud 12:7f7fadb5c106 225 && (_x_pos + _x_vel*10.0f/_frame_rate + 1) >= start.x && (_x_pos + _x_vel*10.0f/_frame_rate + 1) <= end.x
ellisbhastroud 12:7f7fadb5c106 226 && (_y_pos + _y_vel*10.0f/_frame_rate - 1) >= start.y && (_y_pos + _y_vel*10.0f/_frame_rate - 1) <= end.y) {
ellisbhastroud 12:7f7fadb5c106 227
ellisbhastroud 12:7f7fadb5c106 228 swap(_x_vel, _y_vel); //reflects from wall with velocity directions swapped
ellisbhastroud 14:08ac9aaa34c3 229 _bounce_flag = true;
ellisbhastroud 12:7f7fadb5c106 230 }
ellisbhastroud 12:7f7fadb5c106 231 }