
A skydiving game created using an mbed. This code used threads and mutexes to create a skydiving simulation on an uLCD. The sounds being played are read off of a microSD card and played through the speakers. The user controls the skydiver's movements with a navigation switch.
Dependencies: 4DGL-uLCD-SE SDFileSystem mbed-rtos mbed wave_player
main.cpp
- Committer:
- mhennessy3
- Date:
- 2016-03-16
- Revision:
- 0:2bc06deb0e7d
- Child:
- 1:d0bc93562029
File content as of revision 0:2bc06deb0e7d:
#include "mbed.h" #include "rtos.h" #include "uLCD_4DGL.h" #include "SDFileSystem.h" #include "wave_player.h" uLCD_4DGL uLCD(p28,p27,p30); // serial tx, serial rx, reset pin; Mutex lcd_mutex;// Create the mutex lock object PwmOut speaker(p21); //create a PwmOut object for the speaker SDFileSystem sd(p5, p6, p7, p21, "sd"); //SD card AnalogOut DACout(p18); wave_player waver(&DACout); ///////////////////////////////////////////////////////////////////////////////////////////// //Navigation Switch class class Nav_Switch { public: Nav_Switch(PinName up,PinName down,PinName left,PinName right,PinName fire); int read(); //boolean functions to test each switch bool up(); bool down(); bool left(); bool right(); bool fire(); //automatic read on RHS operator int (); //index to any switch array style bool operator[](int index) { return _pins[index]; }; private: BusIn _pins; }; Nav_Switch::Nav_Switch (PinName up,PinName down,PinName left,PinName right,PinName fire): _pins(up, down, left, right, fire) { _pins.mode(PullUp); //needed if pullups not on board or a bare nav switch is used - delete otherwise wait(0.001); //delays just a bit for pullups to pull inputs high } inline bool Nav_Switch::up() { return !(_pins[0]); } inline bool Nav_Switch::down() { return !(_pins[1]); } inline bool Nav_Switch::left() { return !(_pins[2]); } inline bool Nav_Switch::right() { return !(_pins[3]); } inline bool Nav_Switch::fire() { return !(_pins[4]); } inline int Nav_Switch::read() { return _pins.read(); } inline Nav_Switch::operator int () { return _pins.read(); } Nav_Switch myNav( p12, p9, p10, p8, p11); //pin order on Sparkfun breakout ////////////////////////////////////////////////////////////////////////////////////////////// // initialize variables int rx1, ry1, rrx1, rry1, rrrx1, rrry1, length; int rx2, rrx2, rrrx2; int dis_top, midC, breakT; int tx1, ty1, lx1, ly1; int stopLength, circY, parachute; int shapeColor1, count; // thread to write to LCD screen void thread1(void const *args){ //generates obstacles while(true){ lcd_mutex.lock();//acquire lock //Erase previous position of obstacles uLCD.filled_rectangle(rx1, ry1, rx1+10, ry1+10, BLUE); uLCD.filled_rectangle(rrx1, rry1, rrx1+10, rry1+10, BLUE); uLCD.filled_rectangle(rrrx1, rrry1, rrrx1+10, rrry1+10, BLUE); if(length<stopLength) { //continues the loop from offscreen to back on the screen when within a looped time if(ry1<0){ ry1=137; rx1=(rx1+30)%127; shapeColor1 = (shapeColor1 + 0x110000) & 0xFFFFFF; } if(rry1<0){ rry1=137; rrx1=(rrx1+65)%127; } if(rrry1<0){ rrry1=137; rrrx1=(rrrx1+93)%127; } if(ly1<0){ ly1=137; lx1 = (lx1+50)%127; } } // update positions of obstacles ry1 = ry1-10; rry1 = rry1-10; rrry1 = rrry1-10; ty1 = ty1-10; ly1 = ly1-10; wait(.01); // draw updated obstacles uLCD.filled_rectangle(rx1, ry1, rx1+10, ry1+10,shapeColor1);//change position uLCD.filled_rectangle(rrx1, rry1, rrx1+10, rry1+10,0xFF3300);//change position uLCD.filled_rectangle(rrrx1, rrry1, rrrx1+10, rrry1+10,0x99ffcc);//change position lcd_mutex.unlock();//release lock //Checking for collisions with obstacles rx2 = rx1+10; rrx2 = rrx1+10; rrrx2 = rrrx1 +10; dis_top= 8+7; //y pos of circle +radius 7 // detect a collision between skydiver and obstacle //circle 1 if( (((midC-7)<=rx2 && rx2<=(midC+7)) || ((midC-7)<=rx1 && rx1<=(midC+7))) && ((ry1<dis_top) && (ry1>0))) { lcd_mutex.lock(); uLCD.cls(); uLCD.text_width(2); //2X size text uLCD.text_height(2); uLCD.color(RED); uLCD.locate(2,2); uLCD.printf("\n GAME \n OVER!\n"); wait(.05); lcd_mutex.unlock(); break; } //circle 2 if( (((midC-7)<=rrx2 && rrx2<=(midC+7)) || ((midC-7)<=rrx1 && rrx1<=(midC+7))) && ((rry1<dis_top) && (rry1>0))) { lcd_mutex.lock(); uLCD.cls(); uLCD.text_width(2); //2X size text uLCD.text_height(2); uLCD.color(RED); uLCD.locate(2,2); uLCD.printf("\n GAME \n OVER!\n"); wait(.05); lcd_mutex.unlock(); break; } //circle 3 if( (((midC-7)<=rrrx2 && rrrx2<=(midC+7)) || ((midC-7)<=rrrx1 && rrrx1<=(midC+7))) && ((rrry1<dis_top) && (rrry1>0))) { lcd_mutex.lock(); uLCD.cls(); uLCD.text_width(2); //2X size text uLCD.text_height(2); uLCD.color(RED); uLCD.locate(2,2); uLCD.printf("\n GAME \n OVER!\n"); FILE *wave_file; wave_file=fopen("/sd/mydir/loser.wav","r"); waver.play(wave_file); fclose(wave_file); wait(2); lcd_mutex.unlock(); break; } length = length +1; //increment lenght or duration of the number of scrolls it goes through Thread::wait(500); // Begin the final fall to the ground if(length>=stopLength+15 && circY<109){ //displays text to hit fire while falling until you hit fire and deploy the parachute if(count==0){ lcd_mutex.lock(); uLCD.text_width(1); //2X size text uLCD.text_height(1); uLCD.color(GREEN); uLCD.locate(2,2); uLCD.printf("\n Hit fire for \n a parachute! \n"); //wait(2); lcd_mutex.unlock(); } lcd_mutex.lock(); uLCD.filled_rectangle(0, 128, 128, 118,GREEN); uLCD.filled_rectangle(90, 123, 105, 118,RED); if(parachute==1){ uLCD.triangle(midC-10,circY -25, midC+10, circY -25, midC, circY -7, BLUE); } uLCD.filled_circle(midC, circY, 7, BLUE); midC = midC-1; circY = circY + 2; if(parachute==1){ uLCD.triangle(midC-10,circY -25, midC+10, circY -25, midC, circY -7, BLACK); } uLCD.filled_circle(midC, circY, 7, BLACK); lcd_mutex.unlock();//release lock //if fire is pressed then parachute is deployed if(myNav.fire() == 1){ parachute = 1; lcd_mutex.lock(); uLCD.triangle(midC-10,circY -25, midC+10, circY -25, midC, circY -7, BLACK); uLCD.text_width(1); //2X size text uLCD.text_height(1); uLCD.color(BLUE); uLCD.locate(2,2); uLCD.printf("\n Hit fire for \n a parachute! \n"); count = 1; lcd_mutex.unlock(); } //checking to see if the botton of the circle touched the red space...if so you win if(circY+7==117 && (midC<=105 && midC>=90)) { lcd_mutex.lock(); uLCD.text_width(2); //2X size text uLCD.text_height(2); uLCD.color(GREEN); uLCD.locate(2,2); if(parachute == 1) { uLCD.printf("\n You \n WON!\n"); ///////////////////////////////////////////////////////SDcard reading from sound for winning!!!! FILE *wave_file; wave_file=fopen("/sd/mydir/yababy.wav","r"); waver.play(wave_file); fclose(wave_file); } //if you don't deploy your parachute but still land ont he red, you still lose if(parachute == 0) { uLCD.printf("\n You \n lost.\n"); // SDcard reading for losing FILE *wave_file; wave_file=fopen("/sd/mydir/loser.wav","r"); waver.play(wave_file); fclose(wave_file); } lcd_mutex.unlock(); } //checks to see if you touch green part of the ground if(circY+7>=117 && (midC>105 || midC<90)) { lcd_mutex.lock(); uLCD.text_width(2); //2X size text uLCD.text_height(2); uLCD.color(GREEN); uLCD.locate(2,2); uLCD.printf("\n You \n lost.\n"); // SDcard reading for losing FILE *wave_file; wave_file=fopen("/sd/mydir/loser.wav","r"); waver.play(wave_file); fclose(wave_file); //wait(2); lcd_mutex.unlock(); } } } } /*// Sound Thread for Wind void thread2(void const *args) { if(parachute == 1) { FILE *wave_file; wave_file=fopen("/sd/mydir/Wind.wav","r"); waver.play(wave_file); fclose(wave_file); } }*/ int main() { //uLCD.text_mode(OPAQUE); // Initial start screen and countdown to beginning of game uLCD.printf("\nSkydiving!\n"); //Default Green on black text uLCD.printf("\n Starting Game \nShortly..."); uLCD.text_width(4); //4X size text uLCD.text_height(4); uLCD.color(RED); wait(2); for (int i=3; i>=0; --i) { uLCD.locate(1,2); uLCD.printf("%2D",i); wait(1); } uLCD.cls(); //uLCD.printf("Change baudrate......"); uLCD.baudrate(3000000); //jack up baud rate to max for fast display //if demo hangs here - try lower baud rates // // printf text only full screen mode demo uLCD.background_color(BLUE); uLCD.cls(); uLCD.locate(0,0); uLCD.color(WHITE); uLCD.textbackground_color(BLUE); uLCD.set_font(FONT_7X8); uLCD.text_mode(OPAQUE); //initialization of variables circY = 8; rx1 = 10; ry1 = 160; rrx1 = 50; rry1 = 128; rrrx1 = 100; rrry1 = 200; tx1=10; ty1=30; lx1 = 25; ly1 = 130; length =0; midC = 64; breakT = 0; stopLength = 50; shapeColor1 = 0x66FF33; uLCD.filled_circle(midC, 8, 7, BLACK); // draw initial skydiver // draw initial obstacles uLCD.filled_rectangle(rx1, ry1, rx1+10, ry1+10, WHITE); uLCD.filled_rectangle(rrx1, rry1, rrx1+10, rry1+10, WHITE); uLCD.filled_rectangle(rrrx1, rrry1, rrrx1+10, rrry1+10, WHITE); uLCD.filled_circle(midC, circY, 7, BLACK); ///// Sound of Scream jumping out of Airplane FILE *wave_file; wave_file=fopen("/sd/mydir/scream_male.wav","r"); waver.play(wave_file); fclose(wave_file); //// End Scream Thread t1(thread1); //Thread t2(thread2); while(true) { if(breakT ==1){ uLCD.cls(); uLCD.filled_circle(midC, circY, 7, BLACK); } //control if nav switch is switch left if(myNav.left() == 0x01){ lcd_mutex.lock();//acquire lock if(parachute==1){ uLCD.triangle(midC-10,circY -25, midC+10, circY -25, midC, circY -7, BLUE); } uLCD.filled_circle(midC, circY, 7, BLUE); if((midC-1)<=7){ midC = 7; } else{ midC = midC-1; } if(parachute==1){ uLCD.triangle(midC-10,circY -25, midC+10, circY -25, midC, circY -7, BLACK); } uLCD.filled_circle(midC, circY, 7, BLACK); lcd_mutex.unlock();//release lock } //control if nav switch is switched right if(myNav.right() == 0x01){ lcd_mutex.lock();//acquire lock if(parachute==1){ uLCD.triangle(midC-10,circY -25, midC+10, circY -25, midC, circY -7, BLUE); } uLCD.filled_circle(midC, circY, 7, BLUE); if((midC+1)>=120){ midC = 120; } else{ midC = midC+1; } if(parachute==1){ uLCD.triangle(midC-10,circY -25, midC+10, circY -25, midC, circY -7, BLACK); } uLCD.filled_circle(midC, circY, 7, BLACK); lcd_mutex.unlock();//release lock } } }