Ahmed Adamjee
/
SnakeVSBlock
Snake vs Block Game to be run upon K64F.
Diff: GameEngine/SnakevsBlock/SnakevsBlock.cpp
- Revision:
- 51:387249f9b333
- Parent:
- 50:3cf9a94a264e
- Child:
- 52:c2faa96cf293
diff -r 3cf9a94a264e -r 387249f9b333 GameEngine/SnakevsBlock/SnakevsBlock.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/GameEngine/SnakevsBlock/SnakevsBlock.cpp Fri Apr 26 18:30:25 2019 +0000 @@ -0,0 +1,295 @@ +#include "SnakevsBlock.h" + +SnakevsBlock::SnakevsBlock() +{ + +} + +SnakevsBlock::~SnakevsBlock() +{ + +} + +void SnakevsBlock::init() +{ + //The level initialisation and all the other initial information passing will be done here + level = 1; + garbage = 0; //this is to allow the user to change the position of reference for motion control by saving the absolute angle. + foodbuff = 0; //this makes the food fall at diffrent times when a particular level starts. + send_block_number = 0; + blockgap = 300; + blockbuff = -50; + for(int i=0; i<=14; i++) {b[i] = 1;} //makes all the snake beads move by default. + SnakevsBlock::object_initialisations(); +} + +void SnakevsBlock::reset() +{ + //This prepares the game for the next level by reseting certain variables. + foodbuff = 0; + for(int i=0; i<=2; i++) { + food_pos[i].x = 0; + food_pos[i].y = 0; + } + if(blockgap >= 50) {blockgap -= 40;} //to make progressive levels harder by making the blocks drop more frequently. + SnakevsBlock::object_initialisations(); +} + +void SnakevsBlock::object_initialisations() +{ + _l.init(); //length calc object initialisation. + _s.init(); //snake object initialisation. + _f.init(); //food 1 object initialisation. + _ff.init(); //food 2 object initialisation. + _fff.init(); //food 3 object initialisation. + _b.init(); //block object initialisation. +} + +void SnakevsBlock::read_input(Gamepad &pad, FXOS8700CQ &device, int g_mode) +{ + device.get_values(); + angle = -device.get_roll_angle(); + //if button A is pressed then reset that particular position to center + if (pad.check_event(Gamepad::A_PRESSED) == true) { + garbage = angle; + } + device.get_values(); + angle = -device.get_roll_angle() - garbage; + if(g_mode == 1) { //this condition returns the relevant working directions if we select joystick in StartScreen. + _d = pad.get_direction(); //Obtains Direction pushed towards on Joystick. + _mag = pad.get_mag(); //Obtains Magnitude of Joystick. + } + else if(g_mode == 2) { //this condition returns the relevant working directions if we select motion control in StartScreen. + if (angle >= 8) { + _d = E; + } + else if (angle <= -8) { + _d = W; + } + else { + _d = CENTRE; + } + } + device.get_values(); + //printf("%d",gm); + //printf("%f",angle); + //printf("%f",device.get_roll_angle()); +} + +void SnakevsBlock::draw(N5110 &lcd, Gamepad &pad) { + _length = _l._getLength(); + _s.draw(pad, lcd, _length, level); //Draws the Snake. //Make these snake buffs relative to the snake drops which in turn relate to the game speed + if(foodbuff >= 0) { + _f.draw(lcd, blockbuff); //Draws the first food. + } + if(foodbuff >= 50) { + _ff.draw(lcd, blockbuff); //Draws the second food. + } + if(foodbuff >= 80) { + _fff.draw(lcd, blockbuff); //Draws the third food. + } + foodbuff +=1; + if(foodbuff >= 8) { + _b.draw(lcd, _length); + } + if(foodbuff == 8) { + blockbuff = -10; + } + //Code to print length on game screen. + _l.print_length_on_screen(lcd); +} + +int SnakevsBlock::update(N5110 &lcd, Gamepad &pad, SDFileSystem &sd) //Updates objects on screen. +{ + send_block_number = 0; //this is for the game to decide wether to remember the number on the block for the current itteration. + //we dont need to remember if it has already gone past the screen. + CheckSnakeFoodCollision(pad); //Function checks for when the snake collides with it's food. + CheckSnakeBlockCollision(pad); //Function checks for when the snake collides with any of the blocks. + CheckSnakeBlockSidesCollision(pad); //Function checks for when the snake collides with any of the blocks' sides. + _s.update(_d, b); //_d is the direction of joystick and b controls the motion of a section of the snake relative to obstruction + _f.update(); + _ff.update(); + _fff.update(); + _b.update(blocknum, blockgap, srn, send_block_number); + blockbuff++; + if(blockbuff >= blockgap) { //this makes blockbuff reset every time the new set of blocks appear. + blockbuff = -11; + } + //_statset.read(sd); //to read the currently stored value. + if(_length == 0) { + _wl.GameOver(lcd,pad); + } + if((pad.check_event(Gamepad::BACK_PRESSED))||(_length == 0)){ //Waits for Back button to be pressed. + back = 1; + SnakevsBlock::init(); + } + else { + back = 0; + } + printf("%d\n",_length); + if(_length >= 20) { + level = _wl.LevelComplete(lcd, pad, level); + _Setstats.write(level, sd); + SnakevsBlock::reset(); + } + return back; +} + +void SnakevsBlock::get_pos() +{ + //printf("player pos = %f %f \n", player_pos.x, player_pos.y); //top left of player sprite + // 81.000000 0.000000 top right + // 0.000000 0.000000 is top left + // 81.000000 45.000000 bottom right + snakex = _s.get_pos().x; //this could be snake_pos[0].x or simply snake_pos[0] to represent both x&y but as it is used the most, it improves readability. + snakey = _s.get_pos().y; //this could be snake_pos[0].y or simply snake_pos[0] to represent both x&y but as it is used the most, it improves readability. + //printf("snakexy in GAME = %d %d \n", snakex, snakey); + //Obtains all required coordinates. + food_pos[0] = _f.get_pos(); + food_pos[1] = _ff.get_pos(); + food_pos[2] = _fff.get_pos(); + //obtains origin cordinates of block. + b_pos = _b.get_pos(); + //this saves the positions of each snake beed (the first to the last) in a single array. Element[0] is the top beed and soo on. + snake_pos[0] = _s.get_pos(); //gets the position of the top beed and saves in array. + snake_pos[1] = _s.get_pos_before1(); //gets the position of the second beed and saves in array. + snake_pos[2] = _s.get_pos_before2(); //gets the position of the third beed and saves in array. + snake_pos[3] = _s.get_pos_before3(); //gets the position of the fourth beed and saves in array. + snake_pos[4] = _s.get_pos_before4(); //gets the position of the fifth beed and saves in array. + snake_pos[5] = _s.get_pos_before5(); //gets the position of the sixth beed and saves in array. + snake_pos[6] = _s.get_pos_before6(); //gets the position of the seventh beed and saves in array. + snake_pos[7] = _s.get_pos_before7(); //gets the position of the eight beed and saves in array. + snake_pos[8] = _s.get_pos_before8(); //gets the position of the ninth beed and saves in array. + snake_pos[9] = _s.get_pos_before9(); //gets the position of the last beed and saves in array. +} + + +void SnakevsBlock::CheckSnakeFoodCollision(Gamepad &pad) { + //If statements check if the snake sprite has collided with any + //of the three food sprites, if so then the food location is reset and + //length of the snake is increased using the length variable. + for(int y=0; y<=2; y++) { //this loop automatically detects each combination of collision in the y postion + for(int x=0; x<=2; x++) { //this loop automatically detects each combination of collision in the x postion + for(int food_sr=0; food_sr<=2; food_sr++) { //this loop automatically detects which food we are interacting with. + if ( + ((snakey + y == food_pos[food_sr].y) || + (snakey + y == food_pos[food_sr].y + 1) || + (snakey + y == food_pos[food_sr].y + 2)) && + ((snakex + x == food_pos[food_sr].x) || + (snakex + x == food_pos[food_sr].x + 1) || + (snakex + x == food_pos[food_sr].x + 2)) + ) { + //printf("snake feast working \n"); + //audio feedback + pad.tone(786.0,0.1); + food_pos[food_sr].x = (rand() % 82); //this makes the food pop up at a random, unspecified location in the x axis. + food_pos[food_sr].y = -3; + _l.PlusLength(); + } + } + } + } + _f.set_pos(food_pos[0]); + _ff.set_pos(food_pos[1]); + _fff.set_pos(food_pos[2]); +} + +void SnakevsBlock::CheckSnakeBlockCollision(Gamepad &pad) { + //Obtains the numbers inside the block. + b_number = _b.get_number(); + //If statements check if the snake sprite has collided with any + //of the blocks which are a maximum of 5, if so then the snake length reduces and the block number reduces + //the block has to move slower and come down after every 2/3 iterations(dependent on the snake size.(think about this) + for(int block=0; block<=83; block+=1) { //this loop automatically detects for each section of block and each combination of collision + if (((snakey == b_pos.y + 11)||(snakey == b_pos.y + 10)||(snakey == b_pos.y + 9)) && (snakex + 1 == b_pos.x + block)) { + //the or for the block's y position is due to the fact the exact y co-ordinate might not be collided if the snake's length has increased in the same itteration. + //printf("snake collision working \n"); + //audio feedback + if(blocknum > 0) {b_pos.y = 0;} //change this to speed y = 0 when length = 10. + srn = CheckBlock(block); //this tells us which of the 5 blocks we are colliding with + blocknum = b_number[srn]; + if((_length>=10)&&(b_number[srn]>0)) { //this makes the block stop moving down if it's length is more than 10 and still collides. + velocity = 0; + } + else { + velocity = 1; + } + ImplementCollision(pad); + SnakevsBlock::_set_velocity(); + } + } +} + +void SnakevsBlock::_set_velocity() { + _b.velocity.y = velocity; + _f.velocity.y = velocity; + _ff.velocity.y = velocity; + _fff.velocity.y = velocity; +} + +int SnakevsBlock::CheckBlock(int block) { + int srn; + if((block>=0)&&(block<=18)) {srn = 0;} + if((block>=19)&&(block<=34)) {srn = 1;} + if((block>=35)&&(block<=50)) {srn = 2;} + if((block>=51)&&(block<=66)) {srn = 3;} + if((block>=67)&&(block<=83)) {srn = 4;} + return srn; +} + +void SnakevsBlock::ImplementCollision(Gamepad &pad) { + send_block_number = 1; + if(blocknum > 0) { // to make sure that snake doesn't decrease in _length if number on the block is less than 1; + _l.MinusLength(); + pad.tone(1000.0,0.1); + wait(0.04); + } + blocknum-=1; +} + +void SnakevsBlock::CheckSnakeBlockSidesCollision(Gamepad &pad) +{ + //If statements check if the snake sprite has collided with any + //of the blocks' sides and then stop the snake moving in x axis + int length = _length; + if(_length>=10) {length = 10;} //to stop the snake length virtually at 10 when it goes past it. + + for(int i=0; i<=9; i++) { + b[i] = 1; + } + for(int i=0; i<=9; i++) { //i checks for all possible collisions with the snake respective to it's length. + for(int b_y_combination=0; b_y_combination<=10; b_y_combination++) { + if ( + (snake_pos[i].y == b_pos.y + b_y_combination) || + (snake_pos[i].y + 1 == b_pos.y + b_y_combination) || + (snake_pos[i].y + 2 == b_pos.y + b_y_combination)) { + for(int b_x_combination=2; b_x_combination<=82; b_x_combination+=16) { + //For West side of walls + if( + ((snake_pos[i].x == b_pos.x + b_x_combination+2) || //W + (snake_pos[i].x + 1 == b_x_combination+2))&&(_d != E)&&(length > i) //W + ) { + //code makes sure that the colliding part doesn't move in x axis. + for(int snake_beed_num=0; snake_beed_num<=10; snake_beed_num++) { + if(length == snake_beed_num + i) { + b[snake_beed_num - 1] = 0; + } + } + } + //for East side of walls + else if ( + ((snake_pos[i].x + 1 == b_x_combination) || //E + (snake_pos[i].x + 2 == b_x_combination))&&(_d != W)&&(length > i) //E + ) { + //code makes sure that the colliding part doesn't move in x axis. + for(int snake_beed_num=0; snake_beed_num<=10; snake_beed_num++) { + if(length == snake_beed_num + i) { + b[snake_beed_num - 1] = 0; + } + } + } + } + } + } + } +} \ No newline at end of file