Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: mbed
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
Generated on Wed Jul 20 2022 02:14:09 by
1.7.2