mRackitBall - the single player pong

Dependencies:   4DGL-uLCD-SE mbed-rtos mbed

main.cpp

Committer:
hrodriguez8
Date:
2014-10-22
Revision:
0:3c93e7a26a42

File content as of revision 0:3c93e7a26a42:

#include "mbed.h"
//#include "rtos.h"
#include "stdio.h"
#include "uLCD_4DGL.h"

#define boldOn uLCD.text_bold(ON)
#define boldOff uLCD.text_bold(OFF)

/*Setting up required pins, global variables and other required items*/

//Debugging Options
int lcdjoystickDebug = 0; //1=on, 0=off


/* ----- Status Led ----- */
//DigitalOut statusLed(LED1); //if off - in menu ... if on - in game ... if flashing - paused?

/* ----- Pushbuttons ----- */
InterruptIn pbSelect(p22); //right pb - select
InterruptIn pbPause(p21); //left pb - pause/resume game

/* ----- LCD screen ----- */
uLCD_4DGL uLCD(p9, p10, p11); // create a lcd object
//Mutex lcd_mutex;  //used to lock the lcd

/* ----- Joystick ----- */
static const float lcdWidth = 128; //Lcd screen is 128x128
static const float lcdHeight = 128;
AnalogIn joystickX(p15);
AnalogIn joystickY(p16);

volatile float joystickXReading; //Read joystick x
volatile float joystickYReading; //Read joystick y
volatile unsigned int Xpos; //joystick x pos after calc
volatile unsigned int Ypos; //joystick y pos after calc

/* ----- States for game and menus ----- */
//Probably a way to optimize this to limit the usage of global variables

volatile int currentState = 1; //State starts in menu -- 1=menu -- 2=options -- 3=start game -- 4=pause game
volatile int mainMenuSelection = 1; //Determines which menu option is currently highlighted 1=Start , 2=Options

volatile int optionsMenuSelection = 1; //Determines which option is highlighted
volatile int optionsChoice = 1; //Determines which # is highlighted on each item


/* ----- Functions/Prototypes ----- */
void mainMenu();
void optionsMenu();
void helpMenu();
void startGame();

void drawDesign();

/* ----- End Functions/Prototypes ----- */


/* ----- Changeable Options ----- */
//When drawing the menu, drawing the player paddle or drawing the ball on the screen
//use these variables

int textColorMain = GREEN; // Changes the main text color
int textColorSecondary = RED; //This is the color of text when highlighted
int playerColor = GREEN; // Changes the player paddle color -- 1=green, 2=blue
int ballColor = WHITE; //Changes the ball color -- 1=white, 2=red
int borderDesign = 1; //Changes the main menu's border design -- 1=none, 2=square with lines

/* ----- End Changeable Options ----- */


/* ----- Game Variables And Functions ----- */

//For player paddle
int playerxPos, playeryPos, playerLength, playerThickness;
void movePlayer(); //moving the padddle

//For ball
int ballxPos, ballyPos, ballRadius;
float fx, fy,vx,vy;
void moveBall(); //moving the ball


/* ----- End In-game Variables ----- */




/* ----- Main ----- */
int main() {
    
    pbSelect.mode(PullUp); // PullUp mode for pushbuttons
    pbPause.mode(PullUp); 
    
    uLCD.baudrate(3000000); //overclock LCD
    uLCD.cls();

    playerxPos   = 50;  playeryPos = 124;
    playerLength = 78;  playerThickness = 126;
    
    fx=60.0, fy=115.0, vx=1.0, vy=0.5;
    ballxPos = 60;  ballyPos = 115; ballRadius = 3;
    
    while(true) {
        
        joystickXReading = joystickX; //Joystick calculations
        joystickYReading = 1.0f - joystickY;
    
        Xpos = (unsigned int)(lcdWidth * joystickXReading);
        Ypos = (unsigned int)(lcdHeight * joystickYReading);        
               
        switch(currentState){ //States for the game -- 1=menu -- 2=options -- 3=help -- 4=start game -- 5=pause game
            
            case 1: //MENU
            mainMenu();
            wait(.15); //delay for selecting
            break;
            
            case 2: //OPTIONS
            optionsMenu();
            wait(.15);
            break;
            
            case 3: //HELP
            helpMenu();
            wait(.15);
            break;
            
            case 4: //START GAME
            startGame();
            wait(.15);
            break;
            
            case 5: //PAUSE GAME
            boldOn;
            uLCD.text_string("Paused", 6, 7, FONT_5X7, textColorMain);
            boldOff;
            while(pbPause);
            uLCD.text_string("      ", 6, 7, FONT_5X7, BLACK);
            currentState = 4; //Stay in above loop unless pressed
            wait(.15);
            break;
        
        }//End switch for states        
        
    }//End While
    
}//End Main

/* ----- End Main ----- */



/* ----- Full Functions ----- */

////////////////////
// --- mainMenu --- //
void mainMenu(){ //This will show which option the player has selected by highlighting it based on mainMenuSelection

    if( Xpos > 70 ) { //We are scrolling down, 66 is when joystick isn't moving
        mainMenuSelection++;
        if(mainMenuSelection > 3) mainMenuSelection = 1; //If there were more options you could change (> 2) to (> # of selections)                     
    }
        
    if( Xpos < 62 ) { //We are scrolling up
        mainMenuSelection--;
        if(mainMenuSelection < 1) mainMenuSelection = 3; //If there were more options you could change (menuSelection # of selections)                     
    } 
    
    uLCD.locate(4,0);
    uLCD.printf("mRackitBall");
    
    if(borderDesign != 1) drawDesign(); //If borderDesign doesn't equal one then there is a design, draw it
           
    if(mainMenuSelection == 1) {
        boldOn;
        uLCD.text_string("Start", 6, 4, FONT_5X7, textColorSecondary);
        boldOff;
    }
    else {
        uLCD.text_string("Start", 6, 4, FONT_5X7, textColorMain);
    }
        
    if(mainMenuSelection == 2) {
        boldOn;
        uLCD.text_string("Options", 6, 7, FONT_5X7, textColorSecondary);
        boldOff;
    }
    else {
        uLCD.text_string("Options", 6, 7, FONT_5X7, textColorMain);
    }
    
    if(mainMenuSelection == 3) {
        boldOn;
        uLCD.text_string("Help", 6, 10, FONT_5X7, textColorSecondary);
        boldOff;
    }
    else {
        uLCD.text_string("Help", 6, 10, FONT_5X7, textColorMain);
    }
        
    uLCD.text_string("", 7, 10, FONT_5X7, textColorMain); //Prevents other text from gettin wrong colors (how to fix..)    
    
    
    
    if(!pbSelect) { //When the select(right) button is pressed currentState will change
        if(mainMenuSelection == 1) { //Start the game -- 4=start game
            currentState = 4; 
            uLCD.cls();
        }                
        if(mainMenuSelection == 2) { //Open options menu -- 2=options
            currentState = 2;
            uLCD.cls(); 
        }
        if(mainMenuSelection == 3) { //Open help menu -- 3=help
            currentState = 3;
            uLCD.cls();
        }
    } // End pushButton selection
        
} // End Menu Function
////////////////////


////////////////////
// --- Options Menu

void optionsMenu() {
    
    uLCD.text_string("Options", 5, 0, FONT_5X7, textColorMain);
    
    //These determine how many options are in each highlighted options, each option will change accordingly
    //Example: If you want 3 text options, make numTextOptions = 3 and then add the new text color
    //         to the correct section of the code.  Although due to LCD width constraints you may be only 
    //         able to add 4 different options.
    
    //Changes these variables according to how many options you want to have.
    int numTextOptions = 2; //green, white
    int numPlayerOptions = 2; //green, blue
    int numBallColorOptions = 2; //white, red
    int numMainMenuDesigns = 3; //none, squares with lines, squares with double lines
    
    //-- This is for the options menu determining which option is highlighted    
    if( Xpos > 70 ) { //We are scrolling down, 66 is when joystick isn't moving -- This is for the options menu determining which option is highlighted
        optionsMenuSelection++;
        if(optionsMenuSelection > 5) optionsMenuSelection = 1; //If there were more options you could change (> 2) to (> # of selections)                     
    }        
    if( Xpos < 62 ) { //We are scrolling up
        optionsMenuSelection--;
        if(optionsMenuSelection < 1) optionsMenuSelection = 5; //If there were more options you could change (menuSelection # of selections)                     
    }   
    if( Ypos < 70 ) { //We are scrolling right
        optionsChoice++;                    
    }   
    if( Ypos > 62 ) { //We are scrolling left
        optionsChoice--;                   
    }

////     
//Begin Option Selection and Changing
////

//--TextColor Change
    if( optionsMenuSelection == 1 ) {
        
    
        if(optionsChoice > numTextOptions) { optionsChoice = numTextOptions; } //Don't go past the max number of options.  No wrap around.
        if(optionsChoice < 0) { optionsChoice = 1; }
        
        boldOn;
        uLCD.text_string("TextColor", 0, 2, FONT_5X7, textColorSecondary);
        boldOff;       
        
        if(optionsChoice == 1) { //highlight textColor 1 -- green
            boldOn;
            uLCD.text_string("1", 10, 2, FONT_5X7, textColorMain);
            boldOff;
        }
        else {
            uLCD.text_string("1", 10, 2, FONT_5X7, textColorMain);
        }
        
        if(optionsChoice == 2) { //highlight textColor 2 -- white
            boldOn;
            uLCD.text_string("2", 12, 2, FONT_5X7, textColorMain);
            boldOff;        
        }
        else {
            uLCD.text_string("2", 12, 2, FONT_5X7, textColorMain);
        }
        
        //From the example above, you would add more colors here.
        
        //Press pushbutton to select the option
        if(!pbSelect){
            if(optionsChoice == 1) { textColorMain = GREEN; }
            if(optionsChoice == 2) { textColorMain = WHITE; }
        }        
    }
    
    else { //if not selected, just display it
        uLCD.text_string("TextColor", 0, 2, FONT_5X7, textColorMain);
        
        //This will keep the option bolded in the options Menu -- showing which option is currently selected
        if(textColorMain == GREEN) { //keep 1 bolded
            boldOn;
            uLCD.text_string("1", 10, 2, FONT_5X7, textColorMain);
            boldOff;        
        }
        else {
            uLCD.text_string("1", 10, 2, FONT_5X7, textColorMain);
        }
        
        if(textColorMain == WHITE) { //keep 2 bolded
            boldOn;
            uLCD.text_string("2", 12, 2, FONT_5X7, textColorMain);
            boldOff;        
        }
        else {
            uLCD.text_string("2", 12, 2, FONT_5X7, textColorMain);
        }
        
        //From the example above, you would add more colors here aswell.
        
    }
//--End TextColor Change


//--Player Color
    if( optionsMenuSelection == 2 ) {        
    
        if(optionsChoice > numPlayerOptions) { optionsChoice = numPlayerOptions; } //Don't go past the max number of options.  No wrap around.
        if(optionsChoice < 0) { optionsChoice = 1; }
        
        boldOn;
        uLCD.text_string("PlayerCol", 0, 4, FONT_5X7, textColorSecondary);
        boldOff;       
        
        if(optionsChoice == 1) { //highlight textColor 1 -- green
            boldOn;
            uLCD.text_string("1", 10, 4, FONT_5X7, textColorMain);
            boldOff;
        }
        else {
            uLCD.text_string("1", 10, 4, FONT_5X7, textColorMain);
        }
        
        if(optionsChoice == 2) { //highlight textColor 2 -- blue
            boldOn;
            uLCD.text_string("2", 12, 4, FONT_5X7, textColorMain);
            boldOff;        
        }
        else {
            uLCD.text_string("2", 12, 4, FONT_5X7, textColorMain);
        }
        
        //add more player colors above
        
        //Press pushbutton to select the option
        if(!pbSelect){
            if(optionsChoice == 1) { playerColor = GREEN; }
            if(optionsChoice == 2) { playerColor = BLUE; }
        }        
    }
    
    else { //if not selected, just display it
        uLCD.text_string("PlayerCol", 0, 4, FONT_5X7, textColorMain);
        
        //This will keep the option bolded in the options Menu -- showing which option is currently selected
        if(playerColor == GREEN) { //keep 1 bolded
            boldOn;
            uLCD.text_string("1", 10, 4, FONT_5X7, textColorMain);
            boldOff;        
        }
        else {
            uLCD.text_string("1", 10, 4, FONT_5X7, textColorMain);
        }
        
        if(playerColor == BLUE) { //keep 2 bolded
            boldOn;
            uLCD.text_string("2", 12, 4, FONT_5X7, textColorMain);
            boldOff;        
        }
        else {
            uLCD.text_string("2", 12, 4, FONT_5X7, textColorMain);
        } 
        
        //add more player colors above
    }
//--End Player Color


//--Ball Color
    if( optionsMenuSelection == 3 ) {        
    
        if(optionsChoice > numBallColorOptions) { optionsChoice = numBallColorOptions; } //Don't go past the max number of options.  No wrap around.
        if(optionsChoice < 0) { optionsChoice = 1; }
        
        boldOn;
        uLCD.text_string("BallColor", 0, 6, FONT_5X7, textColorSecondary);
        boldOff;       
        
        if(optionsChoice == 1) { //highlight textColor 1 -- green
            boldOn;
            uLCD.text_string("1", 10, 6, FONT_5X7, textColorMain);
            boldOff;
        }
        else {
            uLCD.text_string("1", 10, 6, FONT_5X7, textColorMain);
        }
        
        if(optionsChoice == 2) { //highlight textColor 2 -- red
            boldOn;
            uLCD.text_string("2", 12, 6, FONT_5X7, textColorMain);
            boldOff;        
        }
        else {
            uLCD.text_string("2", 12, 6, FONT_5X7, textColorMain);
        }
        
        //add more ball colors above
        
        //Press pushbutton to select the option
        if(!pbSelect){
            if(optionsChoice == 1) { ballColor = WHITE; }
            if(optionsChoice == 2) { ballColor = RED; }
        }        
    }
    
    else { //if not selected, just display it
        uLCD.text_string("BallColor", 0, 6, FONT_5X7, textColorMain);
        
        //This will keep the option bolded in the options Menu -- showing which option is currently selected
        if(ballColor == WHITE) { //keep 1 bolded
            boldOn;
            uLCD.text_string("1", 10, 6, FONT_5X7, textColorMain);
            boldOff;        
        }
        else {
            uLCD.text_string("1", 10, 6, FONT_5X7, textColorMain);
        }
        
        if(ballColor == RED) { //keep 2 bolded
            boldOn;
            uLCD.text_string("2", 12, 6, FONT_5X7, textColorMain);
            boldOff;        
        }
        else {
            uLCD.text_string("2", 12, 6, FONT_5X7, textColorMain);
        }
        
        //add more ball colors above
    }

//--End Ball Color


//--Main Menu Design
    if( optionsMenuSelection == 4 ) {
        
   
        if(optionsChoice > numMainMenuDesigns) { optionsChoice = numMainMenuDesigns; } //Don't go past the max number of options.  No wrap around.
        if(optionsChoice < 0) { optionsChoice = 1; }
        
              
        boldOn;
        uLCD.text_string("Design", 0, 8, FONT_5X7, textColorSecondary);
        boldOff;       
        
        if(optionsChoice == 1) { //highlight design 1 - no design
            boldOn;
            uLCD.text_string("1", 10, 8, FONT_5X7, textColorMain);
            boldOff;
        }
        else {
            uLCD.text_string("1", 10, 8, FONT_5X7, textColorMain);
        }
        
        if(optionsChoice == 2) { //highlight design 2 -- rectangles with lines
            boldOn;
            uLCD.text_string("2", 12, 8, FONT_5X7, textColorMain);
            boldOff;        
        }
        else {
            uLCD.text_string("2", 12, 8, FONT_5X7, textColorMain);
        }
        
        if(optionsChoice == 3) { // highlight design 3 -- rectangles with double lines
            boldOn;
            uLCD.text_string("3", 14, 8, FONT_5X7, textColorMain);
            boldOff;
        }
        else {
            uLCD.text_string("3", 14, 8, FONT_5X7, textColorMain);   
        }
        
        //Add new designs above here        
        //Press pushbutton to select the option
        if(!pbSelect){
            if(optionsChoice == 1) { borderDesign = 1; }
            if(optionsChoice == 2) { borderDesign = 2; }
            if(optionsChoice == 3) { borderDesign = 3; }
        }        
    }
    
    else {
        uLCD.text_string("Design", 0, 8, FONT_5X7, textColorMain);
        
        //This will keep the option bolded in the options Menu -- showing which option is currently selected
        if(borderDesign == 1) { //keep 1 bolded
            boldOn;
            uLCD.text_string("1", 10, 8, FONT_5X7, textColorMain);
            boldOff;        
        }
        else {
            uLCD.text_string("1", 10, 8, FONT_5X7, textColorMain);
        }
        
        if(borderDesign == 2) { //keep 2 bolded
            boldOn;
            uLCD.text_string("2", 12, 8, FONT_5X7, textColorMain);
            boldOff;
        }
        else {
            uLCD.text_string("2", 12, 8, FONT_5X7, textColorMain);
        }
        
        if(borderDesign == 3) { //keep 3 bolded
            boldOn;
            uLCD.text_string("3", 14, 8, FONT_5X7, textColorMain);
            boldOff;
        }
        else {
            uLCD.text_string("3", 14, 8, FONT_5X7, textColorMain);
        }
        
        //Add new designs above here
    }//end else

//--End MainMenu Design



//--Back
    if( optionsMenuSelection == 5 ) { //Go Back to mainMenu state
        boldOn;
        uLCD.text_string("Back", 0, 13, FONT_5X7, textColorSecondary);
        boldOff;
        uLCD.text_string("", 1, 13, FONT_5X7, textColorMain);
        
        if(!pbSelect) { //When pushbutton is pressed go back to mainmenu state
            currentState = 1;
            optionsMenuSelection = 1; //reset is back to 1 for next entry
            uLCD.cls();            
        }        
    }
    else {
        uLCD.text_string("Back", 0, 13, FONT_5X7, textColorMain);        
    }
    
//--End Back 
    
}
// --- End Options Menu
////////////////////


////////////////////
// --- Help Menu

void helpMenu(){
    
    uLCD.text_string("Help", 6, 0, FONT_5X7, textColorMain);
    
    uLCD.text_string("Joystick", 0, 2, FONT_5X7, textColorMain);
    uLCD.text_string("Used to move", 1, 3, FONT_5X7, textColorMain);

    uLCD.text_string("Left Button", 0, 5, FONT_5X7, textColorMain);
    uLCD.text_string("Used to pause", 1, 6, FONT_5X7, textColorMain);

    uLCD.text_string("Right Button", 0, 8, FONT_5X7, textColorMain);
    uLCD.text_string("Used to select", 1, 9, FONT_5X7, textColorMain);
    
    boldOn;
    uLCD.text_string("Back", 0, 13, FONT_5X7, textColorSecondary);
    boldOff;
    uLCD.text_string("", 1, 13, FONT_5X7, textColorMain);
    
    if(!pbSelect) { // When Back is selected go back to the main menu state -- 1=main menu  
        currentState = 1;
        uLCD.cls();
    }
}
// --- End Help Menu
////////////////////


////////////////////
// --- drawDesign (border for mainmenu)
void drawDesign() {
    
    if(borderDesign == 2) {
        uLCD.line(0, 0, 0, 127, textColorMain);
        uLCD.line(127, 0, 127, 127, textColorMain);
        uLCD.line(0, 127, 127, 127, textColorMain);
        uLCD.filled_rectangle(0, 0, 5, 5, textColorMain);
        uLCD.filled_rectangle(122, 0, 127, 5, textColorMain);
        uLCD.filled_rectangle(0, 122, 5, 127, textColorMain);
        uLCD.filled_rectangle(122, 122, 127, 127, textColorMain);        
    }
    
    if(borderDesign == 3) {
        uLCD.line(0, 0, 0, 127, textColorMain);
        uLCD.line(127, 0, 127, 127, textColorMain);
        uLCD.line(0, 127, 127, 127, textColorMain);
        
        uLCD.line(5, 0, 5, 127, textColorMain);
        uLCD.line(122, 0, 122, 127, textColorMain);
        uLCD.line(0, 122, 127, 122, textColorMain);
        
        uLCD.filled_rectangle(0, 0, 5, 5, textColorMain);
        uLCD.filled_rectangle(122, 0, 127, 5, textColorMain);
        uLCD.filled_rectangle(0, 122, 5, 127, textColorMain);
        uLCD.filled_rectangle(122, 122, 127, 127, textColorMain);        
    }

}
// --- drawDesign
////////////////////


////////////////////
// --- Start Game

void startGame() {
    
    if(!pbSelect) {
        
        currentState = 1; //Reset and go to menu if rightbutton is pressed

        playerxPos   = 50;  playeryPos = 124; //Reset the variables for next run
        playerLength = 78;  playerThickness = 126;
        
        fx=60.0, fy=115.0, vx=1.0, vy=0.5;
        ballxPos = 60;  ballyPos = 115; ballRadius = 3;
        
        uLCD.cls();
        wait(.2);
        return; 
    }
    if(!pbPause) {
        wait(.15);
        currentState = 5; //Pause the game
        return; 
    }
    
    //uLCD.filled_circle(64, 115, 3, ballColor); //ball
    
    movePlayer(); //move the paddle
    moveBall();
    



}
// --- End Start Game
////////////////////


////////////////////
// --- movePlayer

//For player paddle
//int playerxPos, playeryPos, playerLength, playerThickness;

void movePlayer() {
    //Draw paddle
    uLCD.filled_rectangle(playerxPos, playeryPos, playerLength, playerThickness, playerColor); //player paddle
    
    int playerSpeedModifier = 3;
    
    if( Ypos < 70 && playerLength < 126) { //scrolling left, increasing x, and not at the border
       playerxPos += playerSpeedModifier; //Changes these numbers to increase scrolling speed
       playerLength += playerSpeedModifier;
       //color to the left
       uLCD.filled_rectangle(playerxPos-(playerSpeedModifier), playeryPos, playerxPos, playerThickness, BLACK);
    }
    if( Ypos > 62 && playerxPos > 0) { //scrolling right, decreaseing x, and not at the border
        playerxPos -= playerSpeedModifier; //Changes these numbers to increase scrolling speed
        playerLength -= playerSpeedModifier;
        //color to the right
        uLCD.filled_rectangle(playerLength, playeryPos, playerLength+(playerSpeedModifier), playerThickness, BLACK);
    }
       
}
// --- End Move
////////////////////

////////////////////
// --- moveball
/*
//For ball
int ballxPos, ballyPos, ballWidth, ballHeight, ballxSpeed, ballySpeed;
void moveBall(); //moving the ball
*/

void moveBall() {
    uLCD.filled_circle(ballxPos, ballyPos, ballRadius, BLACK); //ball
    
    if( (ballxPos <= ballRadius+1) || (ballxPos>=127-ballRadius) ) {       
       vx = -vx*2;
    }
    
    if( (ballyPos <= ballRadius+1) || (ballyPos>=127-ballRadius) ) {
        if(ballyPos >= playeryPos && ( (ballxPos <= playerxPos)||(ballxPos >= playerLength) ) )  {
            uLCD.text_string("Game over", 6,4, FONT_5X7, textColorMain);
            currentState = 1;
            wait(4);
            uLCD.cls();
            
            playerxPos   = 50;  playeryPos = 124; //Reset the variables for next run
            playerLength = 78;  playerThickness = 126;
            
            fx=60.0, fy=115.0, vx=1.0, vy=0.5;
            ballxPos = 60;  ballyPos = 115; ballRadius = 3;
        
            return;
        }
       vy = -vy*2;
    }
    
    if(vy > 6 ) { vy = 6; } //These determine how fast the ball will go and when it will cap off
    else if( vy < -6 ) { vy = -6; }
    
    if(vx > 6 ){ vx = 6; }
    else if( vx < -6 ) { vx = -6; }
    
    if(lcdjoystickDebug){
        uLCD.locate(0,0);
        uLCD.printf("px%3d, py%3d",playerxPos, playeryPos);
        uLCD.locate(0,1);
        uLCD.printf("l%3d, t%3d", playerLength, playerThickness);
        uLCD.locate(0,2);
        uLCD.printf("bx%3d, by%3d",ballxPos,ballyPos);
    }
    
    fx=fx+vx;
    fy=fy+vy;
    ballxPos = (int)fx;
    ballyPos = (int)fy;   
    
    uLCD.filled_circle(ballxPos, ballyPos, ballRadius, ballColor); //ball
    
}
// --- End moveBall
////////////////////


//End of Main Code
//////////////////////////////////////////////////////////////////////