I simplified the library "ILI9225_TFT" provided by Arman Safikhani to better suit my needs in implementing a simple sliding puzzle game.

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers States.h Source File

States.h

00001 #include "Fonts.h"
00002 
00003 //STATE 0
00004 //GLCD Displays the start screen - encouraging the player to start the game
00005 //by displaying the message "PRESS SELECT TO START".
00006 //
00007 //Player must press the SELECT button to trigger the next STATE.
00008 void greetingScreen() {
00009     tft.clear();
00010     tft.setFont(Terminal12x16);
00011     tft.drawText(60, 40, "PRESS", COLOR_RED);
00012     tft.drawText(54, 65, "SELECT", COLOR_RED);
00013     tft.drawText(77, 90, "TO", COLOR_RED);
00014     tft.drawText(60, 115, "START", COLOR_RED);
00015     
00016     while(1) {
00017         if(getPlayerInput(wirelessInput_Freq) == 6) //SELECT -> 6
00018             return;
00019     }
00020 }
00021 
00022 //STATE 1
00023 //GLCD encourages player to take a picture of something by displaying the
00024 //message "SELECT TO TAKE PICTURE".
00025 //
00026 //Player must press the SELECT button to take a picture and trigger the next
00027 //STATE.
00028 void takePicture() {
00029     tft.clear();
00030     tft.setFont(Terminal12x16);
00031     tft.drawText(54, 40, "SELECT", COLOR_RED);
00032     tft.drawText(77, 65, "TO", COLOR_RED);
00033     tft.drawText(65, 90, "TAKE", COLOR_RED);
00034     tft.drawText(50, 115, "PICTURE", COLOR_RED);
00035     
00036     while(1) {
00037         if(getPlayerInput(wirelessInput_Freq) == 6) { //SELECT -> 6
00038             for(int index = 0; index < 19200; index++)
00039                 handlePixel(index, getNextPixel());
00040             return;
00041         }
00042     }
00043 }
00044 
00045 //STATE 2
00046 //GLCD will display the picture taken in STATE 1 @ the bottom of the screen.
00047 //
00048 //Player input is ignored during this STATE.
00049 void previewPicture() {
00050     tft.clear();
00051     updatePuzzle();
00052 }
00053 
00054 //STATE 3
00055 //GLCD will display the message "SELECT > ACCEPT" atop "OR" atop
00056 //"CANCEL > RETAKE" at the top of the screen.
00057 //
00058 //Player may press SELECT to continue (STATE 4) w| picture or CANCEL to retake
00059 //the picture (STATE 1).
00060 bool confirmPicture() {
00061     tft.fillRectangle(0, 0, 175, 91, COLOR_BLACK);
00062     tft.setFont(Terminal12x16);
00063     tft.drawText(4, 8, "SELECT > ACCEPT", COLOR_RED);
00064     tft.drawText(77, 33, "OR", COLOR_RED);
00065     tft.drawText(4, 58, "CANCEL > RETAKE", COLOR_RED);
00066     //printElementsInPicture();
00067     
00068     while(1) {
00069         if(getPlayerInput(wirelessInput_Freq) == 6) //SELECT -> 6
00070             return true; //Confirm the picture by returning true
00071         else if(getPlayerInput(wirelessInput_Freq) == 7) //CANCEL -> 7
00072             return false; //Retake the picture by returning false
00073     }
00074 }
00075 
00076 //STATE 4
00077 //GLCD will display the message "LOADING" and keeps it there until the
00078 //LPC1769 has finished shuffling the pieces in the background. When it is done,
00079 //it will black out the screen, populate the 4x4 grid with the puzzle pieces,
00080 //and start the player off at index 0 of the puzzle grid.
00081 //Remark: 2 out of 16 of the puzzle pieces will be missing. There were 3 reasons
00082 //that led us to this design choice:
00083 //1) We had to remove, at the very least, 1 puzzle piece to make a classic
00084 //sliding puzzle game.
00085 //2) We desired that the sizeof(picture) << 32kB but we still wanted a colored
00086 //image (i.e., 16 bit aray element) so we needed to get rid of 2 pieces to reach
00087 //our goal.
00088 //3) If puzzle piece positions for a classic sliding puzzle game are generated
00089 //completely randomly then they are only solvable 50% of the time based off
00090 //whether there is an even amount of permutations. There are applicable methods
00091 //for only generating solvable puzzles but another (and easier) solution is to
00092 //just remove a second puzzle piece.
00093 //
00094 //The player's button presses are ignored during this time.
00095 void shufflePuzzle() {
00096     tft.clear();
00097     tft.setFont(Terminal12x16);
00098     tft.drawText(47, 40, "LOADING", COLOR_RED);
00099 
00100     shuffleGridIndices();
00101 
00102     tft.clear();
00103     updatePuzzle();
00104     cursorIndex = 0;
00105     highlightGridIndex(cursorIndex, false);
00106 }
00107 
00108 //STATE 5
00109 //We wait for the player to press SELECT. If the player presses SELECT we must
00110 //verify 2 characteristics about the target piece before we may trigger STATE 6:
00111 //1) Target puzzle piece is NOT one of the 2 missing puzzle pieces.
00112 //2) Target puzzle piece is NOT locked on all 4 sides.
00113 //
00114 //At this point, the player is able to use the UP, DOWN, LEFT, and RIGHT buttons
00115 //to move around their cursor until they find a piece that they want to swap
00116 //for another piece. While their cursor is hovering over the target piece, they
00117 //would press SELECT to "grab it". The cursor is green in this state.
00118 uint8_t selectionMode() {
00119     highlightGridIndex(cursorIndex, false);
00120     //printElementsInPicture();
00121     while(1) {
00122         if(getPlayerInput(wirelessInput_Freq) == 6) { //SELECT -> 6
00123             if(selectionMode_indexVerified(cursorIndex)) //& index verified
00124                 return cursorIndex;
00125         }
00126         else if(getPlayerInput(wirelessInput_Freq) == 2 //UP -> 2
00127             && cursorIndex - 4 > -1)
00128             highlightGridIndex(cursorIndex - 4, false);
00129         else if(getPlayerInput(wirelessInput_Freq) == 3 //DOWN -> 3
00130             && cursorIndex + 4 < 16)
00131             highlightGridIndex(cursorIndex + 4, false);
00132         else if(getPlayerInput(wirelessInput_Freq) == 4 //LEFT -> 4
00133             && ((cursorIndex%4) - 1) > -1)
00134             highlightGridIndex(cursorIndex - 1, false);
00135         else if(getPlayerInput(wirelessInput_Freq) == 5 //RIGHT -> 5
00136             && ((cursorIndex%4) + 1) < 4)
00137             highlightGridIndex(cursorIndex + 1, false);
00138     }
00139 }
00140 
00141 //STATE 6
00142 //If player presses UP, DOWN, LEFT, or RIGHT, we verify that target index is an
00143 //empty space before making the move and triggering STATE 5. A piece may only be
00144 //moved 1 index position and it may only be moved to 1 of the 2 missing puzzle
00145 //piece indices.
00146 //
00147 //Only UP, DOWN, LEFT, RIGHT, and CANCEL are monitored during this state.
00148 //Pressing CANCEL, at any time, would restore us back to STATE 5 and no swapping
00149 //would occur. The cursor is red in this state.
00150 void selectedMode(uint8_t selectedIndex) {
00151     highlightGridIndex(selectedIndex, true);
00152 
00153     while(1) {
00154         if(getPlayerInput(wirelessInput_Freq) == 7) //CANCEL -> 7
00155             return;
00156         if(getPlayerInput(wirelessInput_Freq) == 2 //UP -> 2
00157             && selectedIndex - 4 > -1) {
00158             if(puzzState[selectedIndex - 4] > 13) { //Empty space above?
00159                 swap(&puzzState[selectedIndex], &puzzState[selectedIndex - 4]);
00160                 updatePuzzle();
00161                 cursorIndex = selectedIndex - 4;
00162                 return;
00163             }
00164         }
00165         if(getPlayerInput(wirelessInput_Freq) == 3 //DOWN -> 3
00166             && selectedIndex + 4 < 16) {
00167             if(puzzState[selectedIndex + 4] > 13) { //Empty space below?
00168                 swap(&puzzState[selectedIndex], &puzzState[selectedIndex + 4]);
00169                 updatePuzzle();
00170                 cursorIndex = selectedIndex + 4;
00171                 return;
00172             }
00173         }
00174         if(getPlayerInput(wirelessInput_Freq) == 4 //LEFT -> 4
00175             && ((selectedIndex%4) - 1) > -1) {
00176             if(puzzState[selectedIndex - 1] > 13) { //Empty space to the left?
00177                 swap(&puzzState[selectedIndex], &puzzState[selectedIndex - 1]);
00178                 updatePuzzle();
00179                 cursorIndex = selectedIndex - 1;
00180                 return;
00181             }
00182         }
00183         if(getPlayerInput(wirelessInput_Freq) == 5 //RIGHT -> 5
00184             && ((selectedIndex%4) + 1) < 4) {
00185             if(puzzState[selectedIndex + 1] > 13) { //Empty space to the right?
00186                 swap(&puzzState[selectedIndex], &puzzState[selectedIndex + 1]);
00187                 updatePuzzle();
00188                 cursorIndex = selectedIndex + 1;
00189                 return;
00190             }
00191         }
00192     }
00193 }