I simplified the library "ILI9225_TFT" provided by Arman Safikhani to better suit my needs in implementing a simple sliding puzzle game.
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 }
Generated on Thu Jul 14 2022 22:45:10 by
1.7.2