ELEC2645 (2019/20) / Mbed 2 deprecated ELEC2645_Project_el17oc

Dependencies:   mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers snake.cpp Source File

snake.cpp

00001 #include "snake.h"
00002 
00003 Snake::Snake()
00004 {
00005 
00006 }
00007 
00008 Snake::~Snake()
00009 {
00010 }
00011 
00012 void Snake::init()//int x, int y)
00013 {
00014     _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
00015     _x1 = 48;
00016     _x2 = 48;
00017     _x3 = 48;
00018     _x4 = 48;
00019     _x5 = 48;
00020 
00021     _y0 = 20;                           //the snakes body is in a vertical positon
00022     _y1 = 19;
00023     _y2 = 18;
00024     _y3 = 17;
00025     _y4 = 16;
00026     _y5 = 15;
00027 
00028     _apx = 48;                        //initial apple position - directly in front of snake
00029     _apy = 25;
00030     _gameover = false;                //when _gameover = true, game cannot be played
00031     _reset_apple = false;             //triggers the generation of a new apple position.
00032     _score = 0;                       //initialises score to 0
00033     _direction = down;                  //initial direction
00034     _countdown = 18;                  //initial number of moves is lower than the reset value in order to keep the number of moves low to increase difficulty
00035 }
00036 
00037 Vector2D Snake::get_Snakehead()
00038 {
00039     Vector2D Snakehead;             //defines Snakehead as a Vector
00040     Snakehead.x = _x0;              //returns _x0, _y0 values
00041     Snakehead.y = _y0;
00042 
00043     return Snakehead;               //Snakehead position is called and used in GameEngine::get_LEDs by calling this class
00044 
00045 }
00046 
00047 
00048 void Snake::apple_collected(N5110 &lcd, Gamepad &pad)   //checks to see whether an apple has been collected
00049 {
00050 
00051     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
00052         // if they are the same: the score increases, a new apple position is generated, the countdown timer is reset,  LEDS and Speaker are triggered
00053         _score++;                               //increases score
00054         _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
00055         _countdown = _countdown + 25;          //38 is added to the current countdown timer - this larger _countdown is, the further the snake can travel to collect apples.
00056         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
00057         pad.led(2, 1);                         //toggles middle left led on
00058         pad.led(4, 1);                          //toggles middle right led on
00059         wait(0.1);
00060         pad.led(2, 0);
00061         pad.led(4, 0);
00062 
00063 
00064 
00065     } else {
00066         _countdown = _countdown - 1;           //for each change in position, counter decreases by 1 - the counter represents how many moves you have to collect an apple
00067 
00068     }
00069 }
00070 
00071 int Snake::get_countdown()
00072 {
00073     //allows _countdown value to be called from other classes
00074     return _countdown;
00075 }
00076 
00077 
00078 void Snake::check_gameover(N5110 &lcd)
00079 {
00080     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
00081         //the second condition for, game over = true, is if the snake head cooroinate is equal to one of the snake body bits coordinate
00082         _gameover = true;                                   // the third conditios is game is over if the counter = 0, indicating you've ran out of moves.
00083     }
00084     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)) {
00085         _gameover = true;
00086     }
00087     if(_countdown == 0) {
00088         _gameover = true;
00089 
00090     }
00091 }
00092 
00093 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
00094 {
00095     lcd.clear();                                    //clears the lcd before assigning what is to be printed
00096 
00097     // plot the apple
00098     lcd.setPixel(_apx, _apy,1);                     //plot apple position -whether it is a new position or the same position
00099 
00100     //plot the border
00101     lcd.drawRect(15, 0, 54, 32, FILL_TRANSPARENT);  //plots border of snake map
00102 
00103     //plot the snake
00104     lcd.setPixel(_x0, _y0,1);                       //plots snake body's new position changed by move_snake() function
00105     lcd.setPixel(_x1, _y1,1);
00106     lcd.setPixel(_x2, _y2,1);
00107     lcd.setPixel(_x3, _y3,1);
00108     lcd.setPixel(_x4, _y4,1);
00109     lcd.setPixel(_x5, _y5,1);
00110     lcd.setPixel(_x6, _y6,1);
00111     lcd.setPixel(_x7, _y7,1);                        //new position of the end bit of the snake is plotted here
00112     // _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
00113 
00114 
00115     char buffer1[14];
00116     sprintf(buffer1,"   %2d   %2d",_score, _countdown);
00117     lcd.printString(buffer1,0,5);
00118 
00119     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
00120         lcd.clear();                                            //
00121 
00122         pad.led(1,1);
00123         pad.led(4,1);
00124         lcd.printString( "  Game Over  ", 0, 1 );               //prints game over message
00125         lcd.printString( " ~~~~~~~<:>-<", 0, 3 );               // prints symbolic snake
00126         char buffer1[14];
00127         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
00128         lcd.printString(buffer1,0,4);                                   ///print score
00129 
00130 
00131     }
00132 
00133 //   char buffer2[14];
00134     // sprintf(buffer2,"%2d",_score);
00135     // lcd.printString(buffer2,0,3);
00136 
00137     lcd.refresh();                                       //updates the lcd display according to the code in this function
00138 }
00139 
00140 
00141 
00142 
00143 
00144 void Snake::get_direction(Gamepad &pad)  //gets the direction based on the input of the gamepad
00145 {
00146     // int x;                            // int x was used as a variable to test whether the button were generating the correct output
00147     Directions direction = _direction;   //"direction" stores the previous value of _direction to stop the snake going in the opposite direction to the way its travelling
00148 
00149     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
00150         if (pad.A_pressed()) {
00151 
00152             _direction = right;         //the snake direction is stored in _direction so on the next loop direction = right
00153             //       x=1;
00154         }
00155     }
00156     if(direction != right) {
00157         if (pad.Y_pressed()) {
00158 
00159             _direction = left;
00160             //      x=2;
00161         }
00162 
00163     }
00164     if(direction != up) {
00165         if (pad.B_pressed()) {
00166             //       x=3;
00167             _direction = down;
00168         }
00169     }
00170     if(direction != down) {
00171         if (pad.X_pressed()) {
00172 
00173             _direction = up;
00174             //       x=4;
00175         }
00176     } else {
00177         _direction = _direction;            // setting the direction equal to itself if no button is pressed means the snake will move automatically once direction is set
00178 
00179     }
00180     //  printf("direction %d ", x);        //printf statements used in CoolTerm to check whether the input commands where working correctly
00181 }
00182 
00183 
00184 
00185 void Snake::move_snake()           //assigns the new values of the snake position
00186 {
00187     if (_direction == down) {       //shifting the snake position bit by bit, with respect to _x0 and _y0;
00188         _x7 = _x6;                //coordinate _x[i], _y[i] = _x[i-1], _y[i-1]
00189         _y7 = _y6;
00190         _x6 = _x5;
00191         _y6 = _y5;
00192         _x5 = _x4;
00193         _y5 = _y4;
00194         _x4 = _x3;
00195         _y4 = _y3;
00196         _x3 = _x2;
00197         _y3 = _y2;
00198         _x2 = _x1;
00199         _y2 = _y1;
00200         _x1 = _x0;
00201         _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
00202 
00203         _x0 = _x0;
00204         _y0 = _y0 + 1;          //changes the position one bit at a time so the snake can only move horizontally or vertically
00205     }
00206     if (_direction == up) {
00207         _x7 = _x6;
00208         _y7 = _y6;
00209         _x6 = _x5;
00210         _y6 = _y5;
00211         _x5 = _x4;
00212         _y5 = _y4;
00213         _x4 = _x3;
00214         _y4 = _y3;
00215         _x3 = _x2;
00216         _y3 = _y2;
00217         _x2 = _x1;
00218         _y2 = _y1;
00219         _x1 = _x0;
00220         _y1 = _y0;
00221 
00222         _x0 = _x0;             // x remains constant
00223         _y0 = _y0 - 1;          //y decerases by 1 to move up as the y axis decreases from top to bottom
00224 
00225     }
00226     if (_direction == left) {
00227         _x7 = _x6;
00228         _y7 = _y6;
00229         _x6 = _x5;
00230         _y6 = _y5;
00231         _x5 = _x4;
00232         _y5 = _y4;
00233         _x4 = _x3;
00234         _y4 = _y3;
00235         _x3 = _x2;
00236         _y3 = _y2;
00237         _x2 = _x1;
00238         _y2 = _y1;
00239         _x1 = _x0;
00240         _y1 = _y0;
00241 
00242         _x0 = _x0 - 1;       //changes x=x-1
00243         _y0 = _y0;           //y remains the same to move left
00244 
00245 
00246 
00247     }
00248 
00249     if (_direction == right) {
00250         _x7 = _x6;
00251         _y7 = _y6;
00252         _x6 = _x5;
00253         _y6 = _y5;
00254         _x5 = _x4;
00255         _y5 = _y4;
00256         _x4 = _x3;
00257         _y4 = _y3;
00258         _x3 = _x2;
00259         _y3 = _y2;
00260         _x2 = _x1;
00261         _y2 = _y1;
00262         _x1 = _x0;
00263         _y1 = _y0;
00264 
00265         _x0 = _x0 + 1;
00266         _y0 = _y0;
00267 
00268 
00269     }
00270 }
00271 
00272 
00273 void Snake::render_clear_tail(N5110 &lcd)
00274 {
00275 
00276     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
00277 }
00278 
00279 bool Snake::get_gameover()                               //methods to access member variables of the class
00280 {
00281     return _gameover;
00282 }
00283 int Snake::get_score()
00284 {
00285     return _score;
00286 }
00287 
00288 
00289 
00290 
00291 
00292 void Snake::get_Apple_position(N5110 &lcd)
00293 {
00294     if(_reset_apple == true) {      // _reset_apple is a triggered when an apple is collected and causes a new Apple position to be randomly generated
00295         _reset_apple = false;         // returned to false immediately so another position can be generated function can be triggered again in the next loop
00296         lcd.setPixel(_apx, _apy,0);     //sets the exisiting apple position to 0 to remove it from lcd.
00297         _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                                 
00298         _apy = rand()%28+2;        // the range is from 16 to 69 as the lowest x coordinate of the rectangle is 15 and the highest is 69
00299     }
00300 
00301 
00302 }
00303 
00304