ELEC2645 (2019/20)
/
ELEC2645_Project_el17oc1
Owen Cavender 201159294
Diff: snake.cpp
- Revision:
- 14:7fb3c93343b6
- Parent:
- 13:b37dde18bfdc
- Child:
- 16:9500059ad5d8
--- a/snake.cpp Fri May 29 16:27:29 2020 +0000 +++ b/snake.cpp Sat May 30 02:31:43 2020 +0000 @@ -11,9 +11,9 @@ -void Snake::init() +void Snake::init()//int x, int y) { - _x0 = 48; + _x0 = 48; //initialises the snake and apple position _x1 = 48; _x2 = 48; _x3 = 48; @@ -26,14 +26,15 @@ _y3 = 17; _y4 = 16; _y5 = 15; - - _apx = 48; + + _apx = 48; //initial apple position - directly in front of snake _apy = 25; - _gameover = false; + _gameover = false; //when _gameover = true, game cannot be played _reset_apple = false; _score = 0; _direction = up; - _countdown = 30; + _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]; } @@ -55,89 +56,95 @@ { //need to code clear apple and make sure apple isnt spawning every time - if((_x0 == _apx) && (_y0 == _apy)) { + 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; - _countdown = 30; //causes new apple position to be generated - pad.tone(1500.0,0.5); - pad.led(2, 1); + _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); - - //pad.led(2, 0); - //pad.led(4, 0); + wait(0.1); + pad.led(2, 0); + pad.led(4, 0); } else { - _countdown = _countdown - 1; - printf(" countdown = %d score %d ", _countdown ,_score); + _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) //code where it hits itself +void Snake::check_gameover(N5110 &lcd) { - if (_x0 == 0 ||_x0 == 84 || _y0 == 32 || _y0 == 0) { //how do i access snakehead.headx - - _gameover = true; - } - 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)) { - _gameover = true; - } - if(_countdown == 0) { - _gameover = true; //|| (_x0 == _x4 && _y0 == _y4)) - - } + 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. } - -void Snake::gameover_true(N5110 &lcd) -{ + 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; - while (_gameover == true) { - - lcd.printString( " Game Over L ", 0, 2 ); - char buffer1[14]; - sprintf(buffer1,"%2d",_score); - lcd.printString(buffer1,0 ,48); // font is 8 wide, so leave 4 pixel gape from middle assuming two digits - - - if (_score <= 7) { - lcd.printString(" Loser ", 0,10); - } - if (7< _score <= 25) { - lcd.printString(" Good Job! ", 0,10); - } else { - lcd.printString(" SNAKE PRO ", 0,10); - lcd.printString(" ~.~.~.~.<8>~ ", 0, 5); - - } - lcd.refresh(); } } -void Snake::render(N5110 &lcd) +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); //apple + lcd.setPixel(_apx, _apy,1); //plot apple position -whether it is a new position or the same position - lcd.drawRect(0, 0, 84, 40, FILL_TRANSPARENT); //game - lcd.setPixel(_x0, _y0,1); //snake + 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 +} @@ -145,27 +152,27 @@ void Snake::get_direction(Gamepad &pad) { - // int x; - Directions direction = _direction; - if(direction != left) { + // 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; + // x=1; } } if(direction != right) { if (pad.Y_pressed()) { _direction = left; - // x=2; + // x=2; } - //check these are orrecrt } if(direction != down) { if (pad.B_pressed()) { - // x=3; + // x=3; _direction = up; } } @@ -173,35 +180,47 @@ if (pad.X_pressed()) { _direction = down; - // x=4; + // x=4; } } else { - _direction = _direction; + _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("direction %d ", x); //printf statements used in CoolTerm to check whether the input commands where working correctly } void Snake::move_snake() { - if (_direction == up) { - _x5 = _x4; - _x4 = _x3; + 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; + _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; + _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; @@ -214,8 +233,14 @@ } 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; @@ -223,7 +248,7 @@ _x1 = _x0; _y1 = _y0; - _x0 = _x0 - 1; + _x0 = _x0 - 1; //changes x=x-1 , y remains the same to move left _y0 = _y0; @@ -231,8 +256,14 @@ } 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; @@ -244,18 +275,17 @@ _y0 = _y0; - } else - _direction = _direction; + } } void Snake::render_clear_tail(N5110 &lcd) { - lcd.setPixel(_x5, _y5, false); + 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() +bool Snake::get_gameover() //methods to access member variables of the class { return _gameover; } @@ -263,70 +293,21 @@ { return _score; } -int Snake::get_oldscore() -{ - return _oldscore; -} -int Snake::get_reset_value() -{ - return _reset_value; -} + + void Snake::get_Apple_position(N5110 &lcd) { - if(_reset_apple == true) - { - lcd.setPixel(_apx, _apy,0); - _apx = rand()%82+1; - _apy = rand()%30+1; + 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; + } - _reset_apple = false; - } else { - _apx = _apx; - _apy = _apy; - } } -/* -void Snake::get_time(Timer &timer) -{ - ticker.attach(&flip, 2.0); - _realtime = timer.read(); - _display_time = (Reset_value - _realtime); - int x = _realtime; - int y = _display_time; - printf("12-T = %d t = %d ", y, x); -*/ - -int Snake::set_reset_value() -{ - - if (0 <= _score && _score < 10) { - _reset_value = 12; - } - if (10 <= _score && _score < 15) { - _reset_value = 10; - } - if (15 <= _score && _score < 20) { - _reset_value = 8; - } else { - _reset_value = 6; - } - - return _reset_value; -} - - -//void Snake::print_display_time(N5110 &lcd) -//{ - // int countdown = _realtime; - - // char buffer1[14]; - //sprintf(buffer1,"%2d",countdown); - //lcd.printString(buffer1,WIDTH/2,30); // font is 8 wide, so leave 4 pixel gape from middle assuming two digits - //char buffer2[14]; - -//} \ No newline at end of file