ELEC2645 (2019/20) / ELEC2645_Project_el18s2g
Committer:
Lycaon13
Date:
Fri May 22 09:26:11 2020 +0000
Revision:
1:aa6940176074
Parent:
0:0172de3db301
writing game logic

Who changed what in which revision?

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