mRackitBall - the single player pong
Dependencies: 4DGL-uLCD-SE mbed-rtos mbed
Diff: main.cpp
- Revision:
- 0:3c93e7a26a42
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.cpp Wed Oct 22 18:48:34 2014 +0000 @@ -0,0 +1,762 @@ +#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 +////////////////////////////////////////////////////////////////////// + + +