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.
Engine.cpp
00001 #include "Engine.h" 00002 00003 Engine::Engine() 00004 { 00005 00006 } 00007 00008 Engine::~Engine() 00009 { 00010 00011 } 00012 00013 void Engine::init() // initialise the game parameters 00014 { 00015 00016 gameTest(); 00017 00018 _solid.init(10,15); 00019 _noodles.init(10,10); 00020 _gameOver = false; 00021 00022 printf("Engine initialised\n"); 00023 } 00024 void Engine::setLvl(int _levelToSet) 00025 { 00026 _lvl = _levelToSet; // sets the current level, this is used when the menu changes the currently selected level 00027 } 00028 00029 void Engine::loadLvl() 00030 { 00031 if (_lvl == 1) { //checks to see what level should be loaded 00032 lvlOne(); 00033 } else if (_lvl == 2) { 00034 lvlTwo(); 00035 } else if (_lvl == 3) { 00036 lvlThree(); 00037 } 00038 printf("Level Loaded\n"); 00039 } 00040 00041 void Engine::lvlOne() 00042 { 00043 memset(_grid, 0, sizeof(_grid)); //clears the grid as it is a blank level 00044 } 00045 00046 void Engine::lvlTwo() 00047 { 00048 int _newGrid[22][22] = { 00049 {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, 00050 {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, 00051 {0,0,1,1,1,1,1,1,0,0,0,0,1,1,1,1,1,1,0,0}, 00052 {0,0,1,1,1,1,1,1,0,0,0,0,1,1,1,1,1,1,0,0}, 00053 {0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0}, 00054 {0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0}, 00055 {0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0}, 00056 {0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0}, 00057 {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, 00058 {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, 00059 {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, 00060 {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, 00061 {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, 00062 {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, 00063 {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, 00064 {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, 00065 {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, 00066 {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, 00067 {0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0}, 00068 {0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0}, 00069 {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, 00070 {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0} 00071 }; 00072 00073 /* 00074 To load a set level, the level is first created as a new 2d array. It is set values for each coordinate 00075 Then the functional array has the values of _newGrid set to it individually 00076 */ 00077 for(int i = 0; i < 22; i++) { 00078 for (int j = 0; j < 22; j++) { 00079 _grid[i][j] = _newGrid[i][j]; 00080 } 00081 } 00082 } 00083 00084 void Engine::lvlThree() 00085 { 00086 int _newGrid[22][22] = { 00087 {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, 00088 {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, 00089 {0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0}, 00090 {0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,0,0,0}, 00091 {0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,0,0,0}, 00092 {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0}, 00093 {0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0}, 00094 {0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0}, 00095 {0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, 00096 {0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, 00097 {0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, 00098 {0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, 00099 {0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, 00100 {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0}, 00101 {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0}, 00102 {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0}, 00103 {0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,0,0}, 00104 {0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,0,0}, 00105 {0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,0,0}, 00106 {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, 00107 {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, 00108 {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0} 00109 }; 00110 00111 for(int i = 0; i < 22; i++) { 00112 for (int j = 0; j < 22; j++) { 00113 _grid[i][j] = _newGrid[i][j]; 00114 } 00115 } 00116 } 00117 00118 void Engine::read_input(Gamepad &pad) 00119 { 00120 _d = pad.get_direction(); //_d stores the direction that the joystick is pushed in for later use 00121 } 00122 00123 void Engine::draw(N5110 &lcd) 00124 { 00125 lcd.drawRect(0,0,48,48,FILL_TRANSPARENT); //draws a square around the 'play area' 00126 00127 for (int j = 0; j < 22; j++) { //goes through each coordinate in the grid, 00128 for (int i = 0; i < 22; i++) { 00129 if (_grid[i][j] != 0) { //checks if the current square is NOT empty 00130 lcd.drawRect((2 * i) + 2,(2 * j) + 2,2,2,FILL_BLACK); //if the above is true a 2x2 square will be drawn in the allocated location (the grid is scalled up 2x with a 2 pixel gap arround the edge) 00131 } 00132 } 00133 } 00134 00135 lcd.printString("Score",50,0); 00136 00137 00138 int _score = (_solid.getLength() - 3); //gets the score from the current snake length, it defualts to lenght 3 and increases with each food eaten. Therefor the length will allways be 3 more than the score 00139 00140 char buffer1[21]; //buffer used for changing ints to strings 00141 sprintf(buffer1,"%3d",_score); //changes _score to a 3 letter string 00142 lcd.printString(buffer1,50,1); //prints the new string in the top right of the screen 00143 } 00144 00145 void Engine::gameOverScreen(N5110 &lcd) 00146 { 00147 printf("GameOver\n"); 00148 for (int i = 0; i < 22; i++) { //covers every square of the grid 00149 for (int j = 0; j < 22; j++) { 00150 lcd.drawRect((2 * i) + 2,(2 * j) + 2,2,2,FILL_BLACK); //draws a 2x2 square ontop of whatever is drawn in the cooridnates of the grid at the current time 00151 wait(0.01); //slight delay to allow the screen to keep up 00152 lcd.refresh(); //refreshes the screen but doesn't clear it, the intention is to get an overlay effect 00153 } 00154 } 00155 } 00156 00157 void Engine::update(Gamepad &pad) 00158 { 00159 loadLvl(); //loads the level 00160 00161 _solid.update(_d); //updates the coordinates of the snake 00162 00163 checkGameOverAndSetGrid(); //checks if a game over state has been reached, if not set the new coordinates for the snake 00164 00165 _grid[_noodles.getX()][_noodles.getY()] = 2; //sets the current location of the food to the grid, stored as a 2 to differentiate it from the terrrain and tail 00166 00167 if (checkFood()) { //checks if the head has reached food 00168 00169 pad.tone(750.0,0.1); //plays a beep to signify that the snake has eaten 00170 00171 growSnake(); //grows the snake as it has eaten the food 00172 00173 bool empty = false; //makes a varible for finding an empty square 00174 00175 while (!empty) { //loops until empty square found 00176 00177 _noodles.random(); //randomise position of noodles 00178 00179 if ( _grid[_noodles.getX()][_noodles.getY()] == 0) { 00180 00181 empty = true; //stops looping when free space is found 00182 // no need to set the grid as it will put the noodles in the new location the next time 'update' is called 00183 } 00184 00185 } 00186 } 00187 } 00188 00189 void Engine::checkGameOverAndSetGrid() 00190 { 00191 00192 int _l =_solid.getLength(); //stores the length of the snake to make it easier to debug 00193 00194 for (int z = 0; z < _l; z++) { //checks the entire lenght of the snake 00195 00196 if (_solid.getX(z) > 21 || _solid.getX(z) < 0) { //checks if the x coordinate is out of bounds 00197 _gameOver = true; 00198 } else if (_solid.getY(z) > 21 || _solid.getY(z) < 0) { //checks if the y coordinate is out of bounds 00199 _gameOver = true; 00200 } 00201 00202 if (_grid[_solid.getX(z)][_solid.getY(z)] != 1) { //checks if the square the snake has moved to is clear 00203 _grid[_solid.getX(z)][_solid.getY(z)] = 1; //if so sets the current square to be occupied 00204 } else { 00205 _gameOver = true; //if not a game over state has been reached 00206 } 00207 } 00208 } 00209 00210 bool Engine::checkFood() 00211 { 00212 if (_grid[_solid.getX(0)][_solid.getY(0)] == 2) { //checks if the head has reached food 00213 return true; 00214 } else { 00215 return false; 00216 } 00217 } 00218 00219 void Engine::growSnake() 00220 { 00221 if (_solid.getLength()<484) { //checks if the snake can grow any more 00222 00223 _solid.grow(); //makes snake longer 00224 00225 } 00226 00227 //If the snake cannot grow any more the player has won the game and filled every tile with the snake, this is extremly unlikely to happen and a game over state will be reached 00228 //I feel no need to implement a victory screen due to how unlikey this is to happen 00229 } 00230 00231 float Engine::getScore() 00232 { 00233 return _score; 00234 } 00235 00236 00237 bool Engine::getGameOver() 00238 { 00239 return _gameOver; 00240 } 00241 00242 void Engine::gameTest() 00243 { 00244 printf("Testing...\n"); 00245 if (!snakeTest()) { 00246 printf("Some game tests failed!\n"); 00247 } else if (!foodTest()) { 00248 printf("Some game tests failed!\n"); 00249 } else { 00250 printf("All game tests passed!\n"); 00251 } 00252 } 00253 00254 bool Engine::snakeTest() 00255 { 00256 //checks if the grow function and initalisation works corectly 00257 00258 _solid.init(12,10); 00259 00260 bool _testState = true; 00261 00262 _solid.grow(); 00263 _solid.grow(); 00264 00265 int _testLength = _solid.getLength(); 00266 00267 if ( _testLength != 5) { //checks if the snake has grown 00268 _testState = false; 00269 } 00270 if ( _solid.getY(0) != 10) { //checks the coordiantes of each snake section to check they are in the correct place 00271 _testState = false; 00272 } 00273 if ( _solid.getX(0) != 12) { 00274 _testState = false; 00275 } 00276 if ( _solid.getY(1) != 11) { 00277 _testState = false; 00278 } 00279 if ( _solid.getX(1) != 12) { 00280 _testState = false; 00281 } 00282 if ( _solid.getY(2) != 12) { 00283 _testState = false; 00284 } 00285 if ( _solid.getX(2) != 12) { 00286 _testState = false; 00287 } 00288 00289 return _testState; 00290 00291 } 00292 00293 bool Engine::foodTest() 00294 { 00295 //checks if the radomise function works correctly for the food 00296 00297 bool _testState = true; 00298 00299 _noodles.init(7,3); 00300 00301 _grid[_noodles.getX()][_noodles.getY()] = 2; //sets the grid value so that the randomise loop will work correctly 00302 00303 00304 00305 bool empty = false; //makes a varible for finding an empty square 00306 00307 while (!empty) { //loops until empty square found 00308 00309 _noodles.random(); //randomise position of noodles 00310 00311 if ( _grid[_noodles.getX()][_noodles.getY()] == 0) { 00312 00313 empty = true; //stops looping when free space is found 00314 // no need to set the grid as it will put the noodles in the new location the next time 'update' is called 00315 } 00316 00317 } 00318 00319 00320 if (_noodles.getX() ==7 && _noodles.getY() == 3) { //checks to see if randomised correctly 00321 _testState = false; //fail 00322 } 00323 00324 return _testState; 00325 }
Generated on Sun Jul 17 2022 04:24:16 by
1.7.2