Owen Cavender 201159294

Dependencies:   mbed Gamepad2

Committer:
el17oc
Date:
Sat May 30 20:20:10 2020 +0000
Revision:
17:eddcd4d21fd7
Parent:
16:9500059ad5d8
Final Submission. I have read and agreed with Statement of Academic Integrity

Who changed what in which revision?

UserRevisionLine numberNew contents of line
el17oc 1:897160a1a3ae 1 #include "snake.h"
el17oc 1:897160a1a3ae 2
el17oc 1:897160a1a3ae 3 Snake::Snake()
el17oc 1:897160a1a3ae 4 {
el17oc 1:897160a1a3ae 5
el17oc 1:897160a1a3ae 6 }
el17oc 1:897160a1a3ae 7
el17oc 1:897160a1a3ae 8 Snake::~Snake()
el17oc 1:897160a1a3ae 9 {
el17oc 6:bf90044188d0 10 }
el17oc 6:bf90044188d0 11
el17oc 14:7fb3c93343b6 12 void Snake::init()//int x, int y)
el17oc 6:bf90044188d0 13 {
el17oc 16:9500059ad5d8 14 _x0 = 48; //initialises each part of the snake //_x0 and _y0 is the snake's head coordinate whose position is followed by the other bits periodically
el17oc 6:bf90044188d0 15 _x1 = 48;
el17oc 6:bf90044188d0 16 _x2 = 48;
el17oc 6:bf90044188d0 17 _x3 = 48;
el17oc 12:60c856354406 18 _x4 = 48;
el17oc 12:60c856354406 19 _x5 = 48;
el17oc 6:bf90044188d0 20
el17oc 16:9500059ad5d8 21 _y0 = 20; //the snakes body is in a vertical positon
el17oc 6:bf90044188d0 22 _y1 = 19;
el17oc 6:bf90044188d0 23 _y2 = 18;
el17oc 6:bf90044188d0 24 _y3 = 17;
el17oc 12:60c856354406 25 _y4 = 16;
el17oc 12:60c856354406 26 _y5 = 15;
el17oc 14:7fb3c93343b6 27
el17oc 16:9500059ad5d8 28 _apx = 48; //initial apple position - directly in front of snake
el17oc 9:a69a6a06dddf 29 _apy = 25;
el17oc 14:7fb3c93343b6 30 _gameover = false; //when _gameover = true, game cannot be played
el17oc 16:9500059ad5d8 31 _reset_apple = false; //triggers the generation of a new apple position.
el17oc 16:9500059ad5d8 32 _score = 0; //initialises score to 0
el17oc 16:9500059ad5d8 33 _direction = down; //initial direction
el17oc 17:eddcd4d21fd7 34 _countdown = 22; //initial number of moves is lower than the reset value in order to keep the number of moves low to increase difficulty (changed it from 18 - 22 as it wasn't possible with 18 moves)
el17oc 6:bf90044188d0 35 }
el17oc 6:bf90044188d0 36
el17oc 9:a69a6a06dddf 37 Vector2D Snake::get_Snakehead()
el17oc 9:a69a6a06dddf 38 {
el17oc 16:9500059ad5d8 39 Vector2D Snakehead; //defines Snakehead as a Vector
el17oc 16:9500059ad5d8 40 Snakehead.x = _x0; //returns _x0, _y0 values
el17oc 9:a69a6a06dddf 41 Snakehead.y = _y0;
el17oc 9:a69a6a06dddf 42
el17oc 16:9500059ad5d8 43 return Snakehead; //Snakehead position is called and used in GameEngine::get_LEDs by calling this class
el17oc 9:a69a6a06dddf 44
el17oc 9:a69a6a06dddf 45 }
el17oc 9:a69a6a06dddf 46
el17oc 6:bf90044188d0 47
el17oc 16:9500059ad5d8 48 void Snake::apple_collected(N5110 &lcd, Gamepad &pad) //checks to see whether an apple has been collected
el17oc 12:60c856354406 49 {
el17oc 12:60c856354406 50
el17oc 16:9500059ad5d8 51 if((_x0 == _apx) && (_y0 == _apy)) { // directly comparing position of the apple and the Snakehead by using an and statement to see if the x and y components are equal
el17oc 16:9500059ad5d8 52 // if they are the same: the score increases, a new apple position is generated, the countdown timer is reset, LEDS and Speaker are triggered
el17oc 16:9500059ad5d8 53 _score++; //increases score
el17oc 14:7fb3c93343b6 54 _reset_apple = true; //causes new apple position to be generated - _reset _apple is compared to a bool true - when an apple is collected a new apple position is generated
el17oc 16:9500059ad5d8 55 _countdown = _countdown + 25; //38 is added to the current countdown timer - this larger _countdown is, the further the snake can travel to collect apples.
el17oc 14:7fb3c93343b6 56 pad.tone(1500.0,0.5); //if the counter is reset to just 38, there will be some distances the snake cannot as it is further than 38 pixels away - unless the player collects accumulates their available moves
el17oc 16:9500059ad5d8 57 pad.led(2, 1); //toggles middle left led on
el17oc 16:9500059ad5d8 58 pad.led(4, 1); //toggles middle right led on
el17oc 14:7fb3c93343b6 59 wait(0.1);
el17oc 14:7fb3c93343b6 60 pad.led(2, 0);
el17oc 14:7fb3c93343b6 61 pad.led(4, 0);
el17oc 12:60c856354406 62
el17oc 12:60c856354406 63
el17oc 12:60c856354406 64
el17oc 12:60c856354406 65 } else {
el17oc 16:9500059ad5d8 66 _countdown = _countdown - 1; //for each change in position, counter decreases by 1 - the counter represents how many moves you have to collect an apple
el17oc 6:bf90044188d0 67
el17oc 6:bf90044188d0 68 }
el17oc 12:60c856354406 69 }
el17oc 1:897160a1a3ae 70
el17oc 12:60c856354406 71 int Snake::get_countdown()
el17oc 12:60c856354406 72 {
el17oc 14:7fb3c93343b6 73 //allows _countdown value to be called from other classes
el17oc 12:60c856354406 74 return _countdown;
el17oc 1:897160a1a3ae 75 }
el17oc 1:897160a1a3ae 76
el17oc 1:897160a1a3ae 77
el17oc 14:7fb3c93343b6 78 void Snake::check_gameover(N5110 &lcd)
el17oc 1:897160a1a3ae 79 {
el17oc 16:9500059ad5d8 80 if (_x0 == 15 ||_x0 == 69 || _y0 == 32 || _y0 == 0) { // the first condition is, if the snakehead coordinate touches the edge of the rectangle, it is gameover
el17oc 16:9500059ad5d8 81 //the second condition for, game over = true, is if the snake head cooroinate is equal to one of the snake body bits coordinate
el17oc 14:7fb3c93343b6 82 _gameover = true; // the third conditios is game is over if the counter = 0, indicating you've ran out of moves.
el17oc 8:997f90c88246 83 }
el17oc 14:7fb3c93343b6 84 if ((_x0 == _x1 && _y0 == _y1) || (_x0 == _x2 && _y0 == _x2) || (_x0 == _x2 && _y0 == _y2) || (_x0 == _x3 && _y0 == _y3) || (_x0 == _x4 && _y0 == _y4)|| (_x0 == _x5 && _y0 == _y5)|| (_x0 == _x6 && _y0 == _y6)|| (_x0 == _x7 && _y0 == _y7)) {
el17oc 14:7fb3c93343b6 85 _gameover = true;
el17oc 14:7fb3c93343b6 86 }
el17oc 14:7fb3c93343b6 87 if(_countdown == 0) {
el17oc 14:7fb3c93343b6 88 _gameover = true;
el17oc 12:60c856354406 89
el17oc 1:897160a1a3ae 90 }
el17oc 1:897160a1a3ae 91 }
el17oc 1:897160a1a3ae 92
el17oc 16:9500059ad5d8 93 void Snake::render(N5110 &lcd, Gamepad &pad) //final function in the main function's while loop as the screen updates based on all any changes which occur in the functions
el17oc 12:60c856354406 94 {
el17oc 16:9500059ad5d8 95 lcd.clear(); //clears the lcd before assigning what is to be printed
el17oc 13:b37dde18bfdc 96
el17oc 16:9500059ad5d8 97 // plot the apple
el17oc 14:7fb3c93343b6 98 lcd.setPixel(_apx, _apy,1); //plot apple position -whether it is a new position or the same position
el17oc 12:60c856354406 99
el17oc 16:9500059ad5d8 100 //plot the border
el17oc 14:7fb3c93343b6 101 lcd.drawRect(15, 0, 54, 32, FILL_TRANSPARENT); //plots border of snake map
el17oc 14:7fb3c93343b6 102
el17oc 16:9500059ad5d8 103 //plot the snake
el17oc 14:7fb3c93343b6 104 lcd.setPixel(_x0, _y0,1); //plots snake body's new position changed by move_snake() function
el17oc 12:60c856354406 105 lcd.setPixel(_x1, _y1,1);
el17oc 12:60c856354406 106 lcd.setPixel(_x2, _y2,1);
el17oc 12:60c856354406 107 lcd.setPixel(_x3, _y3,1);
el17oc 12:60c856354406 108 lcd.setPixel(_x4, _y4,1);
el17oc 12:60c856354406 109 lcd.setPixel(_x5, _y5,1);
el17oc 14:7fb3c93343b6 110 lcd.setPixel(_x6, _y6,1);
el17oc 16:9500059ad5d8 111 lcd.setPixel(_x7, _y7,1); //new position of the end bit of the snake is plotted here
el17oc 16:9500059ad5d8 112 // _x0, _y0 old positional values are cleared previously before this function in an earlier one as otherwise the program would lose reference of that pixel when the position updates and we wouldnt be able to clear it
el17oc 16:9500059ad5d8 113
el17oc 14:7fb3c93343b6 114
el17oc 14:7fb3c93343b6 115 char buffer1[14];
el17oc 16:9500059ad5d8 116 sprintf(buffer1," %2d %2d",_score, _countdown);
el17oc 16:9500059ad5d8 117 lcd.printString(buffer1,0,5);
el17oc 16:9500059ad5d8 118
el17oc 16:9500059ad5d8 119 if (_gameover == true) { //As _gameover is a member variable, if the condition is the previous function is met, the true value will be stored in _gameover and can be accessed in this function
el17oc 16:9500059ad5d8 120 lcd.clear(); //
el17oc 14:7fb3c93343b6 121
el17oc 16:9500059ad5d8 122 pad.led(1,1);
el17oc 16:9500059ad5d8 123 pad.led(4,1);
el17oc 16:9500059ad5d8 124 lcd.printString( " Game Over ", 0, 1 ); //prints game over message
el17oc 16:9500059ad5d8 125 lcd.printString( " ~~~~~~~<:>-<", 0, 3 ); // prints symbolic snake
el17oc 16:9500059ad5d8 126 char buffer1[14];
el17oc 16:9500059ad5d8 127 sprintf(buffer1," Score: %2d", _score); //prints your score - cannot simply use N5110::printString as we need to output a value and the Number of inputs wouldnt match the function declaration
el17oc 16:9500059ad5d8 128 lcd.printString(buffer1,0,4); ///print score
el17oc 16:9500059ad5d8 129
el17oc 16:9500059ad5d8 130
el17oc 16:9500059ad5d8 131 }
el17oc 14:7fb3c93343b6 132
el17oc 14:7fb3c93343b6 133 // char buffer2[14];
el17oc 14:7fb3c93343b6 134 // sprintf(buffer2,"%2d",_score);
el17oc 16:9500059ad5d8 135 // lcd.printString(buffer2,0,3);
el17oc 14:7fb3c93343b6 136
el17oc 16:9500059ad5d8 137 lcd.refresh(); //updates the lcd display according to the code in this function
el17oc 14:7fb3c93343b6 138 }
el17oc 12:60c856354406 139
el17oc 1:897160a1a3ae 140
el17oc 1:897160a1a3ae 141
el17oc 2:44e4a6ecdbef 142
el17oc 8:997f90c88246 143
el17oc 16:9500059ad5d8 144 void Snake::get_direction(Gamepad &pad) //gets the direction based on the input of the gamepad
el17oc 6:bf90044188d0 145 {
el17oc 16:9500059ad5d8 146 // int x; // int x was used as a variable to test whether the button were generating the correct output
el17oc 14:7fb3c93343b6 147 Directions direction = _direction; //"direction" stores the previous value of _direction to stop the snake going in the opposite direction to the way its travelling
el17oc 14:7fb3c93343b6 148
el17oc 14:7fb3c93343b6 149 if(direction != left) { //if current direction is left, the not statement is false blocking access to the next command from the 'A' button preventing _direction being set to right
el17oc 6:bf90044188d0 150 if (pad.A_pressed()) {
el17oc 6:bf90044188d0 151
el17oc 16:9500059ad5d8 152 _direction = right; //the snake direction is stored in _direction so on the next loop direction = right
el17oc 14:7fb3c93343b6 153 // x=1;
el17oc 6:bf90044188d0 154 }
el17oc 6:bf90044188d0 155 }
el17oc 6:bf90044188d0 156 if(direction != right) {
el17oc 10:ee781d18e0f6 157 if (pad.Y_pressed()) {
el17oc 6:bf90044188d0 158
el17oc 6:bf90044188d0 159 _direction = left;
el17oc 14:7fb3c93343b6 160 // x=2;
el17oc 12:60c856354406 161 }
el17oc 12:60c856354406 162
el17oc 6:bf90044188d0 163 }
el17oc 16:9500059ad5d8 164 if(direction != up) {
el17oc 12:60c856354406 165 if (pad.B_pressed()) {
el17oc 14:7fb3c93343b6 166 // x=3;
el17oc 16:9500059ad5d8 167 _direction = down;
el17oc 6:bf90044188d0 168 }
el17oc 6:bf90044188d0 169 }
el17oc 16:9500059ad5d8 170 if(direction != down) {
el17oc 12:60c856354406 171 if (pad.X_pressed()) {
el17oc 6:bf90044188d0 172
el17oc 16:9500059ad5d8 173 _direction = up;
el17oc 14:7fb3c93343b6 174 // x=4;
el17oc 6:bf90044188d0 175 }
el17oc 12:60c856354406 176 } else {
el17oc 14:7fb3c93343b6 177 _direction = _direction; // setting the direction equal to itself if no button is pressed means the snake will move automatically once direction is set
el17oc 6:bf90044188d0 178
el17oc 12:60c856354406 179 }
el17oc 14:7fb3c93343b6 180 // printf("direction %d ", x); //printf statements used in CoolTerm to check whether the input commands where working correctly
el17oc 12:60c856354406 181 }
el17oc 1:897160a1a3ae 182
el17oc 5:d716013c6a18 183
el17oc 5:d716013c6a18 184
el17oc 16:9500059ad5d8 185 void Snake::move_snake() //assigns the new values of the snake position
el17oc 12:60c856354406 186 {
el17oc 16:9500059ad5d8 187 if (_direction == down) { //shifting the snake position bit by bit, with respect to _x0 and _y0;
el17oc 14:7fb3c93343b6 188 _x7 = _x6; //coordinate _x[i], _y[i] = _x[i-1], _y[i-1]
el17oc 14:7fb3c93343b6 189 _y7 = _y6;
el17oc 14:7fb3c93343b6 190 _x6 = _x5;
el17oc 14:7fb3c93343b6 191 _y6 = _y5;
el17oc 14:7fb3c93343b6 192 _x5 = _x4;
el17oc 14:7fb3c93343b6 193 _y5 = _y4;
el17oc 14:7fb3c93343b6 194 _x4 = _x3;
el17oc 14:7fb3c93343b6 195 _y4 = _y3;
el17oc 12:60c856354406 196 _x3 = _x2;
el17oc 12:60c856354406 197 _y3 = _y2;
el17oc 12:60c856354406 198 _x2 = _x1;
el17oc 12:60c856354406 199 _y2 = _y1;
el17oc 12:60c856354406 200 _x1 = _x0;
el17oc 14:7fb3c93343b6 201 _y1 = _y0; //_x1 ,_y1 and must be assingned to _x0,_y0 before its own position updates otherwise bit 0 and bit 1 would be plotted as 1 pixel
el17oc 5:d716013c6a18 202
el17oc 12:60c856354406 203 _x0 = _x0;
el17oc 14:7fb3c93343b6 204 _y0 = _y0 + 1; //changes the position one bit at a time so the snake can only move horizontally or vertically
el17oc 12:60c856354406 205 }
el17oc 16:9500059ad5d8 206 if (_direction == up) {
el17oc 14:7fb3c93343b6 207 _x7 = _x6;
el17oc 14:7fb3c93343b6 208 _y7 = _y6;
el17oc 14:7fb3c93343b6 209 _x6 = _x5;
el17oc 14:7fb3c93343b6 210 _y6 = _y5;
el17oc 12:60c856354406 211 _x5 = _x4;
el17oc 14:7fb3c93343b6 212 _y5 = _y4;
el17oc 12:60c856354406 213 _x4 = _x3;
el17oc 14:7fb3c93343b6 214 _y4 = _y3;
el17oc 12:60c856354406 215 _x3 = _x2;
el17oc 12:60c856354406 216 _y3 = _y2;
el17oc 12:60c856354406 217 _x2 = _x1;
el17oc 12:60c856354406 218 _y2 = _y1;
el17oc 12:60c856354406 219 _x1 = _x0;
el17oc 12:60c856354406 220 _y1 = _y0;
el17oc 5:d716013c6a18 221
el17oc 16:9500059ad5d8 222 _x0 = _x0; // x remains constant
el17oc 16:9500059ad5d8 223 _y0 = _y0 - 1; //y decerases by 1 to move up as the y axis decreases from top to bottom
el17oc 12:60c856354406 224
el17oc 12:60c856354406 225 }
el17oc 12:60c856354406 226 if (_direction == left) {
el17oc 14:7fb3c93343b6 227 _x7 = _x6;
el17oc 14:7fb3c93343b6 228 _y7 = _y6;
el17oc 14:7fb3c93343b6 229 _x6 = _x5;
el17oc 14:7fb3c93343b6 230 _y6 = _y5;
el17oc 13:b37dde18bfdc 231 _x5 = _x4;
el17oc 13:b37dde18bfdc 232 _y5 = _y4;
el17oc 14:7fb3c93343b6 233 _x4 = _x3;
el17oc 14:7fb3c93343b6 234 _y4 = _y3;
el17oc 12:60c856354406 235 _x3 = _x2;
el17oc 12:60c856354406 236 _y3 = _y2;
el17oc 12:60c856354406 237 _x2 = _x1;
el17oc 12:60c856354406 238 _y2 = _y1;
el17oc 12:60c856354406 239 _x1 = _x0;
el17oc 12:60c856354406 240 _y1 = _y0;
el17oc 12:60c856354406 241
el17oc 16:9500059ad5d8 242 _x0 = _x0 - 1; //changes x=x-1
el17oc 16:9500059ad5d8 243 _y0 = _y0; //y remains the same to move left
el17oc 6:bf90044188d0 244
el17oc 6:bf90044188d0 245
el17oc 5:d716013c6a18 246
el17oc 5:d716013c6a18 247 }
el17oc 6:bf90044188d0 248
el17oc 12:60c856354406 249 if (_direction == right) {
el17oc 14:7fb3c93343b6 250 _x7 = _x6;
el17oc 14:7fb3c93343b6 251 _y7 = _y6;
el17oc 14:7fb3c93343b6 252 _x6 = _x5;
el17oc 14:7fb3c93343b6 253 _y6 = _y5;
el17oc 13:b37dde18bfdc 254 _x5 = _x4;
el17oc 13:b37dde18bfdc 255 _y5 = _y4;
el17oc 14:7fb3c93343b6 256 _x4 = _x3;
el17oc 14:7fb3c93343b6 257 _y4 = _y3;
el17oc 12:60c856354406 258 _x3 = _x2;
el17oc 12:60c856354406 259 _y3 = _y2;
el17oc 12:60c856354406 260 _x2 = _x1;
el17oc 12:60c856354406 261 _y2 = _y1;
el17oc 12:60c856354406 262 _x1 = _x0;
el17oc 12:60c856354406 263 _y1 = _y0;
el17oc 12:60c856354406 264
el17oc 12:60c856354406 265 _x0 = _x0 + 1;
el17oc 12:60c856354406 266 _y0 = _y0;
el17oc 12:60c856354406 267
el17oc 12:60c856354406 268
el17oc 14:7fb3c93343b6 269 }
el17oc 12:60c856354406 270 }
el17oc 9:a69a6a06dddf 271
el17oc 6:bf90044188d0 272
el17oc 9:a69a6a06dddf 273 void Snake::render_clear_tail(N5110 &lcd)
el17oc 9:a69a6a06dddf 274 {
el17oc 12:60c856354406 275
el17oc 14:7fb3c93343b6 276 lcd.setPixel(_x7, _y7, false); //sets the end pixel to 0. it must be set to 0 before its position updates otherwise the snakebody will grow continually from _x7, _y7 coordinate
el17oc 9:a69a6a06dddf 277 }
el17oc 6:bf90044188d0 278
el17oc 14:7fb3c93343b6 279 bool Snake::get_gameover() //methods to access member variables of the class
el17oc 8:997f90c88246 280 {
el17oc 8:997f90c88246 281 return _gameover;
el17oc 8:997f90c88246 282 }
el17oc 8:997f90c88246 283 int Snake::get_score()
el17oc 8:997f90c88246 284 {
el17oc 8:997f90c88246 285 return _score;
el17oc 8:997f90c88246 286 }
el17oc 6:bf90044188d0 287
el17oc 6:bf90044188d0 288
el17oc 14:7fb3c93343b6 289
el17oc 14:7fb3c93343b6 290
el17oc 12:60c856354406 291
el17oc 8:997f90c88246 292 void Snake::get_Apple_position(N5110 &lcd)
el17oc 9:a69a6a06dddf 293 {
el17oc 14:7fb3c93343b6 294 if(_reset_apple == true) { // _reset_apple is a triggered when an apple is collected and causes a new Apple position to be randomly generated
el17oc 14:7fb3c93343b6 295 _reset_apple = false; // returned to false immediately so another position can be generated function can be triggered again in the next loop
el17oc 14:7fb3c93343b6 296 lcd.setPixel(_apx, _apy,0); //sets the exisiting apple position to 0 to remove it from lcd.
el17oc 14:7fb3c93343b6 297 _apx = rand()%52+16; //54 = width of the rectangle on the lcd. - the x value of the apple has a range of 52 so it cannot spawn in either side of the wall
el17oc 14:7fb3c93343b6 298 // the range is from 16 to 69 as the lowest x coordinate of the rectangle is 15 and the highest is 69
el17oc 14:7fb3c93343b6 299 _apy = rand()%28+2;
el17oc 14:7fb3c93343b6 300 }
el17oc 12:60c856354406 301
el17oc 6:bf90044188d0 302
el17oc 10:ee781d18e0f6 303 }
el17oc 1:897160a1a3ae 304