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/Engine.cpp
- Committer:
- Andrew_M
- Date:
- 2018-05-08
- Revision:
- 16:4d329ce7b156
- Parent:
- 15:130900e5c268
- Child:
- 17:2a909f7da973
File content as of revision 16:4d329ce7b156:
#include "Engine.h" Engine::Engine() { } Engine::~Engine() { } void Engine::init() // initialise the game parameters { gameTest(); _solid.init(10,15); _noodles.init(10,10); _gameOver = false; } void Engine::setLvl(int _levelToSet) { _lvl = _levelToSet; // sets the current level, this is used when the menu changes the currently selected level } void Engine::loadLvl() { if (_lvl == 1) { //checks to see what level should be loaded lvlOne(); } else if (_lvl == 2) { lvlTwo(); } else if (_lvl == 3) { lvlThree(); } } void Engine::lvlOne() { memset(_grid, 0, sizeof(_grid)); //clears the grid as it is a blank level } void Engine::lvlTwo() { int _newGrid[22][22] = { {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, {0,0,1,1,1,1,1,1,0,0,0,0,1,1,1,1,1,1,0,0}, {0,0,1,1,1,1,1,1,0,0,0,0,1,1,1,1,1,1,0,0}, {0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0}, {0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0}, {0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0}, {0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, {0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0}, {0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0} }; /* To load a set level, the level is first created as a new 2d array. It is set values for each coordinate Then the functional array has the values of _newGrid set to it individually */ for(int i = 0; i < 22; i++) { for (int j = 0; j < 22; j++) { _grid[i][j] = _newGrid[i][j]; } } } void Engine::lvlThree() { int _newGrid[22][22] = { {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, {0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0}, {0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,0,0,0}, {0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,0,0,0}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0}, {0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0}, {0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0}, {0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, {0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, {0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, {0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, {0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0}, {0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,0,0}, {0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,0,0}, {0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,0,0}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0} }; for(int i = 0; i < 22; i++) { for (int j = 0; j < 22; j++) { _grid[i][j] = _newGrid[i][j]; } } } void Engine::read_input(Gamepad &pad) { _d = pad.get_direction(); //_d stores the direction that the joystick is pushed in for later use } void Engine::draw(N5110 &lcd) { lcd.drawRect(0,0,48,48,FILL_TRANSPARENT); //draws a square around the 'play area' for (int j = 0; j < 22; j++) { //goes through each coordinate in the grid, for (int i = 0; i < 22; i++) { if (_grid[i][j] != 0) { //checks if the current square is NOT empty 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) } } } lcd.printString("Score",50,0); 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 char buffer1[21]; //buffer used for changing ints to strings sprintf(buffer1,"%3d",_score); //changes _score to a 3 letter string lcd.printString(buffer1,50,1); //prints the new string in the top right of the screen } void Engine::gameOverScreen(N5110 &lcd) { for (int i = 0; i < 22; i++) { //covers every square of the grid for (int j = 0; j < 22; j++) { 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 wait(0.01); //slight delay to allow the screen to keep up lcd.refresh(); //refreshes the screen but doesn't clear it, the intention is to get an overlay effect } } } void Engine::update(Gamepad &pad) { loadLvl(); //loads the level _solid.update(_d); //updates the coordinates of the snake checkGameOverAndSetGrid(); //checks if a game over state has been reached, if not set the new coordinates for the snake _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 if (checkFood()) { //checks if the head has reached food pad.tone(750.0,0.1); //plays a beep to signify that the snake has eaten growSnake(); //grows the snake as it has eaten the food bool empty = false; //makes a varible for finding an empty square while (!empty) { //loops until empty square found _noodles.random(); //randomise position of noodles if ( _grid[_noodles.getX()][_noodles.getY()] == 0) { empty = true; //stops looping when free space is found // no need to set the grid as it will put the noodles in the new location the next time 'update' is called } } } } void Engine::checkGameOverAndSetGrid() { int _l =_solid.getLength(); //stores the length of the snake to make it easier to debug for (int z = 0; z < _l; z++) { //checks the entire lenght of the snake if (_solid.getX(z) > 21 || _solid.getX(z) < 0) { //checks if the x coordinate is out of bounds _gameOver = true; } else if (_solid.getY(z) > 21 || _solid.getY(z) < 0) { //checks if the y coordinate is out of bounds _gameOver = true; } if (_grid[_solid.getX(z)][_solid.getY(z)] != 1) { //checks if the square the snake has moved to is clear _grid[_solid.getX(z)][_solid.getY(z)] = 1; //if so sets the current square to be occupied } else { _gameOver = true; //if not a game over state has been reached } } } bool Engine::checkFood() { if (_grid[_solid.getX(0)][_solid.getY(0)] == 2) { //checks if the head has reached food return true; } else { return false; } } void Engine::growSnake() { if (_solid.getLength()<484) { //checks if the snake can grow any more _solid.grow(); //makes snake longer } //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 //I feel no need to implement a victory screen due to how unlikey this is to happen } float Engine::getScore() { return _score; } bool Engine::getGameOver() { return _gameOver; } void Engine::gameTest() { if (!snakeTest()) { printf("Some game tests failed!\n"); } else if (!foodTest()) { printf("Some game tests failed!\n"); } else { printf("All game tests passed!\n"); } } bool Engine::snakeTest() { //checks if the grow function and initalisation works corectly _solid.init(12,10); bool _testState = true; _solid.grow(); _solid.grow(); int _testLength = _solid.getLength(); if ( _testLength != 5) { //checks if the snake has grown _testState = false; } if ( _solid.getY(0) != 10) { //checks the coordiantes of each snake section to check they are in the correct place _testState = false; } if ( _solid.getX(0) != 12) { _testState = false; } if ( _solid.getY(1) != 11) { _testState = false; } if ( _solid.getX(1) != 12) { _testState = false; } if ( _solid.getY(2) != 12) { _testState = false; } if ( _solid.getX(2) != 12) { _testState = false; } return _testState; } bool Engine::foodTest() { //checks if the radomise function works correctly for the food bool _testState = true; _noodles.init(7,3); _grid[_noodles.getX()][_noodles.getY()] = 2; //sets the grid value so that the randomise loop will work correctly bool empty = false; //makes a varible for finding an empty square while (!empty) { //loops until empty square found _noodles.random(); //randomise position of noodles if ( _grid[_noodles.getX()][_noodles.getY()] == 0) { empty = true; //stops looping when free space is found // no need to set the grid as it will put the noodles in the new location the next time 'update' is called } } if (_noodles.getX() ==7 && _noodles.getY() == 3) { //checks to see if randomised correctly _testState = false; //fail } return _testState; }