This is a ball on the Mbed.

Dependencies:   4DGL-uLCD-SE IMUfilter ITG3200 Music mbed-rtos mbed

Committer:
Strikewolf
Date:
Fri Mar 14 17:03:16 2014 +0000
Revision:
0:680348a938f8
Initial commit;

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Strikewolf 0:680348a938f8 1 #include "mbed.h"
Strikewolf 0:680348a938f8 2 #include "uLCD_4DGL.h"
Strikewolf 0:680348a938f8 3 #include "rtos.h"
Strikewolf 0:680348a938f8 4 #include "Music.h"
Strikewolf 0:680348a938f8 5 #include "IMU_RPY.h"
Strikewolf 0:680348a938f8 6
Strikewolf 0:680348a938f8 7 DigitalOut myled(LED1);
Strikewolf 0:680348a938f8 8 AnalogIn xpot(p19);
Strikewolf 0:680348a938f8 9 AnalogIn ypot(p20);
Strikewolf 0:680348a938f8 10 uLCD_4DGL uLCD(p9,p10,p11);
Strikewolf 0:680348a938f8 11 music ms(p21);
Strikewolf 0:680348a938f8 12
Strikewolf 0:680348a938f8 13 Mutex xmutex,ymutex;
Strikewolf 0:680348a938f8 14 char mazearr[128][128];
Strikewolf 0:680348a938f8 15 char ballx, bally;
Strikewolf 0:680348a938f8 16 char ballx_old, bally_old;
Strikewolf 0:680348a938f8 17 float ballxvel, ballyvel, ballvel;
Strikewolf 0:680348a938f8 18 enum LEVELSELECT {LEVEL1, LEVEL2, LEVEL3};
Strikewolf 0:680348a938f8 19 LEVELSELECT gamestate = LEVEL1;
Strikewolf 0:680348a938f8 20
Strikewolf 0:680348a938f8 21 //Sound bytes
Strikewolf 0:680348a938f8 22 char s1[] = "E4:8; E4:8; R:8; E4:8; R:8; C4:8; E4:4; G4:4; R:4; G3:4; R:4;";
Strikewolf 0:680348a938f8 23 int s1_len = 61;
Strikewolf 0:680348a938f8 24 char wallbeep[] = "C4:48;";
Strikewolf 0:680348a938f8 25 int wallbeep_len = 6;
Strikewolf 0:680348a938f8 26 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;";
Strikewolf 0:680348a938f8 27 int victory_len = 102;
Strikewolf 0:680348a938f8 28 double tempo = 180;
Strikewolf 0:680348a938f8 29
Strikewolf 0:680348a938f8 30 void displayTitle();
Strikewolf 0:680348a938f8 31 void displayMaze();
Strikewolf 0:680348a938f8 32 void updateVelocity();
Strikewolf 0:680348a938f8 33 void updateBall();
Strikewolf 0:680348a938f8 34 void loadLevel();
Strikewolf 0:680348a938f8 35 void displayVictory();
Strikewolf 0:680348a938f8 36
Strikewolf 0:680348a938f8 37 //xthread and ythread act as the physics engine, simulating velocity and wall detection
Strikewolf 0:680348a938f8 38 void xthread(void const *args)
Strikewolf 0:680348a938f8 39 {
Strikewolf 0:680348a938f8 40 while(1)
Strikewolf 0:680348a938f8 41 {
Strikewolf 0:680348a938f8 42 xmutex.lock();
Strikewolf 0:680348a938f8 43 ymutex.lock();
Strikewolf 0:680348a938f8 44 if(ballxvel > 0)
Strikewolf 0:680348a938f8 45 {
Strikewolf 0:680348a938f8 46 if(mazearr[ballx+1][bally] != 1)
Strikewolf 0:680348a938f8 47 {
Strikewolf 0:680348a938f8 48 ballx++;
Strikewolf 0:680348a938f8 49 }
Strikewolf 0:680348a938f8 50 else
Strikewolf 0:680348a938f8 51 {
Strikewolf 0:680348a938f8 52 ballxvel = -ballxvel;
Strikewolf 0:680348a938f8 53
Strikewolf 0:680348a938f8 54 ms.play(wallbeep,tempo,wallbeep_len);
Strikewolf 0:680348a938f8 55 }
Strikewolf 0:680348a938f8 56 }
Strikewolf 0:680348a938f8 57 else if (ballxvel < 0)
Strikewolf 0:680348a938f8 58 {
Strikewolf 0:680348a938f8 59 if(mazearr[ballx-1][bally] != 1)
Strikewolf 0:680348a938f8 60 {
Strikewolf 0:680348a938f8 61 ballx--;
Strikewolf 0:680348a938f8 62 }
Strikewolf 0:680348a938f8 63 else
Strikewolf 0:680348a938f8 64 {
Strikewolf 0:680348a938f8 65 ms.play(wallbeep,tempo,wallbeep_len);
Strikewolf 0:680348a938f8 66 ballxvel = -ballxvel;
Strikewolf 0:680348a938f8 67 }
Strikewolf 0:680348a938f8 68 }
Strikewolf 0:680348a938f8 69 xmutex.unlock();
Strikewolf 0:680348a938f8 70 ymutex.unlock();
Strikewolf 0:680348a938f8 71 Thread::wait(100-98*abs(ballxvel));
Strikewolf 0:680348a938f8 72 }
Strikewolf 0:680348a938f8 73 }
Strikewolf 0:680348a938f8 74 void ythread(void const *args)
Strikewolf 0:680348a938f8 75 {
Strikewolf 0:680348a938f8 76 while(1)
Strikewolf 0:680348a938f8 77 {
Strikewolf 0:680348a938f8 78 xmutex.lock();
Strikewolf 0:680348a938f8 79 ymutex.lock();
Strikewolf 0:680348a938f8 80 if(ballyvel > 0)
Strikewolf 0:680348a938f8 81 {
Strikewolf 0:680348a938f8 82 if(mazearr[ballx][bally+1] != 1)
Strikewolf 0:680348a938f8 83 {
Strikewolf 0:680348a938f8 84 bally++;
Strikewolf 0:680348a938f8 85 }
Strikewolf 0:680348a938f8 86 else
Strikewolf 0:680348a938f8 87 {
Strikewolf 0:680348a938f8 88 ballyvel = -ballyvel;
Strikewolf 0:680348a938f8 89 ms.play(wallbeep,tempo,wallbeep_len);
Strikewolf 0:680348a938f8 90 }
Strikewolf 0:680348a938f8 91 }
Strikewolf 0:680348a938f8 92 else if (ballyvel < 0)
Strikewolf 0:680348a938f8 93 {
Strikewolf 0:680348a938f8 94 if(mazearr[ballx][bally-1] != 1)
Strikewolf 0:680348a938f8 95 {
Strikewolf 0:680348a938f8 96 bally--;
Strikewolf 0:680348a938f8 97 }
Strikewolf 0:680348a938f8 98 else
Strikewolf 0:680348a938f8 99 {
Strikewolf 0:680348a938f8 100 ballyvel = -ballyvel;
Strikewolf 0:680348a938f8 101 ms.play(wallbeep,tempo,wallbeep_len);
Strikewolf 0:680348a938f8 102 }
Strikewolf 0:680348a938f8 103 }
Strikewolf 0:680348a938f8 104 xmutex.unlock();
Strikewolf 0:680348a938f8 105 ymutex.unlock();
Strikewolf 0:680348a938f8 106 Thread::wait(100-98*abs(ballyvel));
Strikewolf 0:680348a938f8 107 }
Strikewolf 0:680348a938f8 108 }
Strikewolf 0:680348a938f8 109
Strikewolf 0:680348a938f8 110 int main() {
Strikewolf 0:680348a938f8 111 //Overclock uLCD
Strikewolf 0:680348a938f8 112 uLCD.baudrate(3000000);
Strikewolf 0:680348a938f8 113
Strikewolf 0:680348a938f8 114 //Title Screen
Strikewolf 0:680348a938f8 115 //displayTitle();
Strikewolf 0:680348a938f8 116
Strikewolf 0:680348a938f8 117 //Display Maze
Strikewolf 0:680348a938f8 118 loadLevel();
Strikewolf 0:680348a938f8 119 displayMaze();
Strikewolf 0:680348a938f8 120
Strikewolf 0:680348a938f8 121 //Music init
Strikewolf 0:680348a938f8 122 ms.freq(240);
Strikewolf 0:680348a938f8 123 ms.play(s1,tempo,s1_len);
Strikewolf 0:680348a938f8 124 //ms.play(victory, tempo, victory_len);
Strikewolf 0:680348a938f8 125
Strikewolf 0:680348a938f8 126 //Start physics engine threads
Strikewolf 0:680348a938f8 127 Thread t1(xthread);
Strikewolf 0:680348a938f8 128 Thread t2(ythread);
Strikewolf 0:680348a938f8 129
Strikewolf 0:680348a938f8 130 //Initial velocity
Strikewolf 0:680348a938f8 131 ballxvel = 0.5;
Strikewolf 0:680348a938f8 132 ballyvel = -1;
Strikewolf 0:680348a938f8 133
Strikewolf 0:680348a938f8 134 //Execution Loop
Strikewolf 0:680348a938f8 135 while(1) {
Strikewolf 0:680348a938f8 136
Strikewolf 0:680348a938f8 137 updateVelocity();
Strikewolf 0:680348a938f8 138 updateBall();
Strikewolf 0:680348a938f8 139
Strikewolf 0:680348a938f8 140 }
Strikewolf 0:680348a938f8 141 }
Strikewolf 0:680348a938f8 142
Strikewolf 0:680348a938f8 143 //This will be where the gyro values are used to accelerate/decelerate the ball
Strikewolf 0:680348a938f8 144 void updateVelocity()
Strikewolf 0:680348a938f8 145 {
Strikewolf 0:680348a938f8 146 xmutex.lock();
Strikewolf 0:680348a938f8 147 ymutex.lock();
Strikewolf 0:680348a938f8 148 //These should be 0.0 - 1.0 values
Strikewolf 0:680348a938f8 149 //ballxvel = 0.25;
Strikewolf 0:680348a938f8 150 //ballyvel = -0.25; //Note: positive yvel will send the ball DOWN due to the uLCD coordinate system
Strikewolf 0:680348a938f8 151 xmutex.unlock();
Strikewolf 0:680348a938f8 152 ymutex.unlock();
Strikewolf 0:680348a938f8 153 }
Strikewolf 0:680348a938f8 154
Strikewolf 0:680348a938f8 155 //Move the ball around and draw to the screen
Strikewolf 0:680348a938f8 156 void updateBall()
Strikewolf 0:680348a938f8 157 {
Strikewolf 0:680348a938f8 158 xmutex.lock();
Strikewolf 0:680348a938f8 159 ymutex.lock();
Strikewolf 0:680348a938f8 160
Strikewolf 0:680348a938f8 161 uLCD.pixel(ballx_old,bally_old,BLACK); //Wipe the old ball
Strikewolf 0:680348a938f8 162 uLCD.pixel(ballx,bally,0xFFFF00); //Out with the old in with the new!
Strikewolf 0:680348a938f8 163 ballx_old = ballx;
Strikewolf 0:680348a938f8 164 bally_old = bally;
Strikewolf 0:680348a938f8 165
Strikewolf 0:680348a938f8 166 xmutex.unlock();
Strikewolf 0:680348a938f8 167 ymutex.unlock();
Strikewolf 0:680348a938f8 168
Strikewolf 0:680348a938f8 169 //Draw start/end zones
Strikewolf 0:680348a938f8 170 uLCD.filled_rectangle(2,2,22,22,GREEN);
Strikewolf 0:680348a938f8 171 uLCD.filled_rectangle(106,106,126,126,0xFFFF00);
Strikewolf 0:680348a938f8 172
Strikewolf 0:680348a938f8 173 //Check victory condition
Strikewolf 0:680348a938f8 174 if(ballx > 106 && bally > 106)
Strikewolf 0:680348a938f8 175 {
Strikewolf 0:680348a938f8 176 displayVictory();
Strikewolf 0:680348a938f8 177 }
Strikewolf 0:680348a938f8 178 }
Strikewolf 0:680348a938f8 179
Strikewolf 0:680348a938f8 180 //Take whats in the mazearr and write it
Strikewolf 0:680348a938f8 181 void displayMaze()
Strikewolf 0:680348a938f8 182 {
Strikewolf 0:680348a938f8 183 //Clear previous maze
Strikewolf 0:680348a938f8 184 uLCD.filled_rectangle(0, 0, 128, 128, BLACK);
Strikewolf 0:680348a938f8 185
Strikewolf 0:680348a938f8 186 //Write in new maze
Strikewolf 0:680348a938f8 187 for(int i = 0; i < 128; i++)
Strikewolf 0:680348a938f8 188 {
Strikewolf 0:680348a938f8 189 for(int j = 0; j < 128; j++)
Strikewolf 0:680348a938f8 190 {
Strikewolf 0:680348a938f8 191 if(mazearr[i][j] == 1)
Strikewolf 0:680348a938f8 192 {
Strikewolf 0:680348a938f8 193 uLCD.pixel(i,j,RED);
Strikewolf 0:680348a938f8 194 }
Strikewolf 0:680348a938f8 195 }
Strikewolf 0:680348a938f8 196 }
Strikewolf 0:680348a938f8 197 }
Strikewolf 0:680348a938f8 198
Strikewolf 0:680348a938f8 199 //This function will load a different map into the mazearray depending on the level selected
Strikewolf 0:680348a938f8 200 void loadLevel()
Strikewolf 0:680348a938f8 201 {
Strikewolf 0:680348a938f8 202 //Load ball into starting zone
Strikewolf 0:680348a938f8 203 ballx = 12;
Strikewolf 0:680348a938f8 204 bally = 12;
Strikewolf 0:680348a938f8 205
Strikewolf 0:680348a938f8 206 //Zero out the previous maze
Strikewolf 0:680348a938f8 207 for(int i = 0; i < 128; i++)
Strikewolf 0:680348a938f8 208 {
Strikewolf 0:680348a938f8 209 for(int j = 0; j < 128; j++)
Strikewolf 0:680348a938f8 210 {
Strikewolf 0:680348a938f8 211 mazearr[i][j] = 0;
Strikewolf 0:680348a938f8 212 }
Strikewolf 0:680348a938f8 213 }
Strikewolf 0:680348a938f8 214
Strikewolf 0:680348a938f8 215 //Load in test maze
Strikewolf 0:680348a938f8 216 switch(gamestate)
Strikewolf 0:680348a938f8 217 {
Strikewolf 0:680348a938f8 218 case LEVEL1:
Strikewolf 0:680348a938f8 219 //Load a test maze
Strikewolf 0:680348a938f8 220 for(int i = 0; i <= 127; i++)
Strikewolf 0:680348a938f8 221 {
Strikewolf 0:680348a938f8 222 mazearr[i][0] = 1;
Strikewolf 0:680348a938f8 223 mazearr[i][127] = 1;
Strikewolf 0:680348a938f8 224 mazearr[0][i] = 1;
Strikewolf 0:680348a938f8 225 mazearr[127][i] = 1;
Strikewolf 0:680348a938f8 226 }
Strikewolf 0:680348a938f8 227 for(int i = 0; i <= 100; i++)
Strikewolf 0:680348a938f8 228 {
Strikewolf 0:680348a938f8 229 mazearr[i][50] = 1;
Strikewolf 0:680348a938f8 230 }
Strikewolf 0:680348a938f8 231 for(int i = 0; i <= 75; i++) {
Strikewolf 0:680348a938f8 232 mazearr[i][95] = 1;
Strikewolf 0:680348a938f8 233 }
Strikewolf 0:680348a938f8 234 for(int i = 50; i <= 75; i++) {
Strikewolf 0:680348a938f8 235 mazearr[50][i] = 1;
Strikewolf 0:680348a938f8 236 }
Strikewolf 0:680348a938f8 237 break;
Strikewolf 0:680348a938f8 238
Strikewolf 0:680348a938f8 239 case LEVEL2:
Strikewolf 0:680348a938f8 240 //Load a test maze
Strikewolf 0:680348a938f8 241 for(int i = 0; i <= 127; i++)
Strikewolf 0:680348a938f8 242 {
Strikewolf 0:680348a938f8 243 mazearr[i][0] = 1;
Strikewolf 0:680348a938f8 244 mazearr[i][127] = 1;
Strikewolf 0:680348a938f8 245 mazearr[0][i] = 1;
Strikewolf 0:680348a938f8 246 mazearr[127][i] = 1;
Strikewolf 0:680348a938f8 247 }
Strikewolf 0:680348a938f8 248 for(int i = 0; i <= 100; i++)
Strikewolf 0:680348a938f8 249 {
Strikewolf 0:680348a938f8 250 mazearr[i][24] = 1;
Strikewolf 0:680348a938f8 251 }
Strikewolf 0:680348a938f8 252 for(int i = 100; i <= 125; i++) {
Strikewolf 0:680348a938f8 253 mazearr[i][95] = 1;
Strikewolf 0:680348a938f8 254 }
Strikewolf 0:680348a938f8 255 for(int i = 100; i <= 125; i++) {
Strikewolf 0:680348a938f8 256 mazearr[95][i] = 1;
Strikewolf 0:680348a938f8 257 }
Strikewolf 0:680348a938f8 258 for(int i = 40; i <= 65; i++) {
Strikewolf 0:680348a938f8 259 mazearr[i][i] = 1;
Strikewolf 0:680348a938f8 260 }
Strikewolf 0:680348a938f8 261 for(int i = 80; i <= 95; i++) {
Strikewolf 0:680348a938f8 262 mazearr[i][i] = 1;
Strikewolf 0:680348a938f8 263 }
Strikewolf 0:680348a938f8 264 break;
Strikewolf 0:680348a938f8 265
Strikewolf 0:680348a938f8 266 }
Strikewolf 0:680348a938f8 267 }
Strikewolf 0:680348a938f8 268
Strikewolf 0:680348a938f8 269 //Victory screen - 5 sec delay and then next level
Strikewolf 0:680348a938f8 270 void displayVictory()
Strikewolf 0:680348a938f8 271 {
Strikewolf 0:680348a938f8 272 //Lock out physics engine (hacky way to stop ball movement)
Strikewolf 0:680348a938f8 273 xmutex.lock();
Strikewolf 0:680348a938f8 274 ymutex.lock();
Strikewolf 0:680348a938f8 275
Strikewolf 0:680348a938f8 276 ms.play(victory, tempo, victory_len);
Strikewolf 0:680348a938f8 277
Strikewolf 0:680348a938f8 278 //Move ball to start zone
Strikewolf 0:680348a938f8 279 ballx = 12;
Strikewolf 0:680348a938f8 280 bally = 12;
Strikewolf 0:680348a938f8 281
Strikewolf 0:680348a938f8 282 while(1)
Strikewolf 0:680348a938f8 283 {
Strikewolf 0:680348a938f8 284 uLCD.text_width(2);
Strikewolf 0:680348a938f8 285 uLCD.text_height(2);
Strikewolf 0:680348a938f8 286 uLCD.locate(1,3);
Strikewolf 0:680348a938f8 287 uLCD.printf("VICTORY!");
Strikewolf 0:680348a938f8 288 wait(5);
Strikewolf 0:680348a938f8 289 if (gamestate == LEVEL1)
Strikewolf 0:680348a938f8 290 {
Strikewolf 0:680348a938f8 291 gamestate = LEVEL2;
Strikewolf 0:680348a938f8 292 loadLevel();
Strikewolf 0:680348a938f8 293 displayMaze();
Strikewolf 0:680348a938f8 294 wait(1);
Strikewolf 0:680348a938f8 295 break;
Strikewolf 0:680348a938f8 296 }
Strikewolf 0:680348a938f8 297 }
Strikewolf 0:680348a938f8 298 xmutex.unlock();
Strikewolf 0:680348a938f8 299 ymutex.unlock();
Strikewolf 0:680348a938f8 300 }
Strikewolf 0:680348a938f8 301
Strikewolf 0:680348a938f8 302 //Game title screen
Strikewolf 0:680348a938f8 303 void displayTitle()
Strikewolf 0:680348a938f8 304 {
Strikewolf 0:680348a938f8 305 while(1)
Strikewolf 0:680348a938f8 306 {
Strikewolf 0:680348a938f8 307 uLCD.text_width(2);
Strikewolf 0:680348a938f8 308 uLCD.text_height(2);
Strikewolf 0:680348a938f8 309 uLCD.locate(0,0);
Strikewolf 0:680348a938f8 310 uLCD.printf("SuperMbed");
Strikewolf 0:680348a938f8 311 uLCD.text_width(2);
Strikewolf 0:680348a938f8 312 uLCD.text_height(3);
Strikewolf 0:680348a938f8 313 uLCD.locate(2,1);
Strikewolf 0:680348a938f8 314 uLCD.printf("Ball!");
Strikewolf 0:680348a938f8 315 }
Strikewolf 0:680348a938f8 316 }