ELEC2645 (2015/16) / Mbed 2 deprecated HarryPetrovicPong

Dependencies:   N5110 mbed

Fork of 2645_Physics_Engine_Example by Craig Evans

functions.h

Committer:
HarryPetrovic1
Date:
2016-05-05
Revision:
1:6632d8423c65

File content as of revision 1:6632d8423c65:

#include "mbed.h"
#include "N5110.h"
#include "data.h"

/**@file functions.h
@brief File containing functions and actions within the game
@author Harry Petrovic
@date May 2016
*/



/**initialises display so that you can view images upon LCD screen*/

void init_display(); 

/** sets the initial position, velocity and acceleration when the game starts and when the computer scores

    @param pos.x - initial x position
    
    @param pos.y - initial y position
   
    @param vel.x - initial x direction velocity
    
    @param vel.y -initial y direction velocity
    
    @param acc.x - initial x direction acceleration, starts it off moving towards the right
    
    @param acc.y -initial y direction acceleration, starts it off moving towards ground
    */


void init_ball();


/** sets the initial position, velocity and acceleration when the player scores

    @param pos.x - initial x position
    
    @param pos.y - initial y position
   
    @param vel.x - initial x direction velocity
    
    @param vel.y -initial y direction velocity
    
    @param acc.x - initial x direction acceleration, starts it off moving towards the left
    
    @param acc.y -initial y direction acceleration, starts it off moving towards ground
    */

void player_Score_Position(); 

void game_timer_isr();


/** Draws the ball and updates the screen, called from the Nokia 5110 library
     taken from "2645_Physics_Engine_Example"

@param  pos.x -the position of the ball is drawn, corresponding to the calculated position.

@param  pos.y-the position of the ball is drawn, corresponding to the calculated position.

@param radius - deffined as 2

@param fill - set as 0.5 so that it is just an outline


*/ 
void redraw_screen();


/** Calculates the new position (pos+vel) and velocity (vel+acc) of the ball 
    taken from 2645_Physics_Engine_Example and subsequently adapted

@param vel.x - The current x velocity of ball

@param vel.y - The current y velocity of ball

@param acc.x - The current x acceleration of ball

@param acc.y - The current y acceleration of ball

@param pos.x The current x position of ball

@param pos.y - The current y position of ball

@returns vel.x - New calculated x velocity of ball

@returns vel.y - New calculated y velocity of ball

@returns pos.x - New calculated x position of ball

@returns pos.y- New calculated y position of ball

*/


void update_physics_engine();

/** Checks whether or not the ball has come into contact with the paddles, roof or the floor
    taken from 2645_Physics_Engine_Example and subsequently adapted

@param pos.x - The current x position of ball

@param pos.y - The current x position of ball

@param yc - The position of the paddle

@param yp -  the position of user paddle

@return pos.x - if contact has been made new position is given

@return pos.y - if contact has been made new position is given


@return vel.x -  if contact has been made velocity inverted

@return vel.y  if contact has been made velocity inverted

@return acc.x -  if contact has been made acceleration inverted

@return acc.y  if contact has been made acceleration inverted


*/
void check_collisions();


/** sets up the use of the button
*/

void init_K64F();


/** Appears at the start of the game and allows user to choose difficulty

@param yin - used to navigate up and down the menu

@param difficulty - value of 1,2,3 Easy, Med, Hard, sets value in moveComputerPaddle

*/
void menu();


void clearCells();
void refreshCells();

/** allows the user to move their paddle with the joystick

@param yin - gives a reading between 0-1. if below 0.4 yp-- occurs if 0.6 yp++. If inbetween yp = yp

@returns  yp - The co-ordinate of the first pixel within the paddle, moves according to yin value

*/
void moveUserPaddle();

/** Moves the computer paddle


@param pos.y - value is read
@param difficulty - value that is used to set how far off the pace the paddle is

@returns yc - returned from pos.y-difficulty
*/
void moveComputerPaddle();

/**prevents  user paddle moving off screen by forcing position of yp

@param yp - the position of the paddle

*/
void paddleLimits();


/**prevents computer paddle moving off screen by forcing position of yp

@param yc - the position of the paddle

*/
void ComputerpaddleLimits();

/** Determines which player has scored, if any

@param pos.x - The position of the ball

@return computerScore - ++ if ball touches left hand side

@return playerScore - ++ if ball touches right hand side
*/

void Scoring();

/** Resets ball to a position, depending on who scored
 
 @param pos.x - if hits wall the ball will return to default position depending on who scored
 
*/
void resetBall();

/** 

@param - playerScore -the current score of player

@return - message stating victory if playerScore > 10


*/
void victory();
void redraw_screen();

/** 

@param - computerScore -the current score of computer

@return - message stating defeat if playerScore > 10


*/

void loss();





void init_K64F()
{
    select.mode(PullDown);
}

void menu()
{
    while(select) {
        lcd.printString("EASY", 20,1);
        lcd.printString("MED", 20,2);
        lcd.printString("HARD", 20,3);
        if(difficulty == 1) {

        } else if(difficulty == 2) {
        } else if(difficulty ==3) {
        }
        if(yin < 0.6f) {
            difficulty++;
        } else if(yin >0.4f) {
            difficulty--;
        }
        wait(0.1);
    }
}



void clearCells()              //loop and clear
{
    for (int i = 0; i < nx ; i++) {
        for (int j = 0; j < ny ; j++) {
            lcd.clearPixel(i,j);
        }
    }
    lcd.refresh(); //refresh
}

void refreshCells()
{
    for (int i = 0; i< 84 ; i++) {
        for (int j = 0; j < 48 ; j++) {
            if (Array[i][j]) {
                lcd.setPixel(i,j);
            }

            else {
                lcd.clearPixel(i,j);
            }



        }

    }

}



void moveUserPaddle() //used to control paddle

{
    if(yin > 0.6f) { //if potentimeter is greater than 0.6 value the paddle moves up
        yp= yp-3;
    }

    else if(yin < 0.4f) { //as above but the paddle will move down
        yp = yp+3;
    }
}

void moveComputerPaddle()

{
    yc=pos.y-difficulty;
}


void paddleLimits() //makes it so that the paddles remain upon the screen

{
    if (yp <= 0) { //stops paddle disapearing above the screen

        yp=0;
    }

    else if (yp >= 38) { //stops paddle disapearing bellow the screen, value of 40 must be used because of 8 pixel long paddle
        yp=40;
    }
}

void ComputerpaddleLimits() //makes it so that the paddles remain upon the screen

{
    if (yc <= 0) { //stops paddle disapearing above the screen

        yc=0;
    }

    else if (yc >= 38) { //stops paddle disapearing bellow the screen, value of 40 must be used because of 8 pixel long paddle
        yc=38;
    }
}

void Scoring()

{

    if (pos.x - BALLRADIUS < 0) {

        computerScore = computerScore++;

    } else if (pos.x + BALLRADIUS > 83) {

        playerScore = playerScore++;
    }


}

void resetBall()
{

    if (pos.x - BALLRADIUS < 0) {

        wait(0.5);
        init_ball();
    } else if (pos.x + BALLRADIUS > 83) {

        wait (0.5);
        player_Score_Position();
    }


}

void victory()
{

    if (playerScore >=10)

    {
        refreshCells();
        lcd.init();
        lcd.printString("Welldone,",15,0); //display intro & title to game
        lcd.printString("You've Won!",10,1);
        lcd.printString("Is your name",5,2);
        lcd.printString("Roger Federer?",1,3);
        wait (5);
        lcd.refresh();

    }

}

void loss()
{

    if (computerScore >=10)

    {
        refreshCells();
        lcd.init();
        lcd.printString("Unlucky Pal",10,0); //display intro & title to game
        lcd.printString("You Lose, you",5,1);
        lcd.printString("absoloute mug",5,2);
        wait (5);
        lcd.refresh();

    }




}

void redraw_screen()
{
    
    lcd.drawCircle(pos.x,pos.y,BALLRADIUS,0.5);  
    lcd.refresh();
}


void check_collisions()
{
    // see if ball has hit the floor (subtract the radius since the position is the centre of the ball)
    if ( pos.y >= 47 - BALLRADIUS ) {
        pos.y = 47 - BALLRADIUS;  // need to force this or else ball can end up going 'underground'
        vel.y = -0.6 * vel.y;  // y velocity is reflected and dampened
        acc.y = -acc.y;
        // y accleration is still gravity
    }

    if ( pos.y <= 5 - BALLRADIUS ) {
        pos.y = 5 - BALLRADIUS;  // need to force this or else ball can end up going 'underground'
        vel.y = -0.6 * vel.y;  // y velocity is reflected and dampened
        acc.y = -acc.y;
        // y accleration is still gravity
    }

    // has ball gone off the right-hand side?
    if (( pos.x >= 83 - BALLRADIUS ) && (pos.y > yc) && (pos.y < yc + 12)&&(pos.y > yc - 3))  {
        pos.x = 83 - BALLRADIUS;  // need to force this or else ball can end up going off screen
        vel.x = -0.6 * vel.x;  // reflect and damp velocity
        acc.x = -acc.x;  // reflect accleration
    }

    // what about the left?
    if (( pos.x <= BALLRADIUS ) && (pos.y > yp) && (pos.y < yp + 12)&&(pos.y > yp - 3)) {
        pos.x = BALLRADIUS;  // need to force this or else ball can end up going off screen
        vel.x = -0.6 * vel.x;  // reflect and damp velocity
        acc.x = -acc.x;  // reflect accleration
    }

}

void update_physics_engine()
{
    // from Newton's Laws

    acc.x = 1.0F*acc.x;  // reduce a little due to air friction

    // calc new velocity (assume 'unit' time)
    vel.x = vel.x + acc.x; // * g_gt;
    vel.y = vel.y + acc.y; // * g_gt;

    // calc new position (assume 'unit' time)
    pos.x = (pos.x + vel.x) * 1;
    pos.y = (pos.y + vel.y) * 1;

    // should really multiply the above by the time-step,
    // but since the pixel can only be a integer value,
    // it makes the motion a little 'jumpy'.

}

void init_ball()
{
    pos.x = 3;
    pos.y = 4;
    vel.x = 0.0;
    vel.y = 0.0;
    acc.x = 0.5;
    acc.y = 0.075;  
}

void player_Score_Position()
{
    // initial position (top-left)
    pos.x = 80;
    pos.y = 4;
    // initial velocity - still
    vel.x = 0.0;
    vel.y = 0.0;
    // initial acceleration - gravity and a bit of push to right
    acc.x = -0.5;
    acc.y = 0.075;  // +ve so ball accelerates to bottom of display (top of screen is y=0, bottom is y=47)
    // should be 9.8, but can play with value to get a 'nice' ball movement
}

void init_display()
{
    lcd.init();
    lcd.normalMode();      // normal colour mode
    lcd.setBrightness(0.5); // put LED backlight on 50%
}