Mbed Galaga Game
Dependencies: 4DGL-uLCD-SE SDFileSystem mbed-rtos mbed wave_player
main.cpp
- Committer:
- amostafa9
- Date:
- 2016-03-14
- Revision:
- 0:c4b6bb8c2bf4
File content as of revision 0:c4b6bb8c2bf4:
#include "mbed.h" #include "uLCD_4DGL.h" #include "wave_player.h" #include "SDFileSystem.h" //#include "enemies.h" #include <vector> #include "rtos.h" uLCD_4DGL uLCD(p28,p27,p29); AnalogOut DACout(p18); DigitalOut vib(p21); wave_player waver(&DACout); SDFileSystem sd(p5, p6, p7, p8, "sd"); // mosi, miso, sck, cs BusOut mbedleds(LED1,LED2,LED3,LED4); //BusOut/In is faster than multiple DigitalOut/Ins int playLaser = 0;int playEnemyExplode = 0;int playerExplode = 0;//variables to trigger the speaker to play sounds void sdcard_thread(void const *argument)//thread to play the sounds { while(1) { if(playLaser){//play sound if player fires FILE *wave_file; wave_file=fopen("/sd/laser.wav","r"); waver.play(wave_file); fclose(wave_file); playLaser = 0; } if(playerExplode) { //play sound if player dies FILE *wave_file; wave_file=fopen("/sd/Bomb.wav","r"); waver.play(wave_file); fclose(wave_file); playerExplode = 0; } if(playEnemyExplode){//play sound if enemies get hit FILE *wave_file; wave_file=fopen("/sd/Bombnew.wav","r"); waver.play(wave_file); fclose(wave_file); playEnemyExplode = 0; } Thread::wait(50); } } 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(); } // Declar player dimensions int playerWidth = 7; int playerHeight = 3; int playerDelta = 3; int playerXpos = 64; int playerYpos = 113; #define maxNumPlayerMissiles 5 #define numEnemies 10 //struct for missiles typedef struct { int x; ///< The x-coordinate of missile current position int y; ///< The y-coordinate of missile current position int status; ///< The missile status, see MISSILE_STATUS } playerMissile; // infomration about missile position and status //struct for enemies typedef struct { int x; int y; int size; int status; } enemy; enemy enemies[numEnemies];//create a struct array of enemies // initialize the player's position, missile status, draw player, void player_draw(int x, int y, int playerColor) { uLCD.filled_rectangle(x, y, x+playerWidth, y+playerHeight, playerColor); uLCD.filled_rectangle(x+playerDelta, y-playerDelta, x+playerWidth-playerDelta, y+playerHeight, playerColor); } playerMissile playerMissiles[maxNumPlayerMissiles]; //struct array of player missiles //function to fire a missile void player_fire(void){ playerMissile PM; PM.x = playerXpos + (playerWidth/2); PM.y = playerYpos-playerDelta; PM.status = 1; for(int i=0;i<maxNumPlayerMissiles;i++){ if(playerMissiles[i].status==0){ playerMissiles[i]=PM; break; } } } //function to update all parts of the game void updateGame(){ for(int i=0;i<maxNumPlayerMissiles;i++){ // update all missiles if(playerMissiles[i].status == 1){ uLCD.circle(playerMissiles[i].x,playerMissiles[i].y,1,0x0); playerMissiles[i].y-=5; uLCD.circle(playerMissiles[i].x,playerMissiles[i].y,1,0xFF0000); } if(playerMissiles[i].y==0 || playerMissiles[i].status==0){ uLCD.circle(playerMissiles[i].x,playerMissiles[i].y,1,0x0); playerMissiles[i].status = 0; } //update all enemies for(int j=0;j<numEnemies;j++){ if(playerMissiles[i].status==1 && enemies[j].status==1 && playerMissiles[i].x>enemies[j].x && playerMissiles[i].x<enemies[j].x+enemies[j].size && playerMissiles[i].y>enemies[j].y && playerMissiles[i].y<enemies[j].y+enemies[j].size){ enemies[j].status = 0; playerMissiles[i].status = 0; playEnemyExplode=1; uLCD.filled_rectangle(enemies[j].x,enemies[j].y,enemies[j].x+enemies[j].size,enemies[j].y+enemies[j].size,0x0); } } } } //function to set initial position of enemies void enemies_init(void){ enemies[0].x = 1;enemies[0].y = 1;enemies[0].size = 8; enemies[1].x = 26;enemies[1].y = 1;enemies[1].size = 8; enemies[2].x = 51;enemies[2].y = 1;enemies[2].size = 8; enemies[3].x = 76;enemies[3].y = 1;enemies[3].size = 8; enemies[4].x = 101;enemies[4].y = 1;enemies[4].size = 8; enemies[5].x = 1;enemies[5].y = 20;enemies[5].size = 8; enemies[6].x = 26;enemies[6].y = 20;enemies[6].size = 8; enemies[7].x = 51;enemies[7].y = 20;enemies[7].size = 8; enemies[8].x = 76;enemies[8].y = 20;enemies[8].size = 8; enemies[9].x = 101;enemies[9].y = 20;enemies[9].size = 8; } Nav_Switch myNav( p15, p12, p13, p11, p14); //pin order on Sparkfun breakout int main() { Thread thread1(sdcard_thread); int ctr = 0;int distance=5;int vertical = 1;int win = 1;int numDeadEnemies=0; //initialize enemy statuses enemies[0].status = 1;enemies[1].status = 1;enemies[2].status = 1;enemies[3].status = 1;enemies[4].status = 1; enemies[5].status = 1;enemies[6].status = 1;enemies[7].status = 1;enemies[8].status = 1;enemies[9].status = 1; enemies_init(); //draw enemies for(int i=0;i<numEnemies;i++){ uLCD.filled_rectangle(enemies[i].x,enemies[i].y,enemies[i].x+enemies[i].size,enemies[i].y+enemies[i].size,0x00FF00); } int i; while(1) { //with pullups a button hit is a "0" - "~" inverts data to leds if(ctr%10==0){ for(i=0;i<numEnemies;i++){ if(enemies[i].status!=0){ //update enemy positions uLCD.filled_rectangle(enemies[i].x,enemies[i].y,enemies[i].x+enemies[i].size,enemies[i].y+enemies[i].size,0x0); if(vertical<0){enemies[i].x+=distance;}else{enemies[i].y+=5;} uLCD.filled_rectangle(enemies[i].x,enemies[i].y,enemies[i].x+enemies[i].size,enemies[i].y+enemies[i].size,0x00FF00); } } if(vertical<0){distance*=-1;}vertical*=-1; } mbedleds = ~(myNav & 0x0F); //update leds with nav switch direction inputs if(myNav.fire()){//fire missile vib = 1; Thread::wait(100); vib=0; playLaser = 1; player_fire(); mbedleds = 0x0F; //special all leds on case for fire (center button) } //or use - if(myNav[4]==0) mbedleds = 0x0F; //can index a switch bit like this if(myNav.right() && playerXpos <= 110){//player moves right player_draw(playerXpos,playerYpos,0x0); playerXpos+=5; } if(myNav.left() && playerXpos >= 0){//player moves left player_draw(playerXpos,playerYpos,0x0); playerXpos-=5; } player_draw(playerXpos,playerYpos,0xFFFF00);//draw the player updateGame(); //check if player has been hit for(i=0;i<numEnemies;i++){ if(enemies[i].status==1 && playerXpos>enemies[i].x && playerXpos<enemies[i].x+enemies[i].size && playerYpos>enemies[i].y && playerYpos<enemies[i].y+enemies[i].size){ player_draw(playerXpos,playerYpos,0x0);win=0;playerExplode=1;vib=1; } if(enemies[i].status==0)numDeadEnemies++; if(enemies[i].y>128)enemies[i].y=1; } // check for end game conditions if(numDeadEnemies==numEnemies){Thread::wait(1000);break;} if(!win){Thread::wait(1000);vib=0;playerExplode=0;break;} numDeadEnemies = 0; ctr++; Thread::wait(10); } uLCD.locate(5,5); if(win){ uLCD.printf("You Win!!"); }else{ uLCD.printf("GAME OVER"); } }