This is a ball on the Mbed.
Dependencies: 4DGL-uLCD-SE IMUfilter ITG3200 Music mbed-rtos mbed
main_legacy.cpp
00001 #include "mbed.h" 00002 #include "uLCD_4DGL.h" 00003 #include "rtos.h" 00004 #include "Music.h" 00005 #include "IMU_RPY.h" 00006 00007 DigitalOut myled(LED1); 00008 AnalogIn xpot(p19); 00009 AnalogIn ypot(p20); 00010 uLCD_4DGL uLCD(p9,p10,p11); 00011 music ms(p21); 00012 00013 Mutex xmutex,ymutex; 00014 char mazearr[128][128]; 00015 char ballx, bally; 00016 char ballx_old, bally_old; 00017 float ballxvel, ballyvel, ballvel; 00018 enum LEVELSELECT {LEVEL1, LEVEL2, LEVEL3}; 00019 LEVELSELECT gamestate = LEVEL1; 00020 00021 //Sound bytes 00022 char s1[] = "E4:8; E4:8; R:8; E4:8; R:8; C4:8; E4:4; G4:4; R:4; G3:4; R:4;"; 00023 int s1_len = 61; 00024 char wallbeep[] = "C4:48;"; 00025 int wallbeep_len = 6; 00026 char victory[] = "A4:12; R:32; A4:12; R:32; A4:12; R:32; A4:4; R:8; F4:4; R:8; G4:4; R:8; A4:4; R:16; G4:20; R:32; A4:4;"; 00027 int victory_len = 102; 00028 double tempo = 180; 00029 00030 void displayTitle(); 00031 void displayMaze(); 00032 void updateVelocity(); 00033 void updateBall(); 00034 void loadLevel(); 00035 void displayVictory(); 00036 00037 //xthread and ythread act as the physics engine, simulating velocity and wall detection 00038 void xthread(void const *args) 00039 { 00040 while(1) 00041 { 00042 xmutex.lock(); 00043 ymutex.lock(); 00044 if(ballxvel > 0) 00045 { 00046 if(mazearr[ballx+1][bally] != 1) 00047 { 00048 ballx++; 00049 } 00050 else 00051 { 00052 ballxvel = -ballxvel; 00053 00054 ms.play(wallbeep,tempo,wallbeep_len); 00055 } 00056 } 00057 else if (ballxvel < 0) 00058 { 00059 if(mazearr[ballx-1][bally] != 1) 00060 { 00061 ballx--; 00062 } 00063 else 00064 { 00065 ms.play(wallbeep,tempo,wallbeep_len); 00066 ballxvel = -ballxvel; 00067 } 00068 } 00069 xmutex.unlock(); 00070 ymutex.unlock(); 00071 Thread::wait(100-98*abs(ballxvel)); 00072 } 00073 } 00074 void ythread(void const *args) 00075 { 00076 while(1) 00077 { 00078 xmutex.lock(); 00079 ymutex.lock(); 00080 if(ballyvel > 0) 00081 { 00082 if(mazearr[ballx][bally+1] != 1) 00083 { 00084 bally++; 00085 } 00086 else 00087 { 00088 ballyvel = -ballyvel; 00089 ms.play(wallbeep,tempo,wallbeep_len); 00090 } 00091 } 00092 else if (ballyvel < 0) 00093 { 00094 if(mazearr[ballx][bally-1] != 1) 00095 { 00096 bally--; 00097 } 00098 else 00099 { 00100 ballyvel = -ballyvel; 00101 ms.play(wallbeep,tempo,wallbeep_len); 00102 } 00103 } 00104 xmutex.unlock(); 00105 ymutex.unlock(); 00106 Thread::wait(100-98*abs(ballyvel)); 00107 } 00108 } 00109 00110 int main() { 00111 //Overclock uLCD 00112 uLCD.baudrate(3000000); 00113 00114 //Title Screen 00115 //displayTitle(); 00116 00117 //Display Maze 00118 loadLevel(); 00119 displayMaze(); 00120 00121 //Music init 00122 ms.freq(240); 00123 ms.play(s1,tempo,s1_len); 00124 //ms.play(victory, tempo, victory_len); 00125 00126 //Start physics engine threads 00127 Thread t1(xthread); 00128 Thread t2(ythread); 00129 00130 //Initial velocity 00131 ballxvel = 0.5; 00132 ballyvel = -1; 00133 00134 //Execution Loop 00135 while(1) { 00136 00137 updateVelocity(); 00138 updateBall(); 00139 00140 } 00141 } 00142 00143 //This will be where the gyro values are used to accelerate/decelerate the ball 00144 void updateVelocity() 00145 { 00146 xmutex.lock(); 00147 ymutex.lock(); 00148 //These should be 0.0 - 1.0 values 00149 //ballxvel = 0.25; 00150 //ballyvel = -0.25; //Note: positive yvel will send the ball DOWN due to the uLCD coordinate system 00151 xmutex.unlock(); 00152 ymutex.unlock(); 00153 } 00154 00155 //Move the ball around and draw to the screen 00156 void updateBall() 00157 { 00158 xmutex.lock(); 00159 ymutex.lock(); 00160 00161 uLCD.pixel(ballx_old,bally_old,BLACK); //Wipe the old ball 00162 uLCD.pixel(ballx,bally,0xFFFF00); //Out with the old in with the new! 00163 ballx_old = ballx; 00164 bally_old = bally; 00165 00166 xmutex.unlock(); 00167 ymutex.unlock(); 00168 00169 //Draw start/end zones 00170 uLCD.filled_rectangle(2,2,22,22,GREEN); 00171 uLCD.filled_rectangle(106,106,126,126,0xFFFF00); 00172 00173 //Check victory condition 00174 if(ballx > 106 && bally > 106) 00175 { 00176 displayVictory(); 00177 } 00178 } 00179 00180 //Take whats in the mazearr and write it 00181 void displayMaze() 00182 { 00183 //Clear previous maze 00184 uLCD.filled_rectangle(0, 0, 128, 128, BLACK); 00185 00186 //Write in new maze 00187 for(int i = 0; i < 128; i++) 00188 { 00189 for(int j = 0; j < 128; j++) 00190 { 00191 if(mazearr[i][j] == 1) 00192 { 00193 uLCD.pixel(i,j,RED); 00194 } 00195 } 00196 } 00197 } 00198 00199 //This function will load a different map into the mazearray depending on the level selected 00200 void loadLevel() 00201 { 00202 //Load ball into starting zone 00203 ballx = 12; 00204 bally = 12; 00205 00206 //Zero out the previous maze 00207 for(int i = 0; i < 128; i++) 00208 { 00209 for(int j = 0; j < 128; j++) 00210 { 00211 mazearr[i][j] = 0; 00212 } 00213 } 00214 00215 //Load in test maze 00216 switch(gamestate) 00217 { 00218 case LEVEL1: 00219 //Load a test maze 00220 for(int i = 0; i <= 127; i++) 00221 { 00222 mazearr[i][0] = 1; 00223 mazearr[i][127] = 1; 00224 mazearr[0][i] = 1; 00225 mazearr[127][i] = 1; 00226 } 00227 for(int i = 0; i <= 100; i++) 00228 { 00229 mazearr[i][50] = 1; 00230 } 00231 for(int i = 0; i <= 75; i++) { 00232 mazearr[i][95] = 1; 00233 } 00234 for(int i = 50; i <= 75; i++) { 00235 mazearr[50][i] = 1; 00236 } 00237 break; 00238 00239 case LEVEL2: 00240 //Load a test maze 00241 for(int i = 0; i <= 127; i++) 00242 { 00243 mazearr[i][0] = 1; 00244 mazearr[i][127] = 1; 00245 mazearr[0][i] = 1; 00246 mazearr[127][i] = 1; 00247 } 00248 for(int i = 0; i <= 100; i++) 00249 { 00250 mazearr[i][24] = 1; 00251 } 00252 for(int i = 100; i <= 125; i++) { 00253 mazearr[i][95] = 1; 00254 } 00255 for(int i = 100; i <= 125; i++) { 00256 mazearr[95][i] = 1; 00257 } 00258 for(int i = 40; i <= 65; i++) { 00259 mazearr[i][i] = 1; 00260 } 00261 for(int i = 80; i <= 95; i++) { 00262 mazearr[i][i] = 1; 00263 } 00264 break; 00265 00266 } 00267 } 00268 00269 //Victory screen - 5 sec delay and then next level 00270 void displayVictory() 00271 { 00272 //Lock out physics engine (hacky way to stop ball movement) 00273 xmutex.lock(); 00274 ymutex.lock(); 00275 00276 ms.play(victory, tempo, victory_len); 00277 00278 //Move ball to start zone 00279 ballx = 12; 00280 bally = 12; 00281 00282 while(1) 00283 { 00284 uLCD.text_width(2); 00285 uLCD.text_height(2); 00286 uLCD.locate(1,3); 00287 uLCD.printf("VICTORY!"); 00288 wait(5); 00289 if (gamestate == LEVEL1) 00290 { 00291 gamestate = LEVEL2; 00292 loadLevel(); 00293 displayMaze(); 00294 wait(1); 00295 break; 00296 } 00297 } 00298 xmutex.unlock(); 00299 ymutex.unlock(); 00300 } 00301 00302 //Game title screen 00303 void displayTitle() 00304 { 00305 while(1) 00306 { 00307 uLCD.text_width(2); 00308 uLCD.text_height(2); 00309 uLCD.locate(0,0); 00310 uLCD.printf("SuperMbed"); 00311 uLCD.text_width(2); 00312 uLCD.text_height(3); 00313 uLCD.locate(2,1); 00314 uLCD.printf("Ball!"); 00315 } 00316 }
Generated on Wed Jul 13 2022 01:44:57 by 1.7.2