This is a ball on the Mbed.
Dependencies: 4DGL-uLCD-SE IMUfilter ITG3200 Music mbed-rtos mbed
Diff: main_legacy.cpp
- Revision:
- 0:680348a938f8
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main_legacy.cpp Fri Mar 14 17:03:16 2014 +0000 @@ -0,0 +1,316 @@ +#include "mbed.h" +#include "uLCD_4DGL.h" +#include "rtos.h" +#include "Music.h" +#include "IMU_RPY.h" + +DigitalOut myled(LED1); +AnalogIn xpot(p19); +AnalogIn ypot(p20); +uLCD_4DGL uLCD(p9,p10,p11); +music ms(p21); + +Mutex xmutex,ymutex; +char mazearr[128][128]; +char ballx, bally; +char ballx_old, bally_old; +float ballxvel, ballyvel, ballvel; +enum LEVELSELECT {LEVEL1, LEVEL2, LEVEL3}; +LEVELSELECT gamestate = LEVEL1; + +//Sound bytes +char s1[] = "E4:8; E4:8; R:8; E4:8; R:8; C4:8; E4:4; G4:4; R:4; G3:4; R:4;"; +int s1_len = 61; +char wallbeep[] = "C4:48;"; +int wallbeep_len = 6; +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;"; +int victory_len = 102; +double tempo = 180; + +void displayTitle(); +void displayMaze(); +void updateVelocity(); +void updateBall(); +void loadLevel(); +void displayVictory(); + +//xthread and ythread act as the physics engine, simulating velocity and wall detection +void xthread(void const *args) +{ + while(1) + { + xmutex.lock(); + ymutex.lock(); + if(ballxvel > 0) + { + if(mazearr[ballx+1][bally] != 1) + { + ballx++; + } + else + { + ballxvel = -ballxvel; + + ms.play(wallbeep,tempo,wallbeep_len); + } + } + else if (ballxvel < 0) + { + if(mazearr[ballx-1][bally] != 1) + { + ballx--; + } + else + { + ms.play(wallbeep,tempo,wallbeep_len); + ballxvel = -ballxvel; + } + } + xmutex.unlock(); + ymutex.unlock(); + Thread::wait(100-98*abs(ballxvel)); + } +} +void ythread(void const *args) +{ + while(1) + { + xmutex.lock(); + ymutex.lock(); + if(ballyvel > 0) + { + if(mazearr[ballx][bally+1] != 1) + { + bally++; + } + else + { + ballyvel = -ballyvel; + ms.play(wallbeep,tempo,wallbeep_len); + } + } + else if (ballyvel < 0) + { + if(mazearr[ballx][bally-1] != 1) + { + bally--; + } + else + { + ballyvel = -ballyvel; + ms.play(wallbeep,tempo,wallbeep_len); + } + } + xmutex.unlock(); + ymutex.unlock(); + Thread::wait(100-98*abs(ballyvel)); + } +} + +int main() { + //Overclock uLCD + uLCD.baudrate(3000000); + + //Title Screen + //displayTitle(); + + //Display Maze + loadLevel(); + displayMaze(); + + //Music init + ms.freq(240); + ms.play(s1,tempo,s1_len); + //ms.play(victory, tempo, victory_len); + + //Start physics engine threads + Thread t1(xthread); + Thread t2(ythread); + + //Initial velocity + ballxvel = 0.5; + ballyvel = -1; + + //Execution Loop + while(1) { + + updateVelocity(); + updateBall(); + + } +} + +//This will be where the gyro values are used to accelerate/decelerate the ball +void updateVelocity() +{ + xmutex.lock(); + ymutex.lock(); + //These should be 0.0 - 1.0 values + //ballxvel = 0.25; + //ballyvel = -0.25; //Note: positive yvel will send the ball DOWN due to the uLCD coordinate system + xmutex.unlock(); + ymutex.unlock(); +} + +//Move the ball around and draw to the screen +void updateBall() +{ + xmutex.lock(); + ymutex.lock(); + + uLCD.pixel(ballx_old,bally_old,BLACK); //Wipe the old ball + uLCD.pixel(ballx,bally,0xFFFF00); //Out with the old in with the new! + ballx_old = ballx; + bally_old = bally; + + xmutex.unlock(); + ymutex.unlock(); + + //Draw start/end zones + uLCD.filled_rectangle(2,2,22,22,GREEN); + uLCD.filled_rectangle(106,106,126,126,0xFFFF00); + + //Check victory condition + if(ballx > 106 && bally > 106) + { + displayVictory(); + } +} + +//Take whats in the mazearr and write it +void displayMaze() +{ + //Clear previous maze + uLCD.filled_rectangle(0, 0, 128, 128, BLACK); + + //Write in new maze + for(int i = 0; i < 128; i++) + { + for(int j = 0; j < 128; j++) + { + if(mazearr[i][j] == 1) + { + uLCD.pixel(i,j,RED); + } + } + } +} + +//This function will load a different map into the mazearray depending on the level selected +void loadLevel() +{ + //Load ball into starting zone + ballx = 12; + bally = 12; + + //Zero out the previous maze + for(int i = 0; i < 128; i++) + { + for(int j = 0; j < 128; j++) + { + mazearr[i][j] = 0; + } + } + + //Load in test maze + switch(gamestate) + { + case LEVEL1: + //Load a test maze + for(int i = 0; i <= 127; i++) + { + mazearr[i][0] = 1; + mazearr[i][127] = 1; + mazearr[0][i] = 1; + mazearr[127][i] = 1; + } + for(int i = 0; i <= 100; i++) + { + mazearr[i][50] = 1; + } + for(int i = 0; i <= 75; i++) { + mazearr[i][95] = 1; + } + for(int i = 50; i <= 75; i++) { + mazearr[50][i] = 1; + } + break; + + case LEVEL2: + //Load a test maze + for(int i = 0; i <= 127; i++) + { + mazearr[i][0] = 1; + mazearr[i][127] = 1; + mazearr[0][i] = 1; + mazearr[127][i] = 1; + } + for(int i = 0; i <= 100; i++) + { + mazearr[i][24] = 1; + } + for(int i = 100; i <= 125; i++) { + mazearr[i][95] = 1; + } + for(int i = 100; i <= 125; i++) { + mazearr[95][i] = 1; + } + for(int i = 40; i <= 65; i++) { + mazearr[i][i] = 1; + } + for(int i = 80; i <= 95; i++) { + mazearr[i][i] = 1; + } + break; + + } +} + +//Victory screen - 5 sec delay and then next level +void displayVictory() +{ + //Lock out physics engine (hacky way to stop ball movement) + xmutex.lock(); + ymutex.lock(); + + ms.play(victory, tempo, victory_len); + + //Move ball to start zone + ballx = 12; + bally = 12; + + while(1) + { + uLCD.text_width(2); + uLCD.text_height(2); + uLCD.locate(1,3); + uLCD.printf("VICTORY!"); + wait(5); + if (gamestate == LEVEL1) + { + gamestate = LEVEL2; + loadLevel(); + displayMaze(); + wait(1); + break; + } + } + xmutex.unlock(); + ymutex.unlock(); +} + +//Game title screen +void displayTitle() +{ + while(1) + { + uLCD.text_width(2); + uLCD.text_height(2); + uLCD.locate(0,0); + uLCD.printf("SuperMbed"); + uLCD.text_width(2); + uLCD.text_height(3); + uLCD.locate(2,1); + uLCD.printf("Ball!"); + } +} \ No newline at end of file