Linyan Shi
/
cn17lys
N5110
PongEngine/PongEngine.cpp@0:90b7f20b3a8d, 2020-04-28 (annotated)
- Committer:
- aileen
- Date:
- Tue Apr 28 01:39:30 2020 +0000
- Revision:
- 0:90b7f20b3a8d
N5110
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
aileen | 0:90b7f20b3a8d | 1 | #include "PongEngine.h" |
aileen | 0:90b7f20b3a8d | 2 | |
aileen | 0:90b7f20b3a8d | 3 | PongEngine::PongEngine() |
aileen | 0:90b7f20b3a8d | 4 | { |
aileen | 0:90b7f20b3a8d | 5 | |
aileen | 0:90b7f20b3a8d | 6 | } |
aileen | 0:90b7f20b3a8d | 7 | |
aileen | 0:90b7f20b3a8d | 8 | PongEngine::~PongEngine() |
aileen | 0:90b7f20b3a8d | 9 | { |
aileen | 0:90b7f20b3a8d | 10 | |
aileen | 0:90b7f20b3a8d | 11 | } |
aileen | 0:90b7f20b3a8d | 12 | |
aileen | 0:90b7f20b3a8d | 13 | void PongEngine::init(int paddle_width,int paddle_height,int ball_size,int speed) |
aileen | 0:90b7f20b3a8d | 14 | { |
aileen | 0:90b7f20b3a8d | 15 | // initialise the game parameters |
aileen | 0:90b7f20b3a8d | 16 | _paddle_width = paddle_width; |
aileen | 0:90b7f20b3a8d | 17 | _paddle_height = paddle_height; |
aileen | 0:90b7f20b3a8d | 18 | _ball_size = ball_size; |
aileen | 0:90b7f20b3a8d | 19 | _speed = speed; |
aileen | 0:90b7f20b3a8d | 20 | |
aileen | 0:90b7f20b3a8d | 21 | // x position on screen - WIDTH is defined in N5110.h |
aileen | 0:90b7f20b3a8d | 22 | _p1x = GAP; |
aileen | 0:90b7f20b3a8d | 23 | _p2x = WIDTH - GAP - _paddle_width; |
aileen | 0:90b7f20b3a8d | 24 | |
aileen | 0:90b7f20b3a8d | 25 | // puts paddles and ball in middle |
aileen | 0:90b7f20b3a8d | 26 | _p1.init(_p1x,_paddle_height,_paddle_width); |
aileen | 0:90b7f20b3a8d | 27 | _p2.init(_p2x,_paddle_height,_paddle_width); |
aileen | 0:90b7f20b3a8d | 28 | _ball.init(_ball_size,_speed); |
aileen | 0:90b7f20b3a8d | 29 | } |
aileen | 0:90b7f20b3a8d | 30 | |
aileen | 0:90b7f20b3a8d | 31 | void PongEngine::read_input(Gamepad &pad) |
aileen | 0:90b7f20b3a8d | 32 | { |
aileen | 0:90b7f20b3a8d | 33 | _d = pad.get_direction(); |
aileen | 0:90b7f20b3a8d | 34 | _mag = pad.get_mag(); |
aileen | 0:90b7f20b3a8d | 35 | } |
aileen | 0:90b7f20b3a8d | 36 | |
aileen | 0:90b7f20b3a8d | 37 | void PongEngine::draw(N5110 &lcd) |
aileen | 0:90b7f20b3a8d | 38 | { |
aileen | 0:90b7f20b3a8d | 39 | // draw the elements in the LCD buffer |
aileen | 0:90b7f20b3a8d | 40 | // pitch |
aileen | 0:90b7f20b3a8d | 41 | lcd.drawRect(0,0,WIDTH,HEIGHT,FILL_TRANSPARENT); |
aileen | 0:90b7f20b3a8d | 42 | lcd.drawLine(WIDTH/2,0,WIDTH/2,HEIGHT-1,2); |
aileen | 0:90b7f20b3a8d | 43 | //score |
aileen | 0:90b7f20b3a8d | 44 | print_scores(lcd); |
aileen | 0:90b7f20b3a8d | 45 | // paddles |
aileen | 0:90b7f20b3a8d | 46 | _p1.draw(lcd); |
aileen | 0:90b7f20b3a8d | 47 | _p2.draw(lcd); |
aileen | 0:90b7f20b3a8d | 48 | // ball |
aileen | 0:90b7f20b3a8d | 49 | _ball.draw(lcd); |
aileen | 0:90b7f20b3a8d | 50 | } |
aileen | 0:90b7f20b3a8d | 51 | |
aileen | 0:90b7f20b3a8d | 52 | void PongEngine::update(Gamepad &pad) |
aileen | 0:90b7f20b3a8d | 53 | { |
aileen | 0:90b7f20b3a8d | 54 | check_goal(pad); |
aileen | 0:90b7f20b3a8d | 55 | // important to update paddles and ball before checking collisions so can |
aileen | 0:90b7f20b3a8d | 56 | // correct for it before updating the display |
aileen | 0:90b7f20b3a8d | 57 | _p1.update(_d,_mag); |
aileen | 0:90b7f20b3a8d | 58 | _p2.update(_d,_mag); |
aileen | 0:90b7f20b3a8d | 59 | _ball.update(); |
aileen | 0:90b7f20b3a8d | 60 | |
aileen | 0:90b7f20b3a8d | 61 | check_wall_collision(pad); |
aileen | 0:90b7f20b3a8d | 62 | check_paddle_collisions(pad); |
aileen | 0:90b7f20b3a8d | 63 | } |
aileen | 0:90b7f20b3a8d | 64 | |
aileen | 0:90b7f20b3a8d | 65 | void PongEngine::check_wall_collision(Gamepad &pad) |
aileen | 0:90b7f20b3a8d | 66 | { |
aileen | 0:90b7f20b3a8d | 67 | // read current ball attributes |
aileen | 0:90b7f20b3a8d | 68 | Vector2D ball_pos = _ball.get_pos(); |
aileen | 0:90b7f20b3a8d | 69 | Vector2D ball_velocity = _ball.get_velocity(); |
aileen | 0:90b7f20b3a8d | 70 | |
aileen | 0:90b7f20b3a8d | 71 | // check if hit top wall |
aileen | 0:90b7f20b3a8d | 72 | if (ball_pos.y <= 1) { // 1 due to 1 pixel boundary |
aileen | 0:90b7f20b3a8d | 73 | ball_pos.y = 1; // bounce off ceiling without going off screen |
aileen | 0:90b7f20b3a8d | 74 | ball_velocity.y = -ball_velocity.y; |
aileen | 0:90b7f20b3a8d | 75 | // audio feedback |
aileen | 0:90b7f20b3a8d | 76 | pad.tone(750.0,0.1); |
aileen | 0:90b7f20b3a8d | 77 | } |
aileen | 0:90b7f20b3a8d | 78 | // check if hit bottom wall |
aileen | 0:90b7f20b3a8d | 79 | else if (ball_pos.y + _ball_size >= (HEIGHT-1) ) { // bottom pixel is 47 |
aileen | 0:90b7f20b3a8d | 80 | // hit bottom |
aileen | 0:90b7f20b3a8d | 81 | ball_pos.y = (HEIGHT-1) - _ball_size; // stops ball going off screen |
aileen | 0:90b7f20b3a8d | 82 | ball_velocity.y = -ball_velocity.y; |
aileen | 0:90b7f20b3a8d | 83 | // audio feedback |
aileen | 0:90b7f20b3a8d | 84 | pad.tone(750.0,0.1); |
aileen | 0:90b7f20b3a8d | 85 | } |
aileen | 0:90b7f20b3a8d | 86 | |
aileen | 0:90b7f20b3a8d | 87 | // update ball parameters |
aileen | 0:90b7f20b3a8d | 88 | _ball.set_velocity(ball_velocity); |
aileen | 0:90b7f20b3a8d | 89 | _ball.set_pos(ball_pos); |
aileen | 0:90b7f20b3a8d | 90 | } |
aileen | 0:90b7f20b3a8d | 91 | |
aileen | 0:90b7f20b3a8d | 92 | void PongEngine::check_paddle_collisions(Gamepad &pad) |
aileen | 0:90b7f20b3a8d | 93 | { |
aileen | 0:90b7f20b3a8d | 94 | // read current ball attributes |
aileen | 0:90b7f20b3a8d | 95 | Vector2D ball_pos = _ball.get_pos(); |
aileen | 0:90b7f20b3a8d | 96 | Vector2D ball_velocity = _ball.get_velocity(); |
aileen | 0:90b7f20b3a8d | 97 | |
aileen | 0:90b7f20b3a8d | 98 | // check p1 first |
aileen | 0:90b7f20b3a8d | 99 | Vector2D p1_pos = _p1.get_pos(); |
aileen | 0:90b7f20b3a8d | 100 | |
aileen | 0:90b7f20b3a8d | 101 | // see if ball has hit the paddle by checking for overlaps |
aileen | 0:90b7f20b3a8d | 102 | if ( |
aileen | 0:90b7f20b3a8d | 103 | (ball_pos.y >= p1_pos.y) && //top |
aileen | 0:90b7f20b3a8d | 104 | (ball_pos.y <= p1_pos.y + _paddle_height) && //bottom |
aileen | 0:90b7f20b3a8d | 105 | (ball_pos.x >= _p1x) && //left |
aileen | 0:90b7f20b3a8d | 106 | (ball_pos.x <= _p1x + _paddle_width) //right |
aileen | 0:90b7f20b3a8d | 107 | ) { |
aileen | 0:90b7f20b3a8d | 108 | // if it has, fix position and reflect x velocity |
aileen | 0:90b7f20b3a8d | 109 | ball_pos.x = _p1x + _paddle_width; |
aileen | 0:90b7f20b3a8d | 110 | ball_velocity.x = -ball_velocity.x; |
aileen | 0:90b7f20b3a8d | 111 | // audio feedback |
aileen | 0:90b7f20b3a8d | 112 | pad.tone(1000.0,0.1); |
aileen | 0:90b7f20b3a8d | 113 | } |
aileen | 0:90b7f20b3a8d | 114 | |
aileen | 0:90b7f20b3a8d | 115 | // check p2 next |
aileen | 0:90b7f20b3a8d | 116 | Vector2D p2_pos = _p2.get_pos(); |
aileen | 0:90b7f20b3a8d | 117 | |
aileen | 0:90b7f20b3a8d | 118 | // see if ball has hit the paddle by checking for overlaps |
aileen | 0:90b7f20b3a8d | 119 | if ( |
aileen | 0:90b7f20b3a8d | 120 | (ball_pos.y >= p2_pos.y) && //top |
aileen | 0:90b7f20b3a8d | 121 | (ball_pos.y <= p2_pos.y + _paddle_height) && //bottom |
aileen | 0:90b7f20b3a8d | 122 | (ball_pos.x + _ball_size >= _p2x) && //left |
aileen | 0:90b7f20b3a8d | 123 | (ball_pos.x + _ball_size <= _p2x + _paddle_width) //right |
aileen | 0:90b7f20b3a8d | 124 | ) { |
aileen | 0:90b7f20b3a8d | 125 | // if it has, fix position and reflect x velocity |
aileen | 0:90b7f20b3a8d | 126 | ball_pos.x = _p2x - _ball_size; |
aileen | 0:90b7f20b3a8d | 127 | ball_velocity.x = -ball_velocity.x; |
aileen | 0:90b7f20b3a8d | 128 | // audio feedback |
aileen | 0:90b7f20b3a8d | 129 | pad.tone(1000.0,0.1); |
aileen | 0:90b7f20b3a8d | 130 | } |
aileen | 0:90b7f20b3a8d | 131 | |
aileen | 0:90b7f20b3a8d | 132 | // write new attributes |
aileen | 0:90b7f20b3a8d | 133 | _ball.set_velocity(ball_velocity); |
aileen | 0:90b7f20b3a8d | 134 | _ball.set_pos(ball_pos); |
aileen | 0:90b7f20b3a8d | 135 | } |
aileen | 0:90b7f20b3a8d | 136 | |
aileen | 0:90b7f20b3a8d | 137 | void PongEngine::check_goal(Gamepad &pad) |
aileen | 0:90b7f20b3a8d | 138 | { |
aileen | 0:90b7f20b3a8d | 139 | Vector2D ball_pos = _ball.get_pos(); |
aileen | 0:90b7f20b3a8d | 140 | // P2 has scored |
aileen | 0:90b7f20b3a8d | 141 | if (ball_pos.x + _ball_size < 0) { |
aileen | 0:90b7f20b3a8d | 142 | _p2.add_score(); |
aileen | 0:90b7f20b3a8d | 143 | _ball.init(_ball_size,_speed); |
aileen | 0:90b7f20b3a8d | 144 | pad.tone(1500.0,0.5); |
aileen | 0:90b7f20b3a8d | 145 | pad.leds_on(); |
aileen | 0:90b7f20b3a8d | 146 | wait(0.5); |
aileen | 0:90b7f20b3a8d | 147 | pad.leds_off(); |
aileen | 0:90b7f20b3a8d | 148 | } |
aileen | 0:90b7f20b3a8d | 149 | |
aileen | 0:90b7f20b3a8d | 150 | // P1 has scored |
aileen | 0:90b7f20b3a8d | 151 | if (ball_pos.x > WIDTH) { |
aileen | 0:90b7f20b3a8d | 152 | _p1.add_score(); |
aileen | 0:90b7f20b3a8d | 153 | _ball.init(_ball_size,_speed); |
aileen | 0:90b7f20b3a8d | 154 | pad.tone(1500.0,0.5); |
aileen | 0:90b7f20b3a8d | 155 | pad.leds_on(); |
aileen | 0:90b7f20b3a8d | 156 | wait(0.5); |
aileen | 0:90b7f20b3a8d | 157 | pad.leds_off(); |
aileen | 0:90b7f20b3a8d | 158 | } |
aileen | 0:90b7f20b3a8d | 159 | } |
aileen | 0:90b7f20b3a8d | 160 | |
aileen | 0:90b7f20b3a8d | 161 | void PongEngine::print_scores(N5110 &lcd) |
aileen | 0:90b7f20b3a8d | 162 | { |
aileen | 0:90b7f20b3a8d | 163 | // get scores from paddles |
aileen | 0:90b7f20b3a8d | 164 | int p1_score = _p1.get_score(); |
aileen | 0:90b7f20b3a8d | 165 | int p2_score = _p2.get_score(); |
aileen | 0:90b7f20b3a8d | 166 | |
aileen | 0:90b7f20b3a8d | 167 | // print to LCD i |
aileen | 0:90b7f20b3a8d | 168 | char buffer1[14]; |
aileen | 0:90b7f20b3a8d | 169 | sprintf(buffer1,"%2d",p1_score); |
aileen | 0:90b7f20b3a8d | 170 | lcd.printString(buffer1,WIDTH/2 - 20,1); // font is 8 wide, so leave 4 pixel gape from middle assuming two digits |
aileen | 0:90b7f20b3a8d | 171 | char buffer2[14]; |
aileen | 0:90b7f20b3a8d | 172 | sprintf(buffer2,"%2d",p2_score); |
aileen | 0:90b7f20b3a8d | 173 | lcd.printString(buffer2,WIDTH/2 + 4,1); |
aileen | 0:90b7f20b3a8d | 174 | } |