ELEC2645 (2019/20)
/
ELEC2645_Project_el17oc1
Owen Cavender 201159294
snake.cpp
- Committer:
- el17oc
- Date:
- 2020-05-30
- Revision:
- 14:7fb3c93343b6
- Parent:
- 13:b37dde18bfdc
- Child:
- 16:9500059ad5d8
File content as of revision 14:7fb3c93343b6:
#include "snake.h" Snake::Snake() { } Snake::~Snake() { } void Snake::init()//int x, int y) { _x0 = 48; //initialises the snake and apple position _x1 = 48; _x2 = 48; _x3 = 48; _x4 = 48; _x5 = 48; _y0 = 20; _y1 = 19; _y2 = 18; _y3 = 17; _y4 = 16; _y5 = 15; _apx = 48; //initial apple position - directly in front of snake _apy = 25; _gameover = false; //when _gameover = true, game cannot be played _reset_apple = false; _score = 0; _direction = up; _countdown = 12; //initial number of moves is lower than the reset value in order to keep the number of moves low to increase difficulty // Vector2D *_snakebody = new Vector2D [_length]; } Vector2D Snake::get_Snakehead() { Vector2D Snakehead; Snakehead.x = _x0; Snakehead.y = _y0; return Snakehead; } void Snake::apple_collected(N5110 &lcd, Gamepad &pad) { //need to code clear apple and make sure apple isnt spawning every time if((_x0 == _apx) && (_y0 == _apy)) { // directly comparing position of the apple and the Snakehead - if they are the same: the score increases, countdown timer is reset, a new apple position is generated, LEDS and Speaker are triggered // _countdown = _reset_value; _score++; _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 _countdown = _countdown + 38; //38 is added to the current countdown timer - this larger _countdown is, the further the snake can travel to collect apples. 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 pad.led(2, 1); // pad.led(4, 1); wait(0.1); pad.led(2, 0); pad.led(4, 0); } else { _countdown = _countdown - 1; //for each change in position, counter decreases by 1 } } int Snake::get_countdown() { //allows _countdown value to be called from other classes return _countdown; } void Snake::check_gameover(N5110 &lcd) { if (_x0 == 15 ||_x0 == 69 || _y0 == 32 || _y0 == 0) { // the snakehead coordinate is on any edge of the rectangle, it is gameover //the second condition is the game is over if the snake head cooroinate is equal to one of the snake body bits coordinate _gameover = true; // the third conditios is game is over if the counter = 0, indicating you've ran out of moves. } 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)) { _gameover = true; } if(_countdown == 0) { _gameover = true; } } void Snake::gameover_true(N5110 &lcd, Gamepad &pad) { while (_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 lcd.clear(); pad.tone(500,1); lcd.printString( " Game Over ", 0, 1 ); lcd.printString( " ~~~~~~~<:>-<", 0, 3 ); char buffer1[14]; sprintf(buffer1," Score: %2d", _score); //prints your score - cannot simply use N5110::printString as we need to output a value and the No. of inputs wouldnt match up to the function declaration lcd.printString(buffer1,0,4); // font is 8 wide, so leave 4 pixel gape from middle assuming two digits ///print score lcd.refresh(); } } void Snake::render(N5110 &lcd) //final function in the main function's while loop as the screen updatesbased on all any changes which occur in the functions { lcd.clear(); //apple lcd.setPixel(_apx, _apy,1); //plot apple position -whether it is a new position or the same position lcd.drawRect(15, 0, 54, 32, FILL_TRANSPARENT); //plots border of snake map lcd.setPixel(_x0, _y0,1); //plots snake body's new position changed by move_snake() function lcd.setPixel(_x1, _y1,1); lcd.setPixel(_x2, _y2,1); lcd.setPixel(_x3, _y3,1); lcd.setPixel(_x4, _y4,1); lcd.setPixel(_x5, _y5,1); lcd.setPixel(_x6, _y6,1); lcd.setPixel(_x7, _y7,1); //new position of the end bit of the snake is plotted - its old position cleared //NOTES CHANGLE LED VALUES SO IT IS TOP RIHGT OF THE BOX NOT TOP HALF OF THE SCREEN //CHANGE APPLE POSITION COORDINATES SO ITS IN BOX // GET SCORE IN THE SAME PLACE WHEN IT PRINTS AT END char buffer1[14]; sprintf(buffer1," %2d %2d",_score, _countdown); //prints score and counter on the same line lcd.printString(buffer1,0,5); // font is 8 wide, so leave 4 pixel gape from middle assuming two digits // char buffer2[14]; // sprintf(buffer2,"%2d",_score); // lcd.printString(buffer2,0,3); // font is 8 wide, so leave 4 pixel gape from middle assuming two digits lcd.refresh(); //applies plotting commands togeher } void Snake::get_direction(Gamepad &pad) { // int x; Directions direction = _direction; //"direction" stores the previous value of _direction to stop the snake going in the opposite direction to the way its travelling 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 if (pad.A_pressed()) { _direction = right; // x=1; } } if(direction != right) { if (pad.Y_pressed()) { _direction = left; // x=2; } } if(direction != down) { if (pad.B_pressed()) { // x=3; _direction = up; } } if(direction != up) { if (pad.X_pressed()) { _direction = down; // x=4; } } else { _direction = _direction; // setting the direction equal to itself if no button is pressed means the snake will move automatically once direction is set } // printf("direction %d ", x); //printf statements used in CoolTerm to check whether the input commands where working correctly } void Snake::move_snake() { if (_direction == up) { //shifting the snake position bit by bit, with respect to _x0 and _y0; _x7 = _x6; //coordinate _x[i], _y[i] = _x[i-1], _y[i-1] _y7 = _y6; _x6 = _x5; _y6 = _y5; _x5 = _x4; _y5 = _y4; _x4 = _x3; _y4 = _y3; _x3 = _x2; _y3 = _y2; _x2 = _x1; _y2 = _y1; _x1 = _x0; _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 _x0 = _x0; _y0 = _y0 + 1; //changes the position one bit at a time so the snake can only move horizontally or vertically } if (_direction == down) { _x7 = _x6; _y7 = _y6; _x6 = _x5; _y6 = _y5; _x5 = _x4; _y5 = _y4; _x4 = _x3; _y4 = _y3; _x3 = _x2; _y3 = _y2; _x2 = _x1; _y2 = _y1; _x1 = _x0; _y1 = _y0; _x0 = _x0; _y0 = _y0 - 1; } if (_direction == left) { _x7 = _x6; _y7 = _y6; _x6 = _x5; _y6 = _y5; _x5 = _x4; _y5 = _y4; _x4 = _x3; _y4 = _y3; _x3 = _x2; _y3 = _y2; _x2 = _x1; _y2 = _y1; _x1 = _x0; _y1 = _y0; _x0 = _x0 - 1; //changes x=x-1 , y remains the same to move left _y0 = _y0; } if (_direction == right) { _x7 = _x6; _y7 = _y6; _x6 = _x5; _y6 = _y5; _x5 = _x4; _y5 = _y4; _x4 = _x3; _y4 = _y3; _x3 = _x2; _y3 = _y2; _x2 = _x1; _y2 = _y1; _x1 = _x0; _y1 = _y0; _x0 = _x0 + 1; _y0 = _y0; } } void Snake::render_clear_tail(N5110 &lcd) { 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 } bool Snake::get_gameover() //methods to access member variables of the class { return _gameover; } int Snake::get_score() { return _score; } void Snake::get_Apple_position(N5110 &lcd) { if(_reset_apple == true) { // _reset_apple is a triggered when an apple is collected and causes a new Apple position to be randomly generated _reset_apple = false; // returned to false immediately so another position can be generated function can be triggered again in the next loop lcd.setPixel(_apx, _apy,0); //sets the exisiting apple position to 0 to remove it from lcd. _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 // the range is from 16 to 69 as the lowest x coordinate of the rectangle is 15 and the highest is 69 _apy = rand()%28+2; } }