N5110

Dependencies:   mbed

Committer:
aileen
Date:
Tue Apr 28 01:39:30 2020 +0000
Revision:
0:90b7f20b3a8d
N5110

Who changed what in which revision?

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