Uses accompanying Basket, Objects and Fruit libraries to create Fruit Basket game. If an object is caught, points are added; if an object in missed, a 'life' is lost.

Dependents:   Game_Controller_Project

Catch_Model.cpp

Committer:
Nathanj94
Date:
2017-05-04
Revision:
18:99ccfa1bb2ca
Parent:
16:dae98691cc0e

File content as of revision 18:99ccfa1bb2ca:

#include "Catch_Model.h"

Catch_Model::Catch_Model()
{
    
}

Catch_Model::~Catch_Model()
{
    
}
//INITILISATION FUNCTIONS//
//Sets values used to initialise Basket and Objects, sets number of lives
void Catch_Model::init(int basket_y, int basket_width, int objects_speed, int lives)
{
    _basket_y = basket_y;
    _basket_width = basket_width;
    _objects_speed = objects_speed;
    _lives = lives;
    _delay = 1; //if this equals 1, check_a and check_b can be called
    
    basket.init(_basket_y, _basket_width);
    objects.init(_objects_speed);
}

//UPDATE FUNCTIONS//
//Read input of joystick and assign the direction and magnitude to variables
void Catch_Model::input(Gamepad &pad)
{
    _d = pad.get_direction();
    _mag = pad.get_mag();
}

//Update the game score/lives and move the basket/objects
void Catch_Model::update(N5110 &lcd, Gamepad &pad)
{
    check_basket_catch(lcd, pad); //check for basket catch/miss before updating positions
    check_basket_miss(lcd, pad); //as that aspect must take priority
    
    basket.move_stick(_d, _mag);
    basket.move_LR(pad);
    objects.move(_objects_speed);
}

//GAME RULES FUNCTIONS//
//Check if the object is caught
void Catch_Model::check_basket_catch(N5110 &lcd, Gamepad &pad)
{
   int b_x_pos = basket.get_x();
   int b_y_pos = basket.get_y();
   int o_x_pos = objects.get_x();
   int o_y_pos = objects.get_y();
   
   //object y greater than/equal to basket y...
   //...and object x greater than/equal to basket x...
   //...and object x less than/equal to basket x+6 to compensate for width of object beyond x+6 
    if(
       (o_y_pos >= b_y_pos) &&    
       (o_x_pos >= b_x_pos) &&    
       (o_x_pos <= (b_x_pos + 6)) 
       ) {
           pad.tone(1000, 0.2);
           objects.undraw(lcd); //FILL_WHITE so object disappears
           add_score(); //object has a variable that adds correct amount of score
           objects.init(_objects_speed); //drop another object upon contact
           
           //printf("basket catch\n");
    }
}

//Check if the object is not caught
void Catch_Model::check_basket_miss(N5110 &lcd, Gamepad &pad)
{
   int b_y_pos = basket.get_y(); //x co-ordinates unnecessary
   int o_y_pos = objects.get_y(); //if x does not satisfy check_basket_catch, it will satisfy this
   
   int score_var;
   score_var = objects.get_score_var(); 
   
   if (o_y_pos > b_y_pos) {
       objects.undraw(lcd);
       if (score_var != 5) { //if antifruit misses do nothing, otherwise reduce lives
           _lives--;
        }
        pad.tone(100, 0.2);
        objects.init(_objects_speed); //drop another object upon contact
        
        //printf("basket miss\n");
    } 
}

//Check which object is current and add appropriate score
void Catch_Model::add_score()
{
    int score_var;
    score_var = objects.get_score_var();
    
    if (score_var == 1) { //strawberry = 1
        basket.add_score_1();
    } else if (score_var == 2) { //pineapple = 2
        basket.add_score_2();
    } else if (score_var == 3) { //pear = 5
        basket.add_score_5();
    } else if (score_var == 4) { //melon = 10
        basket.add_score_10();
    } else { //antifruit - if caught, reduce lives instead of add score
        _lives--;
    }
    //printf("add score\n");
}

//Return number of lives
int Catch_Model::get_lives() 
{
    return _lives;
}

//BUTTON FUNCTIONS//
//If A is pressed, reset the object
void Catch_Model::check_a(N5110 &lcd, Gamepad &pad)
{
    if (
        (pad.check_event(Gamepad::A_PRESSED) == true) &&
        (_delay == 1) //delay stops powerups from being over-used
        ) {
            objects.undraw(lcd);
            objects.init(_objects_speed);
            
            //while _delay = 0, A and B can't be used...
            //...in 10 seconds _delay = 1, A and B can be used again
            _delay = 0;
            timeout.attach(this, &Catch_Model::set_delay, 10.0); 
            
            //printf("A pressed\n");
        }
    
}

//If B is pressed, give another life
void Catch_Model::check_b(N5110 &lcd, Gamepad &pad)
{
    if (
        (pad.check_event(Gamepad::B_PRESSED) == true) &&
        (_delay == 1) //delay stops powerups from being over-used
        ) {
            _lives++;
            
            //while _delay = 0, A and B can't be used...
            //...in 10 seconds _delay = 1, A and B can be used again
            _delay = 0;
            timeout.attach(this, &Catch_Model::set_delay, 10.0);
            
            //printf("B pressed\n");
        }
    
}

//10 seconds after A or B is pressed, _delay = 1
void Catch_Model::set_delay()
{
    _delay = 1;
}

//DISPLAY FUNCTIONS//
//Re-draw the screen after updates to positions, scores etc are made
void Catch_Model::draw(N5110 &lcd, Gamepad &pad)
{
    basket.draw(lcd);
    objects.draw(lcd);
    print_score(lcd);
    print_lives(lcd);
    print_delay(lcd);
    
    if(get_lives() == 0)
    {
        do{
            lcd.clear();
            final_score(lcd);
        } while (pad.check_event(Gamepad::START_PRESSED) == false);
    }
}

//Get the number of lives and print on the display
void Catch_Model::print_lives(N5110 &lcd)
{
    char buffer[14];
    int lives = get_lives();
    
    int print_lives = sprintf(buffer, "LIVES:%d", lives);
    if (print_lives <= 14) {
        lcd.printString(buffer,0,0);
        lcd.refresh();
    }
}

//Get the score and print on the display
void Catch_Model::print_score(N5110 &lcd)
{
    char buffer[14];
    int score = basket.get_score();
    
    int print_score;
    
    if ((score == 0)||(score <= 9)) { //if loop keeps the length of the string fixed...
        print_score = sprintf(buffer, "000%d", score);
    } else if (score <= 99) {
        print_score = sprintf(buffer, "00%2d", score);
    } else if (score <= 999 ) {
        print_score = sprintf(buffer, "0%3d", score);
    } else {
        print_score = sprintf(buffer, "%4d", score);
    } //...with maximum printable score of 9999
    
    if (print_score <= 14) {
        lcd.printString(buffer,59,0);
        lcd.refresh();
    }
}

void Catch_Model::final_score(N5110 &lcd)
{
    char buffer[14];
    int score = basket.get_score();
    
    int print_score;
    
    if ((score == 0)||(score <= 9)) { //if loop keeps the length of the string fixed...
        print_score = sprintf(buffer, "000%d", score);
    } else if (score <= 99) {
        print_score = sprintf(buffer, "00%2d", score);
    } else if (score <= 999 ) {
        print_score = sprintf(buffer, "0%3d", score);
    } else {
        print_score = sprintf(buffer, "%4d", score);
    } //...with maximum printable score of 9999
    
    lcd.printString("   GAME OVER  ",0,2);
    if (print_score <= 14) {
        lcd.printString(buffer,34,3);
        lcd.refresh();
    }
}

//Print a tick if _delay = 1, otherwise print a cross
void Catch_Model::print_delay(N5110 &lcd)
{
    if (_delay == 1) {
        lcd.drawLine(46,4,50,8,1);
        lcd.drawLine(50,8,54,0,1);
        } else {
            lcd.drawLine(46,0,54,8,1);
            lcd.drawLine(46,8,54,0,1);
        }
}