Snake vs Block Game to be run upon K64F.

Dependencies:   mbed

SnakevsBlock/SnakevsBlock.cpp

Committer:
AhmedPlaymaker
Date:
2019-04-15
Revision:
32:3a3bdeffdf62
Parent:
29:c6358c39a70e
Child:
33:249cf423fb18

File content as of revision 32:3a3bdeffdf62:

#include "SnakevsBlock.h"

SnakevsBlock::SnakevsBlock()
{

}

SnakevsBlock::~SnakevsBlock()
{

}

void SnakevsBlock::init()
{
    //The snake length configuration and all the other initial information passing will be done here
    length = 3;
    level = 1;
    foodbuff = 0;
    send=0;
    speed = 1;
    blockgap = 500;
    blockbuff = -50;
    for(int i=0; i<=14; i++)  {
        b[i] = 1;
    }
    _s.init();
    _f.init();
    _ff.init();
    _fff.init();
    _b.init();
}



void SnakevsBlock::read_input(Gamepad &pad)
{
    _d = pad.get_direction(); //Obtains Direction pushed towards on Joystick.
    _mag = pad.get_mag(); //Obtains Magnitude of Joystick.
}

void SnakevsBlock::draw(N5110 &lcd, Gamepad &pad)   {
    length = _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, blockgap, blockbuff); //Draws the first food.
        if(foodbuff >=50)  {
            _ff.draw(lcd, blockgap, blockbuff); //Draws the second food.
            if(foodbuff >=80) {
                _fff.draw(lcd, blockgap, blockbuff); //Draws the third food.
            }
        }
        foodbuff +=1;
    }
    if(foodbuff >=8) {
        send = _b.draw(lcd, length, blocknum, srn, blockgap);
    }
    if(foodbuff == 8) {
        blockbuff = 0;
    }
    //Code to print length on game screen.
    char bufferscore[14];
    sprintf(bufferscore,"%d",length);
    lcd.printString(bufferscore,1,0);    
}


int SnakevsBlock::update(Gamepad &pad) //Updates objects on screen.
{
    CheckSnakeBlockCollision(pad); //Function checks for when the snake collides with any of the blocks.
    CheckSnakeFoodCollision(pad); //Function checks for when the snake collides with it's food.
    CheckSnakeBlockSidesCollision(pad, _d); //Function checks for when the snake collides with any of the blocks' sides.
    _s.update(pad.get_direction(),_mag, length, speed, b); //_d is the direction of joystick and b controls thew motion of a section of the snake relative to obstruction
    _f.update();
    _ff.update();
    _fff.update(); 
    _b.update(blocknum, srn, send);
    blockbuff++;
    if(blockbuff == blockgap)  {  //change this while changing the block drop gap
        blockbuff = 0;
    }
    if(length > 15)  {  //to make progressive levels harder
        blockgap -= 20;
        level += 1;
    }
    if(pad.check_event(Gamepad::BACK_PRESSED)){ //Waits for Back button to be pressed.
        back = 1;
        //add some warning here and use A as the button to confirm
        SnakevsBlock::init();
    }
    else {
        back = 0;
    }
    return back;
}

void SnakevsBlock::get_pos()
{
    Vector2D snake_pos = _s.get_pos(length);
    //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 = snake_pos.x;
    snakey = snake_pos.y;
    //printf("snakexy in GAME = %d %d \n", snakex, snakey);
}   
    

void SnakevsBlock::CheckSnakeFoodCollision(Gamepad &pad)    {
    //Obtains all required coordinates.
    Vector2D food_pos[3];
    food_pos[0] = _f.get_pos();
    food_pos[1] = _ff.get_pos();
    food_pos[2] = _fff.get_pos();
    Vector2D snake_pos = _s.get_pos(length);
    //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 (
                    ((snake_pos.y + y == food_pos[food_sr].y) ||
                    (snake_pos.y + y == food_pos[food_sr].y + 1) ||
                    (snake_pos.y + y == food_pos[food_sr].y + 2)) &&
                    ((snake_pos.x + x == food_pos[food_sr].x) ||
                    (snake_pos.x + x == food_pos[food_sr].x + 1) ||
                    (snake_pos.x + x == food_pos[food_sr].x + 2))
                ) {
                    //printf("snake feast working \n");
                    //audio feedback
                    pad.tone(1000.0,0.1);
                    food_pos[food_sr].x = rand() % 82;
                    if((blockbuff>=11)&&(blockbuff<=blockgap-11))  { //this makes sure that the snake food appears seperated from the block
                        food_pos[food_sr].y = -2;
                    }
                    length+=1;
                }
            }
        }
    }
    _f.set_pos(food_pos[0]);
    _ff.set_pos(food_pos[1]);
    _fff.set_pos(food_pos[2]);
}
    
    void SnakevsBlock::CheckSnakeBlockCollision(Gamepad &pad)
    {
        //Obtains all required coordinates.
        Vector2D b_pos = _b.get_pos();
        int *b_number;
        b_number = _b.get_number();
        Vector2D snake_pos = _s.get_pos(length);
        //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 ((snake_pos.y == b_pos.y + 10) && (snake_pos.x + 1 == b_pos.x + block))  {
            //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];
            ImplementCollision(pad);
        }
    }
}
 
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=1;
    blocknum-=1;
    if(blocknum >= 0)  {  // to make sure that snake doesn't decrease in length if number on the block is less than 1;
        length-=1;
        pad.tone(1000.0,0.1);
        wait(0.04);
    }
}

void SnakevsBlock::CheckSnakeBlockSidesCollision(Gamepad &pad, Direction d)
    {
        //Obtains all required coordinates for checking block sides and snake collision.
        Vector2D b_pos = _b.get_pos();
        snake_pos[0] = _s.get_pos(length);
        snake_pos[1] = _s.get_pos_before1(length);
        snake_pos[2] = _s.get_pos_before2(length);
        snake_pos[3] = _s.get_pos_before3(length);
        snake_pos[4] = _s.get_pos_before4(length);
        snake_pos[5] = _s.get_pos_before5(length);
        snake_pos[6] = _s.get_pos_before6(length);
        snake_pos[7] = _s.get_pos_before7(length);
        snake_pos[8] = _s.get_pos_before8(length);
        snake_pos[9] = _s.get_pos_before9(length);
        snake_pos[10] = _s.get_pos_before10(length);
        snake_pos[11] = _s.get_pos_before11(length);
        snake_pos[12] = _s.get_pos_before12(length);
        snake_pos[13] = _s.get_pos_before13(length);
        snake_pos[14] = _s.get_pos_before14(length);
        
        //If statements check if the snake sprite has collided with any
        //of the blocks' sides and then stop the snake moving in x axis
        
        for(int i=0; i<=14; i++)  {
            b[i] = 1;
        }
        
    for(int i=0; i<=14; i++)  {
        for(int a=0; a<=10; a++)  {
            if (
                (snake_pos[i].y == b_pos.y + a) ||
                (snake_pos[i].y + 1 == b_pos.y + a) ||
                (snake_pos[i].y + 2 == b_pos.y + a))  {
                
                //For West side of walls 
                if(
                    ((snake_pos[i].x == b_pos.x + 4) ||  //W
                    (snake_pos[i].x == b_pos.x + 36) ||  //W
                    (snake_pos[i].x == b_pos.x + 68) ||  //W
                    (snake_pos[i].x + 1 == b_pos.x + 4) ||  //W
                    (snake_pos[i].x + 1 == b_pos.x + 36) ||  //W
                    (snake_pos[i].x + 1 == b_pos.x + 68) ||  //W
                    (snake_pos[i].x == b_pos.x + 20) ||  //W
                    (snake_pos[i].x == b_pos.x + 52) ||  //W
                    (snake_pos[i].x == b_pos.x + 84) ||  //W
                    (snake_pos[i].x + 1 == b_pos.x + 20) ||  //W
                    (snake_pos[i].x + 1 == b_pos.x + 52) ||  //W
                    (snake_pos[i].x + 1 == b_pos.x + 84))&&(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<=15; 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_pos.x + 18) ||  //E
                    (snake_pos[i].x + 1 == b_pos.x + 50) ||  //E
                    (snake_pos[i].x + 1 == b_pos.x + 82) ||  //E
                    (snake_pos[i].x + 2 == b_pos.x + 18) ||  //E
                    (snake_pos[i].x + 2 == b_pos.x + 50) ||  //E
                    (snake_pos[i].x + 2 == b_pos.x + 82) ||  //E
                    (snake_pos[i].x + 1 == b_pos.x + 2) ||  //E
                    (snake_pos[i].x + 1 == b_pos.x + 34) ||  //E
                    (snake_pos[i].x + 1 == b_pos.x + 66) ||  //E
                    (snake_pos[i].x + 2 == b_pos.x + 2) ||  //E
                    (snake_pos[i].x + 2 == b_pos.x + 34) ||  //E
                    (snake_pos[i].x + 2 == b_pos.x + 66))&&(d != W) //E
                ) {
                    //code makes sure that the colliding part doesn't move in x axis.
                    for(int snake_beed_num=0; snake_beed_num<=15; snake_beed_num++)  {
                        if(length == snake_beed_num + i)  {
                            b[snake_beed_num - 1] = 0;
                        }
                    }
                }
            }
        }
    }
}