ELEC2645 (2019/20) / Mbed 2 deprecated ELEC2645_Project_el19tb

Dependencies:   mbed

Frogger/Frogger.cpp

Committer:
el19tb
Date:
2020-05-17
Revision:
34:501474a4dc59
Parent:
29:2151cd327a36

File content as of revision 34:501474a4dc59:

#include "Frogger
#include "Menu.h"
#include "GraphicEngine.h"
#include <vector>
#include <stdio.h> 
#include <cstddef>

//there will be multiple cars       
Car firstLane[2];
Car secondLane[2];  
Car thirdLane[3];
Car fourthLane[3];
Car log1Lane[2];
Car lo[2];
Car logger[2];
Car vop[2];


bool frogLog = false; 
bool frogDie = false; // whenever the frog is above safety lane in the middle
bool attach = false;

Frogger::Frogger(GraphicEngine *engine, Level *level, Frog *frog)
{
    this->graphics = engine; // get the renderer in place
    this->level = level; // one level object per engine
    this->frog = frog; // one frog object per run
    
    initializeParams(); // initialize the software parameters
    initializeEmbeddedSystem(); // initialize the hardware paramaters
}

void Frogger::initializeParams()
{
    // screen sizes
    screenW = 84; // width
    screenH = 48; // height
    
    // grid values
    grid = 4; // size of game grid system
    grid_width = 22; // size of screen width in grid units
}

void Frogger::initializeEmbeddedSystem()
{
    //game setup
    graphics.init(); // initialize the LCD object
    graphics.contrast(); // set the contrast to 0.4
    graphics.backLightOn(); // turn on the backlight
    gamepad.init();  // initialize the actual game pad 
}

//main function that starts the game
void CrossyChicken::start(){     
    
    row_number = 1;

    //keep reading and processing user input
    while(1) {
        graphics.clear();
          
        for(int i = 0; i < 2; i++){
            moveCar(&firstLane[i], 2, (-2)); // change x position (moving)
        }
        
        for(int x = 0; x < 2; x++){
            moveCar(&secondLane[x], 1, 1);
        }
        
        for(int t = 0; t < 3; t++){
            moveCar(&thirdLane[t], 2, 1);
        }
        
        for(int c = 0; c < 3; c++){
            moveCar(&fourthLane[c], 2, 1);
        }
        
        for(int v = 0; v < 2; v++){
            moveCar(&log1Lane[v], 1, 1);
        }
       
        for(int b = 0; b < 2; b++){
            moveCar(&lo[b], 2, 1);
           // moveCar(&logger[b], 2, 2);
            moveCar(&vop[b], 1, 2);

        }
        
        graphics.showCar(firstLane);
        graphics.showCar(secondLane);
        graphics.showCar(thirdLane);
        graphics.showCar(fourthLane);
        graphics.showCar(log1Lane);
        graphics.showCar(lo);
        graphics.showCar(logger);
        graphics.showCar(vop);

        graphics.showChicken(); 
        process_input();
        
        // now when the chicken is above the safety 
        // lane we need to ensure that it only can go on logs
        if(chicken.y < screenH - grid*6){
            frogDie = true;  // frog can die if it is in water  

            //if it is not in a log
            for(int x = 0; x < 2; x++){
                setCollision(&log1Lane[x]);
                setCollision(&lo[x]);
                setCollision(&logger[x]);
                setCollision(&vop[x]);

                if(attach){
                    frogOnLog(&log1Lane[x]);   
                    frogOnLog(&lo[x]);   
                    frogOnLog(&logger[x]);   
                    frogOnLog(&vop[x]);   

                }
            }
            
            if(!attach){
                graphics.print();    
            }    
        }
            
        graphics.refresh();
        wait_ms(70);
    } 
}

// log intersects then frog.x = log[i].speed
// frog is attached function
// detach the frog when user goes up or down
// if the frog is back to the safe zone detatch also
// whenever the frog moves detach
//A moves right
//X moves upward
//B moves downward
//Y moves left
void CrossyChicken::process_input() {
    //determine the input 
    /* make this a switch statement */
    if(gamepad.A_pressed()){
        moveChicken(1,0);
        attach = false;
    } else if(gamepad.X_pressed()){
        moveChicken(0,-1);
        attach = false;
    } else if(gamepad.B_pressed()){
        moveChicken(0,1);
        attach = false;
    } else if(gamepad.Y_pressed()){
        moveChicken(-1,0);
        attach = false;
    } 
}

void CrossyChicken::createMultipleSafetyLane()
{
    int min = 0; // start from the top, and draw till 0 
    int max = grid_width; // draw 21 objects to the first lane
    int row = 1;
    int x_fac = 1;
    
    for(int x = 0; x < 2; x++){
        creatSafetyObject(min, max, row, x_fac);
        row += 6; // increment the rows to the next lane
        min +=  22; // fill in the vector with 22 grid units
        max += 22;
    }      
}

void CrossyChicken::createSafetyObject(int min, int max, int row, int x_fac)
{
    int state = 1;
    
    for(int z = 0; z < 22; z++){
        switch(state)
        {
            case 1:
                safety_lane.push_back(z/x_fac, row, 'K'); // safety lane so row 0
                state++;
                break;
            case 2: 
                safety_lane.push_back(z/x_fac, row, 'P'); // safety lane so row 0
                state--; // back to inital state
                break;
        }
    }    
}

void CrossyChicken::drawSafety()
{
    graphics.drawSafetyLanes(safety_lane);   
}


void CrossyChicken::createMultipleRoadLane()
{
    int min = 0; // start from the top, and draw till 0 
    int max = grid_width; // draw 21 objects to the first lane
    int row = 1;
    
    for(int x = 0; x < 4; x++){
        createRoadLane(min, max, row);
        row++; // increment the rows to the next lane
        min +=  22; // fill in the vector with 22 grid units
        max += 22;
    } 
}

// every level is going to have the same amount of blocks
void CrossyChicken::createRoadLane(int min, int max, int row)
{       
    std::vector<Background>::size_type it;
    
    // fill the road objects
    for(int it = min; it != max; it++){
        roads.push_back(it/row, row); // it is the x pos of the obj, row is the y pos
    }
}

void CrossyChicken::drawRoadObjects()
{
    graphics.getRoadObjects(roads);
}

void CrossyChicken::createMultipleLanesWater()
{ 
    int min = 0; // start from the top, and draw till 0 
    int max = grid_width; // draw 21 objects to the first lane
    int row = 7;
    int x_fac = 1;
    
    for(int x = 0; x < 3; x++){
        if(x == 1){ 
            createWaterLane(min, max, row, -0.6); // second row goes left
        } else {
            createWaterLane(min, max, row, 0.4); // rest of the rows go right
        }
        
        row++; // increment the rows to the next lane
        min += grid_width; // fill in the vector with 22 grid units
        max += grid_width;
    }    
}

void CrossyChicken::createWaterLane(int min, int max, int row, float speed, int x_fac){
    int state = 1;    
    for(it = min; it < max; it++)
    {
        switch(state)
        {
            case 1: // initial state
                water[it].push_back(it/x_fac, row, speed, 'F'); // first type of water
                state++; // transition to next state
                break;
            case 2: 
                water[it].push_back(it/x_fac, row, speed, 'S'); // first type of water
                state++; // transition to state 3
                break;       
            case 3:
                water[it].push_back(it/x_fac, row, speed, 'T'); // first type of water
                state = 1; // back to start state
                break;
        } 
    }   
}

// moves the water based on the velocity
void CrossyChicken::moveWater(std::vector<Water>& water_lanes)
{
    for(unsigned int i = 0; i < water_lanes.size(); i++)
    {
        if(water_lanes(i).speed > 0){
            water_lanes(i).x += speed;   
        } else {
            water_lanes(i).x -= speed;   
        }
    }
    
    loopWater(water_lanes); 
}


void CrossyChicken::loopWater(std::vector<Water>& water_lanes)
{ 
    for(unsigned int i = 0; i < water_lanes.size(); i++)
    {
        if(water_lanes(i).x > 84+grid){
            water_lanes(i).x = -4;   
        } else if(water_lanes[i].x < -4){
            water_lanes(i).x = 84 + grid;   
        }
    }
}

void CrossyChicken::drawWater()
{
    graphics.drawWater(water);         
}

void CrossyChicken::drawEndPost()
{
    graphics.drawGoal(84/2)-grid/2, 48-grid*11);     
}

// make the frog move same speed as log
// if the frog moves then detach
void CrossyChicken::frogOnLog(Car *log) {
   if(log->seperation != 0){
        chicken.x += 1.0;
   }     
}

//moves the chicken around the grid
void CrossyChicken::moveChicken(int xWay, int yWay){
    //increment the left side of the chicken by a value of the grid size
    chicken.x += xWay * 4;
    
    //increment the top side by a value of grid sizw
    chicken.y += yWay * 4;
    
    chicken.left_side = chicken.x;
    chicken.right_side = grid + chicken.x;
    chicken.up = chicken.y;
    chicken.down = grid + chicken.y;
        
    //display the new state of the chicken
    //graphics.showChicken();
    
    //wait_ms(30);
}

void CrossyChicken::moveCar(Car *car, int dir, int x) {
    car->speedMedium(dir, x);
    
    // check if car goes out of bounds
    if(car->vehicle.x > 84+grid){
        car->vehicle.x = -4;
        
    } else if(car->vehicle.x < -4){ 
        car->vehicle.x = 84 + grid;
    }
}

// debug
void CrossyChicken::setCollision(Car *car){
    
    float other_bottom = car->vehicle.height + car->vehicle.y;
    
    
    if(!(chicken.up >= other_bottom || 
    (chicken.right_side <= car->vehicle.x)  ||
    (chicken.down <= car->vehicle.y) ||
    chicken.left_side >= (car->vehicle.width + car->vehicle.x))){
        graphics.printTest();
        
        if(chicken.y < screenH - grid*6){
            attach = true;
        } else { 
            attach = false;
        } 
    }
}
 
bool CrossyChicken::returnCollision(Car* log){      
    
    float ob = log->vehicle.height + log->vehicle.y;
    
    if(!(chicken.up >= ob||
    (chicken.right_side <= log->vehicle.x)  ||
    (chicken.down <= log->vehicle.y) ||
    chicken.left_side >= (log->vehicle.width + log->vehicle.x))){
        return true;
    }
}