Adam Baker 201166301

Dependencies:   mbed Gamepad N5110

Blockhead/Blockhead.cpp

Committer:
adambakerwa
Date:
2019-05-09
Revision:
50:9fc8edf722a8

File content as of revision 50:9fc8edf722a8:

#include "Blockhead.h"




// nothing doing in the constructor and destructor
Blockhead::Blockhead()
{

}

Blockhead::~Blockhead()
{

}


//initialise all vairables
void Blockhead::init()              
{

    _x = 35;                        //x cordinate of blockhead
    _y = 5;                         //y cordinate of bloc
    _jump = 0;                      //jump counter
    _wjr = 0;                       //wall jump right counter
    _wjl = 0;                       //wall jump left counter
    _fall = 0;                      //fall counter
    _sprintright = 0;               //right sprint counter
    _sprintleft = 0;                //left sprint counter
    _level = 1;                     //dont initialise every time so doesnt restart at beggining each time..
    _runani = 0;                    //run counter
    _walkani = 0;                   //wak animation counter
    _death = 0;                     //death counter
}


//initialise all variables, except level
void Blockhead::continue_init()         
{


    _x = 0;                             //x cordiante of blockhead
    if (_level == 6 || _level == 7 || _level == 9) {   //start point differs depending on what level your on
        _y = -3;                         //y cordiante either 5,
    } else {
        _y = 25;                        //or 25
    }
    _jump = 0;                          //jump counter
    _wjr = 0;                           //wall jump right counter
    _wjl = 0;                           //wall jump left counter
    _fall = 0;                          //fall counter
    _sprintright = 0;                   //sprint right counter
    _sprintleft = 0;                    //sprint left counter
    _runani = 0;                        //run counter
    _walkani = 0;                       //walk animation counter
    _death = 0;                         //death counter


}


//all mechanics controling blockhead (movement from user input, movement from platforms, and gameover)
void Blockhead::blockhead(Pos pos, N5110 &lcd, Gamepad &pad)    
{
    movement(lcd, pad);                                         //contolls movement of blockhead depending on input
    platform_check(pos);                                        //checks if blochead is on or by a moving platform,
    on_platform(lcd);                                           //if so, moves blockhead acordingly
    gameover(pos, lcd);                                         //intiates death sequence if spike hit or crushed by platform
    
    

}


//all the functions which take an input and controll movement of blockhead (in correct order)
void Blockhead::movement(N5110 &lcd, Gamepad &pad)              
{
    button_press(lcd, pad);                                     //checks if A button is pressed at correct moment (on ground for example), and starts correct counter
    _speed = get_speed(pad);                                    //gets speed value according to joystick position
    jump(lcd);                                                  //performes a jump when jump counter is 1
    wall_jump_left(lcd, _speed);                                //peformes a wall jumo when wjl counter is 1
    wall_jump_right(lcd, _speed);                               //peformes a wall jump when wjr counter is 1
    run_left(lcd, _speed);                                      //moves left if speed is less than 0, lower speed is quicker blockhead moves
    run_right(lcd, _speed);                                     //moves righ if speed is more than 0, higher speed is quicker blockhead moves
    cancel_sprint(lcd, _speed);                                 //cancels sprint if hits wall or joystick is 0
    fall(lcd);                                                  //falls when no ground below
    runner_state(lcd, pad, _speed);                             //displays different sprites depending on what state runner is in (animating him)
}


//when game over, returns 1
int Blockhead::gameover_flag(Gamepad &pad)                     
{
    if (_death > 8 || fallen(pad) == 1) {                      //will return 1 when character falls of screen, or death sequence completes,
        _gameover = 1;
    } else {
        _gameover = 0;
    }
    
    //printf("_gameove = %d", _gameover);  //uncoment to print for testing

    return _gameover;
}

//starts death sequence if crushed by moving platform or if hit spikes
void Blockhead::gameover(Pos pos, N5110 &lcd)                 
{
    if ((crushed_by_ver(pos) + crushed_by_ver_2(pos) + spike_hit(lcd, pos))>0 && _death==0) {
        _death = 1;
    }
    
    //printf("_death = %d", _death);  //uncoment to print for testing
}


//change increment depending on what button is pressed and where the runner is
void Blockhead::button_press(N5110 &lcd, Gamepad &pad)                                                  
{

    if (pad.check_event(Gamepad::A_PRESSED)) {
        if (_ani.pixelsDown(_x,_y,lcd) || _d3 == 3 || _d4 == 3) {                                       //if standing, or if on vertical platform,
            _jump = 1;                                                                                  //jump increment begins.
            pad.tone(880, 0.1);
        } else if (_ani.pixelsLeft(_x,_y,lcd) && _ani.pixelsDown(_x,_y,lcd)==false && _wjr == 0) {      //if in air and by wall to left, wall jump right = 1
            _wjr++;
            pad.tone(1046.502, 0.1);
        } else if (_ani.pixelsRight(_x,_y,lcd) && _ani.pixelsDown(_x,_y,lcd) == false && _wjl == 0) {   //if in air, and by wall to right, wall jump left = 1
            _wjl++;
            pad.tone(1046.502, 0.1);
        }
    }
}


 //move n pixels up if no collision
void Blockhead::move_up(N5110 &lcd, int n)                     
{

    for(int i = 0; i < n; i++) {
        if (_ani.pixelsUp(_x,_y,lcd) == false) {
            _y--;
        }
    }
    
    //printf("_y = %d", _y);  //uncoment to print for testing
}


//move n pixels down if no collision
void Blockhead::move_down(N5110 &lcd, int n)                    
{
    for(int i = 0; i < n; i++) {
        if (_ani.pixelsDown(_x,_y,lcd) == false) {
            _y++;
        }
    }
    
    //printf("_y = %d", _y);  //uncoment to print for testing
}


//move n pixels right if no collision
void Blockhead::move_right(N5110 &lcd, int n)                   
{
    for(int i = 0; i < n; i++) {
        if (_ani.pixelsRight(_x,_y,lcd) == false) {
            _x++;
        }
    }
    
    //printf("_x = %d", _x);  //uncoment to print for testing
}


//move n pixels left if no collision
void Blockhead::move_left(N5110 &lcd, int n)                    
{

    for(int i = 0; i < n; i++) {
        if (_ani.pixelsLeft(_x,_y,lcd) == false) {
            _x--;
        }
    }
    
    //printf("_x = %d", _x);  //uncoment to print for testing

}


//peforms jump sequence when _jump is 1
void Blockhead::jump(N5110 &lcd)
{

    if (_jump <= 4 && _ani.pixelsUp(_x,_y,lcd) == false) {              //if nothing above, and jump counter is below 4
        if (_jump == 1) {                                               //four pixels per refresh for first two jump increments
            _jump++;
            move_up(lcd, 4);
        } else if (_jump == 2) {                                        // two pixels per refresh for next jump incrmements
            _jump++;
            move_up(lcd, 2);
        } else if (_jump > 2 && _jump <= 4) {                           // one pixel per refresh for final jump increments
            move_up(lcd, 1);
            _jump++;
        }
    } else {
        _jump = 0;                                                      //jump counter reset to 0 once jump cycle finished or interupted
    }
    
    //printf("_jump = %d, _x = %d, _y = d%", _jump, _x, _y);  //uncoment to print for testing

}


//peforms wall jump right sequence when _wjr = 1
void Blockhead::wall_jump_right(N5110 &lcd, float speed)
{
    if (_wjr == 1 && _ani.pixelsUp(_x,_y,lcd) == false) {                       //if wjr counter == 1 and nothing above
        _wjr++;
        _wjl = 0;                                                               //set wjl counter to 0, so can jump from opposite wall
        move_up(lcd, 4);                                                        //move four pixels up
        if (speed < 0.5f) {                                                     //and two pixels right, unless joy stick is driving right anyway
            move_right(lcd, 2);
        }
    } else if (_wjr == 2 && _ani.pixelsUp(_x,_y,lcd) == false) {
        _wjr++;
        move_up(lcd,2);                                                         //move two pixels up
        if (speed < 0.5f) {                                                     //and a pixel right, unless joy stick is driving right anyway
            move_right(lcd, 1);
        }
    } else if (_wjr > 2 && _wjr <= 4 && _ani.pixelsUp(_x,_y,lcd) == false) {
        _wjr++;
        move_up(lcd, 1);                                                        //move one pixel up
        if (speed < 0.5f) {                                                     //and a pixel right, unless joy stick is driving right anyway
            move_right(lcd, 1);
        }
    } else if (_ani.pixelsDown(_x,_y,lcd)) {
        _wjr = 0;                                                               //only reset wall jump count when on ground, or when
    } else if (_ani.pixelsUp(_x,_y,lcd)) {                                      //left wall jump activated, so you cant wall jump continuously up one wall.
        _wjr = 0;                                                               //or when ceiling hit to avoid blockhead sticking
    }
    
    //printf("_wjr = %d, _x = %d, _y = d%", _wjr, _x, _y);  //uncoment to print for testing


}


//peforms wall jump left sequence when _wjl = 1 
void Blockhead::wall_jump_left(N5110 &lcd, float speed)
{

    if (_wjl == 1 && _ani.pixelsUp(_x,_y,lcd) == false) {           //if wjl counter == 1 and nothing above
        _wjl++;
        _wjr = 0;                                                               //set wjr counter to 0, so can jump from opposite wall
        move_up(lcd, 4);                                                        //move four pixels up
        if (speed > -0.5f) {                                                    //and two pixels left, unless joy stick is driving left anyway
            move_left(lcd, 2);
        }
    } else if (_wjl == 2 && _ani.pixelsUp(_x,_y,lcd) == false) {
        _wjl++;
        move_up(lcd, 2);                                                        //move two pixels up
        if (speed > -0.5f) {                                                    //and a pixel left, unless joy stick is driving left anyway
            move_left(lcd, 1);
        }
    } else if (_wjl > 2 && _wjl <= 4 && _ani.pixelsUp(_x,_y,lcd) == false) {
        _wjl++;
        move_up(lcd, 1);                                                        // move one pixel up
        if (speed > -0.5f) {                                                    //and a pixel left, unless joy stick is driving left anyway
            move_left(lcd, 1);
        }
    } else if (_ani.pixelsDown(_x,_y,lcd)) {
        _wjl = 0;                                                               //only reset wall jump count when on ground, or when
    } else if (_ani.pixelsUp(_x,_y,lcd)) {                                      //right wall jump activated, so you cant wall jump continuously up one wall.
        _wjl = 0;
    }

    //printf("_wjl = %d, _x = %d, _y = d%", _wjl, _x, _y);  //uncoment to print for testing

}


//peforms fall when NOT in a jump cycle, wall jump cycle, and no ground below.
void Blockhead::fall(N5110 &lcd)
{
    if (_jump == 0 && (_wjr == 0 || _wjr == 5) && (_wjl == 0 || _wjl == 5) && _ani.pixelsDown(_x,_y,lcd) == false) {
        if (_fall == 0) {
            move_down(lcd, 1);                                          //one pixel down per refresh to start
            _fall++;
        } else if (_fall == 1) {
            _fall++;
            move_down(lcd, 2);                                          //then two pixels down per refresh
        } else if (_fall == 2) {
            _fall++;
            move_down(lcd, 3);                                          //then three..
        } else if (_fall >= 3) {
            _fall++;
            move_down(lcd, 4);                                          //then four pixels per fresh (Maximum velocity!)
        }
    } else {
        _fall = 0;                                                      //rest fall counter when no longer falling

    }
    
    //printf("_fall = %d, _x = %d, _y = d%", _fall, _x, _y);  //uncoment to print for testing

}


//gets direction from joystick, and returns as speed
float Blockhead::get_speed(Gamepad &pad)
{

    Vector2D coord = pad.get_coord();
    float speed = coord.x;                                              //set speed to the cordinates of the joystick's x value

    return speed;
    
    //printf("speed = %d, _x = %d, _y = d%", speed);  //uncoment to print for testing
}


//moves blockhead right according to speed
void Blockhead::run_right(N5110 &lcd, float speed)
{
    if (_ani.pixelsRight(_x,_y,lcd) == false && (_wjl == 0 || _wjl == 5)) {     //run right if no obstical
        if (speed > 0.1f && speed <= 0.25f) {                                   //depending on speed, move...
            move_right(lcd, 1);                                                 //1 pixel right
        } else if (speed > 0.25f && speed <= 0.5f) {
            move_right(lcd, 2);                                                 //2 pixels right
        } else if (speed > 0.5f && speed <= 0.75f) {
            move_right(lcd, 3);                                                 //3 pixels right
        } else if (speed > 0.75f) {
            move_right(lcd, 4);                                                 //4 pixels right
            _sprintright++;
            if (_sprintright > 20) {                                            //if at top speed for more than 20 cycles, sprint! (6 pix per refresh);
                move_right(lcd, 2);
            }
        }
    }
    
    //printf("speed = %d, _x = %d, _y = d%", speed, _x, _y);  //uncoment to print for testing

}


//moves blockhead left according to speed
void Blockhead::run_left(N5110 &lcd, float speed)
{


    if (_ani.pixelsLeft(_x,_y,lcd) == false && (_wjr == 0 || _wjr == 5)) {      //run left if no obstical
        if (speed < -0.1f && speed >= -0.25f) {                                 //depending on speed move..
            move_left(lcd, 1);                                                  //1 pixel left
        } else if (speed < -0.25f && speed >= -0.5f) {
            move_left(lcd, 2);                                                  //2 pixels right
        } else if (speed < -0.5f && speed >= -0.75f) {
            move_left(lcd, 3);                                                  //3 pixels right
        } else if (speed < -0.75f) {
            move_left(lcd, 4);                                                  //4 pixels right
            _sprintleft++;
            if (_sprintleft > 20) {                                             //if at top speed for more than 20 cycles, sprint!
                move_left(lcd, 2);
            }

        }
    }

    //printf("speed = %d, _x = %d, _y = d%", speed, _x, _y);  //uncoment to print for testing

}


//restets sprint incrment if collision or joystick idle
void Blockhead::cancel_sprint(N5110 &lcd, float speed)
{

    if (speed < 0.5f || _ani.pixelsRight(_x,_y,lcd) ) {
        _sprintright = 0;                                                   //if collision or speed drops below 0.5 cancell sprint
    }

    if (speed > -0.5f || _ani.pixelsLeft(_x,_y,lcd) ) {
        _sprintleft = 0;                                                   //if collision or speed drops below 0.5 cancell sprint
    }
    
    //printf("_sprintleft = %d, _sprintright = %d", _jump;  //uncoment to print for testing

}

//runs blockhead's alive sequnce untill _death flag turns to one (as a result of death)
void Blockhead::runner_state(N5110 &lcd, Gamepad &pad, float speed)
{

    if (_death == 0) {
        alive_sequence(lcd, speed);                         //whilst game over flag is 0, runs alive sequence animation
    } else {
        death_sequence(lcd, pad);                           //when game over flag turns 1, run death sequence animation)
    }



}


//displays the correct animation depending on runner state  (for example when moving slowly walking animation is displayed)
void Blockhead::alive_sequence(N5110 &lcd, float _speed)    
{
    if (_ani.pixelsRight(_x, _y, lcd) && (_fall > 0 || _jump > 0 ) && (_d3 != 3 && _d4 !=3)) {                                  //if by right wall in air,
        _ani.wallclingRight(_x, _y, lcd);                                                                                       //display wall cling right spite
    } else if (_ani.pixelsLeft(_x, _y, lcd) && (_fall > 0 || _jump > 0 ) && (_d3 != 3 && _d4 !=3)) {                            //if by left wall in air,
        _ani.wallclingLeft(_x, _y, lcd);                                                                                        //display wall cling left sprite
    } else if ( ( (_wjr > 0 && _wjr < 5) || (_speed >= 0.1f && (_fall > 0 || _jump > 0)) ) && (_d3 != 3 && _d4 != 3) ) {        //if falling right,
        _ani.fallingRight(_x, _y, lcd);                                                                                         //display falling left sprite
    } else if ( ( (_wjl > 0 && _wjl < 5) || (_speed < -0.1f && (_fall > 0 || _jump > 0 )) ) && (_d3 != 3 && _d4 != 3) ) {       //if fallig left,
        _ani.fallingLeft(_x, _y, lcd);                                                                                          //display falling left sprite
    } else if ( (_wjr ==9 || _fall > 0 || _jump > 0 ) && (_d3 != 3 && _d4 !=3) )  {                                             //if falling,
        _ani.falling(_x, _y, lcd);                                                                                              //display falling sprite
    } else if (_speed > 0.5f) {                                                                                                 //if speed is more than 0.5
        run_sequence_right(lcd);                                                                                                //peform run right animation
    } else if (_speed > 0.1f) {                                                                                                 //if only more than 0
        walk_sequence_right(lcd);                                                                                               //peform walk right animation
    } else if (_speed < -0.5f) {                                                                                                //if speed less than -0.5
        run_sequence_left(lcd);                                                                                                 //peform run left animation
    } else if (_speed <  -0.1f) {                                                                                               //if only less than 0
        walk_sequence_left(lcd);                                                                                                //peform walk left animation
    } else {                                                                                                                    //if none of the above
        _ani.standing(_x, _y, lcd);                                                                                             //display standing sprite!
    }


}


//displays running animation (right)
void Blockhead::run_sequence_right(N5110 &lcd)
{
    _runani++;
    if (_runani == 1) {                                                 //when running right, cr alterntes between 1 and 2,
        _ani.runRightOne(_x, _y, lcd);                                  //displaying the run right sprites consecutively thus creating a running animation
    } else if (_runani == 2) {
        _ani.runRightTwo(_x, _y, lcd);
        _runani = 0;
    }



}


//displays running animation (left)
void Blockhead::run_sequence_left(N5110 &lcd)
{
    _runani++;
    if (_runani == 1) {                                                 //when running left, cr alterntes between 1 and 2,
        _ani.runLeftOne(_x, _y, lcd);                                   //displaying the run left sprites consecutively thus creating a running animation
    } else if (_runani == 2) {
        _ani.runLeftTwo(_x, _y, lcd);
        _runani = 0;
    }



}


//displays walking animation (right)
void Blockhead::walk_sequence_right(N5110 &lcd)
{
    _walkani++;
    if (_walkani == 1) {
        _ani.walkRightOne(_x, _y, lcd);                                     //when walking right, cw runs between 1 2 3 4,
    } else if (_walkani == 2) {                                             //displaying the walk right sprites consecutively thus creating a walking animation
        _ani.walkRightTwo(_x, _y, lcd);
    } else if (_walkani == 3) {
        _ani.walkRightThree(_x, _y, lcd);
    } else if (_walkani == 4) {
        _ani.walkRightFour(_x, _y, lcd);
        _walkani = 0;
    }


}


//displays walking animation (left)
void Blockhead::walk_sequence_left(N5110 &lcd)
{
    _walkani++;
    if (_walkani == 1) {                                                 //when walking left, cw runs between 1 2 3 4,
        _ani.walkLeftOne(_x, _y, lcd);                                   //displaying the walk right sprites consecutively thus creating a walking animation
    } else if (_walkani == 2) {
        _ani.walkLeftTwo(_x, _y, lcd);
    } else if (_walkani == 3) {
        _ani.walkLeftThree(_x, _y, lcd);
    } else if (_walkani == 4) {
        _ani.walkLeftFour(_x, _y, lcd);
        _walkani = 0;
    }


}


//displays death animation 
void Blockhead::death_sequence(N5110 &lcd, Gamepad &pad)
{

    if (_death == 1) {
        _ani.deathOne(_x,_y,lcd);                                       //when cd activated by gameover, run death sequence animation
        pad.tone(261.62, 0.1); //c3                                     //a tone is played each fram, creating a disonant tune along with the animation
    } else if (_death == 2) {
        _ani.deathTwo(_x,_y,lcd);
        pad.tone(97.999, 0.1); //g2
    } else if (_death == 3) {
        _ani.deathThree(_x,_y,lcd);
        pad.tone(207.652, 0.1);  //g1#
    } else if (_death == 4) {
        _ani.deathFour(_x,_y,lcd);
        pad.tone(155.563, 0.1);   //d1#
    }
    _death++;


}


//changes level when either side of screen
int Blockhead::next_level()
{
    if (_x > 76) {  
        _x = -1;                                                        //when blockhead goes off right side of screen,
        _level++;                                                       //level increments, and blockhead appears at left side
    } else if (_x < -1) {
        _x = 76;                                                        //when blockhead goes off left side of screen,
        _level--;                                                       //level deccrements, and block head appears at right side
    }
    
    //printf("_level = %d", _level);  //uncoment to print for testing

    return _level;

}


//checks if blockhead is on horizontal platform
int Blockhead::on_hoz_check(Pos pos)
{
    int d;
    int c = 0;

    for (int i = 0; i < pos.l; i++) {                                                       //for the entire lenth of moving platform one
        if (((_x+2 == pos.x+i) || (_x+6 == pos.x+i)) &&(_y+12 == pos.y)) {                  //checks if cordinates of horizontal moving platform one,
            c++;                                                                            //are the same as blockheads's underside cordinates, if so c++
        }
    }
    if (c > 0) {                                                                            //if c > 0 blockhead is on the moving platform,
        d = pos.d;                                                                          //then d = direction of moving platform (0 = right, 1 - left)
    } else {                                                                                //if not then d = 2 (insignificant number)
        d = 2;
    }
    
    //printf("d = %d", d);  //uncoment to print for testing

    return d;                                                                               //d is then used to move blcokhead in the direction of the platform he is on
}


//checks if blockhead is by right of horizontal platform
int Blockhead::by_hoz_check_right(Pos pos)
{
    int c = 0;
    int d;

    for (int i = 0; i < 12; i ++) {                                                                                             //for 12 (height of blockhead)
        if ((_x-1 == pos.x + pos.l) && ((_y + i == pos.y) || (_y + i == pos.y+1) || (_y + i == pos.y+2))) {                     //check if cordinates of right side horizontal moving platform one
            c++;                                                                                                                //are the same as blockhead's left side
        }
    }

    if (c > 0 && pos.d == 0) {                                                              // if c > 0 and the platform is moving right
        d = 1;                                                                              // then d = 1,
    } else {                                                                                // otherwise d = 0 (insignificant number)
        d = 0;
    }
    
    //printf("d = %d", d);  //uncoment to print for testing

    return d;                                                                               //d is then used to move blockhead in the direction the platform is pushing against him
}


//checks if blockhead is by left of horizontal platform
int Blockhead::by_hoz_check_left(Pos pos)
{
    int c = 0;
    int d;

    for (int i = 0; i < 12; i ++) {                                                                                             //for 12 (height of blockhead)
        if ((_x+9 == pos.x) && ((_y + i == pos.y) || (_y + i == pos.y+1) || (_y + i == pos.y+2))) {                             //check if cordinates of left side horizontal moving platform one
            c++;                                                                                                                //are the same as blockhead's right side
        }
    }

    if (c > 0 && pos.d == 1) {                                                              //if c > 0 and the platform is moving right
        d = 1;                                                                              //then d = 1,
    } else {                                                                                //otherwise d = 0 (insignificant number)
        d = 0;
    }
    
    //printf("d = %d", d);  //uncoment to print for testing

    return d;                                                                               //d is then used to move blockhead in the dicrection the platform is pushing against him
}


//checks if blockhead is on horizontal platform (2)
int Blockhead::on_hoz_2_check(Pos pos)
{
    int d;
    int c = 0;

    for (int i = 0; i < pos.l2; i++) {
        if (((_x+2 == pos.x2+i) || (_x+6 == pos.x2+i)) &&(_y+12 == pos.y2)) {               //for the entire lenth of moving platform one
            c++;                                                                            //checks if cordinates of horizontal moving platform one,
        }                                                                                   //are the same as blockheads's underside cordinates, if so c++
    }
    if (c > 0) {
        d = pos.d2;                                                                         //if c > 0 blockhead is on the moving platform,
    } else {                                                                                //then d = direction of moving platform (0 = right, 1 - left)
        d = 2;                                                                              //if not then d = 2 (insignificant number)
    }
    
    //printf("d = %d", d);  //uncoment to print for testing

    return d;                                                                               //d is then used to move blcokhead in the direction of the platform he is on
}


//checks if blockhead is by right of horizontal platform (2)
int Blockhead::by_hoz_2_check_right(Pos pos)
{
    int c = 0;
    int d;

    for (int i = 0; i < 12; i ++) {                                                                                             //for 12 (height of blockhead)
        if ((_x-1 == pos.x2 + pos.l2) && ((_y+i == pos.y2) || (_y+i == pos.y2+1) || (_y + i == pos.y2+2))) {                    //check if cordinates of right side horizontal moving platform one
            c++;                                                                                                                //are the same as blockhead's left side
        }
    }
    //if c > 0 and the platform is moving right
    if (c > 0 && pos.d2 == 0) {                                                             //then d = 1,
        d = 1;                                                                              //otherwise d = 0 (insignificant number)
    } else {
        d = 0;
    }
    
    //printf("d = %d", d);  //uncoment to print for testing

    return d;                                                                               //d is then used to move blockhead in the direction the platform is pushing against him
}


//checks if blockhead is by left of horizontal platform (2)
int Blockhead::by_hoz_2_check_left(Pos pos)
{
    int c = 0;
    int d;

    for (int i = 0; i < 12; i ++) {                                                                                             //for 12 (height of blockhead)
        if ((_x+9 == pos.x2) && ((_y + i == pos.y2) || (_y + i == pos.y2+1) || (_y + i == pos.y2+2))) {                         //check if cordinates of left side horizontal moving platform one
            c++;                                                                                                                //are the same as blockhead's right side
        }
    }

    if (c > 0 && pos.d2 == 1) {                                                             //if c > 0 and the platform is moving right
        d = 1;                                                                              //then d = 1,
    } else {                                                                                //otherwise d = 0 (insignificant number)
        d = 0;
    }
    
    //printf("d = %d", d);  //uncoment to print for testing

    return d;                                                                               //d is then used to move blockhead in the dicrection the platform is pushing against him
}


//check is blockhead is on vertical moving platform
int Blockhead::on_ver_check(Pos pos) // add the _x part..
{
    int d;
    int c = 0;

    for (int i = 0; i < pos.vl+1; i++) {                                                    //for width of vertical moving platform
        if ((_y+11 == pos.vy-1) && ((_x == pos.vx+i) || (_x+1 == pos.vx+i) || (_x+2 == pos.vx+i) || (_x+6 == pos.vx+i) || (_x+7 == pos.vx+i) || (_x+8 == pos.vx+i))) {            //check if cordinates of top of vertical moving platform,
            c++;                                                                            //are the same as blockheads underside
        }
    }
    
    if (c > 0) {                                                                            //if c > 0 blockhead is on the moving platform,
        d = pos.vd+3; //3 = down 4 = up                                                     //then d = direction of moving platform (3 = down, 4 = up)
    } else {                                                                                //if not then d = 2 (insignificant number)
        d = 2; //not moving
    }
    
    //printf("d = %d", d);  //uncoment to print for testing

    return d;
}


//check is blockhead is on vertical moving platform (2)
int Blockhead::on_ver_2_check(Pos pos)
{
    int d;
    int c = 0;

    for (int i = 0; i < pos.vl2+1; i++) {                                                   //for width of vertical moving platform
        if ((_y+11 == pos.vy2-1) &&  ((_x == pos.vx2+i) || (_x+1 == pos.vx2+i) || (_x+2 == pos.vx2+i) || (_x+6 == pos.vx2+i) || (_x+7 == pos.vx2+i) || (_x+8 == pos.vx2+i)) ) {   //check if cordinates of top of vertical moving platform
            c++;                                                                            //are the same as blockheads underside
        }
    }

    if (c > 0) {                                                                            //if c > 0 blockhead is on the moving platform,
        d = pos.vd2+3; //3 = down 4 = up                                                    //then d = direction of moving platform (3 = down, 4 = up)
    } else {                                                                                //if not then d = 2 (insignificant number)
        d = 2; //not moving
    }
    
    //printf("d = %d", d);  //uncoment to print for testing

    return d;
}


//checks if blockhead is being crushed by vertical moving platform 
int Blockhead::crushed_by_ver(Pos pos)  
{
    int c = 0;
    int g = 0;

    for (int a = 0; a < 9; a++) {                                                                  //for the height of blockhead,
        for (int i = 0; i < pos.vl+1; i++) {                                                       //and the width of the vertical moving platform,
            if ((_y+10-a == pos.vy-1) &&  ((_x+2 == pos.vx + i) || (_x+6 == pos.vx + i)) ) {       //check if the cordinates of width of vertical moving platform
                c++;                                                                               //are the same as blockehads, starting from bottom -1 and up.
            }
        }
    }

    for (int a = 0; a < 9; a++) {                                                                   //for the height of blockhead
        for (int i = 0; i < pos.vl+1; i++) {                                                        //and the width of the vertical moving platform
            if ((_y+a == pos.vy+pos.vh) &&  ((_x+2 == pos.vx + i) || (_x+6 == pos.vx + i)) ) {      //check if the cordinates of width of vertical moving platform
                c++;                                                                                //are the same as blockhead's, starting from top -1, and down.
            }
        }
    }

    if (c > 0) {                                                                                    //if so, g = 1 .. this means that blockhead his being crushed
        g = 1;
    } else {
        g = 0;
    }
    
    //printf("g = %d", g);  //uncoment to print for testing

    return g;
}


//checks if blockhead is being crushed by vertical moving platform (2)
int Blockhead::crushed_by_ver_2(Pos pos)
{
    int c = 0;
    int g = 0;

    for (int a = 0; a < 9; a++) {                                                                   //for the height of blockhead,
        for (int i = 0; i < pos.vl2+1; i++) {                                                       //and the width of the vertical moving platform two,
            if ((_y+10-a == pos.vy2-1) &&  ((_x+2 == pos.vx2 + i) || (_x+6 == pos.vx2 + i)) ) {     //check if the cordinates of width of vertical moving platform
                c++;                                                                                //are the same as blockehads, starting from bottom -1 and up.
            }
        }
    }

    for (int a = 0; a < 9; a++) {                                                                   //for the height of blockhead
        for (int i = 0; i < pos.vl2+1; i++) {                                                       //and the width of the vertical moving platform two
            if ((_y+a == pos.vy2+pos.vh2) &&  ((_x+2 == pos.vx2 + i) || (_x+6 == pos.vx2 + i)) ) {  //check if the cordinates of width of vertical moving platform
                c++;                                                                                //are the same as blockhead's, starting from top -1, and down.
            }
        }
    }

    if (c > 0) {
        g = 1;                                                                                      //if so, g = 1 .. this means that blockhead is being crushed
    } else {
        g = 0;
    }
    
    //printf("g = %d", g);  //uncoment to print for testing

    return g;
}


//checks if blockhead has hit spikes
int Blockhead::spike_hit(N5110 &lcd, Pos pos)
{
    int c = 0;
    int g;

    for (int i = 0; i < pos.sl; i++) {                                                                                                      //for length of spikes,
        if (lcd.getPixel(pos.sx+i, pos.sy-3)) {                                                                                             //check if pixels above,
            c++;                                                                                                                            //if plus c
        }
    }
    if (lcd.getPixel(pos.sx-1, pos.sy) || lcd.getPixel(pos.sx, pos.sy-1) || lcd.getPixel(pos.sx, pos.sy-2)) {                               //check if pixels to left side of spikes
        c++;                                                                                                                                //if so plus c
    }

    if (lcd.getPixel(pos.sx+pos.sl+1, pos.sy) || lcd.getPixel(pos.sx+pos.sl, pos.sy-1) || lcd.getPixel(pos.sx+pos.sl, pos.sy-2)) {          //checl if pixels to right side of spikes
        c++;                                                                                                                                //if so plus c
    }


    if (c > 0) {                                                                                                //if c > 0, g = 1.. this meand that blockhead has hit the spikes!
        g = 1;
    } else {
        g = 0;
    }
    
    //printf("g = %d", g);  //uncoment to print for testing

    return g;
}


//returns 1 if blockhead falls of screen
int Blockhead::fallen(Gamepad &pad)
{
    int g;

    if (_y > 51) {                                                      //if blockhead falls of screen,
        g = 1;                                                          //g = 1
        fall_tune(pad);
    } else {
        g = 0;
    }

    //printf("g = %d", g);  //uncoment to print for testing

    return g;

}


//plays desending tune to play once blockhead falls off screen.
void Blockhead::fall_tune(Gamepad &pad)
{

    pad.tone(1046.502, 0.1);                                            //desending tune to play once blockhead falls off screen.
    wait(0.1);
    pad.tone(932.328, 0.1);
    wait(0.1);
    pad.tone(622.254, 0.1);
    wait(0.1);
    pad.tone(523.251, 0.1);
    wait(0.1);
    pad.tone(466.164, 0.1);
    wait(0.1);
    pad.tone(369.994, 0.1);
    wait(0.1);
    pad.tone(293.665, 0.1);
    wait(0.1);
    pad.tone(261.626, 0.1);
    wait(0.1);
}


//checks if blcokhead is on or by any of the platforms
void Blockhead::platform_check(Pos pos)
{
    _d = on_hoz_check(pos);                                     //checks if blochead on horizontal (hoz) moving platform
    _r = by_hoz_check_right(pos);                               //checks if blockhead by hoz moving platform
    _l = by_hoz_check_left(pos);
    _d2 = on_hoz_2_check(pos);                                  //checks if blockhead on second horizontal moving platform
    _r2 = by_hoz_2_check_right(pos);
    _l2 = by_hoz_2_check_left(pos);
    _d3 = on_ver_check(pos);                                    //checks if blockhead on vertical moving platform
    _d4 = on_ver_2_check(pos);                                  //checks if blockhead on second vertical moving platform
}


//moves blockhead according to what platform he is on
void Blockhead::on_platform(N5110 &lcd)                                 //if on platform, move blockhead in the  direction the platform is moving
{

    if (_d == 0 || _r == 1 || _d2 == 0 || _r2 == 1) {                   //move blockhead right if on/by a horizontal platform moving right
        move_right(lcd, 1);
    } else if (_d == 1 || _l == 1 || _d2 == 1 || _l2 == 1) {            //move blockhead left if on/by a horizontal platform moving left
        move_left(lcd, 1);
    } else if (_d3 == 4 || _d4 == 4) {                                  //move blockhead up if on a vertical moving platform
        move_up(lcd, 1);
    }

}