Albert Tan-Mulligan / Mbed 2 deprecated ELEC2645_Project_el18ajst

Dependencies:   mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 /*
00002 ELEC2645 Embedded Systems Project
00003 School of Electronic & Electrical Engineering
00004 University of Leeds
00005 2019/20
00006 
00007 Name: Albert Tan Mulligan
00008 Username: el18ajst
00009 Student ID Number:201241153
00010 Date:10/4/2020
00011 */
00012 
00013 // INCLUDES
00014 #include "mbed.h"
00015 #include "Gamepad.h"
00016 #include "N5110.h"
00017 #include "Character.h"
00018 #include "Bullets.h"
00019 #include "Enemy.h"
00020 #include "Bitmaps.h"
00021 #include <vector>
00022 #include <Bitmap.h>
00023 
00024 //my computer had issues with CoolTerm but setting up serial communication fixed it
00025 Serial pc(USBTX, USBRX);
00026 //STRUCTS
00027 struct State {
00028     int number;
00029     int next_state[2];
00030 };
00031 
00032 //OBJECTS
00033 Gamepad pad;
00034 N5110 lcd;
00035 Character p1;
00036 vector<Bullets> shots;
00037 vector<Enemy> enemies;
00038 
00039 //Variables
00040 int melody[46] = {277, 330, 311, 277, 330, 311, 330, 311, 370, 330, 415, 330, 277, 330, 311, 277, 330, 311, 330, 311, 370, 330, 311, 247, 277, 330, 311, 277, 330, 311, 330, 311, 370, 330, 415, 440, 330, 415, 440, 494, 554, 415, 440, 494, 622, 659}; // #c = 277, d# =311, f# = 370, g# = 415
00041 int durations[46] = {4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4};
00042 int dead_music[6] = {0, 0, 220, 220, 220, 175};
00043 int dead_duration[6] = {8,8,8,8,8,1};
00044 State fsm[4] = {
00045     {0,{1,1}},
00046     {1,{2,3}},
00047     {2,{1,1}},
00048     {3,{0,0}}
00049 };
00050 volatile int Current_State = 0;
00051 volatile int timer = 0;
00052 volatile int score = 0;
00053 volatile int holder;
00054 
00055 //PROTOTYPES
00056 void menu();
00057 void GameRun();
00058 void Pause();
00059 void AddEnemy();
00060 void PlayerDead();
00061 void animation();
00062 void reset();
00063 void collisions();
00064 void draws();
00065 void updates(Direction dir);
00066 void DeathAnimation();
00067 
00068 //FUNCTIONS
00069 int main()      //pc.printf("Main Open");
00070 {
00071         pad.init();      //initial setups
00072     lcd.init();
00073     lcd.clear();
00074     //pc.printf("CoolTerm is Connected\n");
00075     lcd.setContrast(0.3 + (pad.read_pot1() / 5.0));
00076     while(1) {
00077         //pc.printf("CurrentState = %d\n", Current_State);
00078         if(Current_State == 0) {
00079             menu();
00080         } else if (Current_State == 1) {
00081             GameRun();
00082         } else if (Current_State == 2) {
00083             Pause();
00084         } else if (Current_State == 3) {
00085             PlayerDead();
00086             reset();
00087         }
00088     }
00089 }
00090 
00091 void menu()
00092 {
00093     //pc.printf("Menu Open");
00094     lcd.clear();
00095     Bitmap sprite(Title, 17, 60);
00096         sprite.render(lcd, 10, 6);
00097     lcd.printString("  Press A to  ",0,3);
00098     lcd.printString("Start",27,4);
00099     lcd.refresh();
00100     while (1) {
00101         //pc.printf("While Loop + %d", g_pad.Button_A_flag);
00102         if (pad.A_held()) {
00103             //pc.printf("Button_A");
00104             animation();
00105             Current_State = fsm[0].next_state[0];
00106             enemies.push_back(Enemy(timer));
00107             timer = 0;
00108             p1.init(40,22);
00109             return;
00110         }
00111         sleep();
00112     }
00113 }
00114 //Runs actual game code
00115 void GameRun()
00116 {
00117     //pc.printf("Game Open/n");
00118     Direction dir = pad.get_direction();
00119     pad.play_melody(46, melody,durations,180.0,true);
00120     while(1) {  //main game run loop
00121         //pc.printf("Direction = %d/n", dir);
00122         timer++;    //Timer to seed random functions/spawn enemies intermittently
00123         if(timer % 100 == 0) {
00124             AddEnemy();
00125         }
00126         dir = pad.get_direction();
00127 
00128         if(dir == N) {
00129             holder = 0;    //setting a placeholder for last direction, because bullets should travel in facing direction if the joystick is in neutral position
00130         } else if(dir == S) {
00131             holder = 2;
00132         } else if(dir == E) {
00133             holder = 1;
00134         } else if(dir == W) {
00135             holder = 3;
00136         }
00137         //pc.printf("Direction holder = %d\n", holder);
00138 
00139         if (pad.A_pressed()) {        //shoot if A is pressed
00140             shots.push_back( Bullets( p1.get_x() + 2, p1.get_y() + 2, holder));
00141         }
00142 
00143         //lcd updates, collsions and draws
00144         updates(dir);
00145         draws();
00146         collisions();
00147 
00148         if (pad.start_held()) {
00149             //pc.printf("Start Held/n");
00150             Current_State = fsm[Current_State].next_state[0];   //Brings up pause menu if you press start
00151             return;
00152         }
00153 
00154         if(Current_State != 1) {
00155             return;    //Collisions could change current state to 3 (Dead state)
00156         }
00157         //setting frames
00158         wait(1.0f/10.0f);
00159     }
00160 }
00161 
00162 void Pause()    //Creates the Pause menu
00163 {
00164     //pc.printf("Pause Menu/n");
00165     lcd.printString("    PAUSED",0,1);
00166     lcd.refresh();
00167     lcd.printString("  Press B to",0,4);
00168     lcd.printString("Unpause",21,5);
00169     if (pad.B_held()) {             //B goes back to main game run code
00170         //pc.printf("B Held/n");
00171         Current_State = fsm[Current_State].next_state[0];
00172         lcd.clear();
00173         return;
00174     }
00175     sleep();    //sleep function for interrupt
00176 }
00177 
00178 void AddEnemy()     //Add enemies
00179 {
00180     //pc.printf("Add Enemy/n");
00181     enemies.push_back(Enemy(timer));    //adds an enemy to the vector of enemy class
00182     return;
00183 }
00184 
00185 void PlayerDead() //Called When Player Dies, B returns the game to menu
00186 {   
00187     //pc.printf("Player Dead/n");
00188     pad.play_melody(6, dead_music, dead_duration,90.0,false);
00189     DeathAnimation();
00190     lcd.inverseMode();
00191     lcd.clear();
00192     lcd.printString("YOU DIED",18,1);
00193     char buffer[14];
00194     if(score >= 10) {  //score displays differently if below 10 to make sure the text is centered
00195         sprintf(buffer, "   Score:%d", score);
00196         lcd.printString(buffer,0,2);
00197     } else {
00198         sprintf(buffer, "Score:0%d", score);
00199         lcd.printString(buffer,18,2);
00200     }
00201     lcd.printString("  Press B to  ",0,4);
00202     lcd.printString("Restart",21,5);
00203     lcd.refresh();
00204     while(1) {
00205         if(pad.B_held()) {
00206             Current_State =fsm[Current_State].next_state[1];
00207             lcd.normalMode();
00208             return;
00209         }
00210         sleep();
00211     }
00212 }
00213 
00214 void animation()    //Small animation for transition between main menus
00215 {
00216 
00217     for(int i = 1; i <= 42; i++) {
00218         lcd.drawRect(0, 0, i, 48, FILL_BLACK);
00219         lcd.drawRect(84-i, 0, i, 48, FILL_BLACK);
00220         lcd.refresh();
00221         wait(0.005);
00222     }
00223 
00224     for(int i = 1; i <= 42; i++) {
00225         lcd.drawRect(0, 0, i, 48, FILL_WHITE);
00226         lcd.drawRect(84-i, 0, i, 48, FILL_WHITE);
00227         lcd.refresh();
00228         wait(0.005);
00229     }
00230 
00231     return;
00232 }
00233 
00234 void reset() //Resets the game variables when you die
00235 {
00236     //pc.printf("Game Reset/n");
00237     score = 0;
00238     while(enemies.size() >= 1) {
00239         enemies.pop_back();
00240     }
00241 
00242     while(shots.size() >= 1) {
00243         shots.pop_back();
00244     }
00245 
00246     p1.reset();
00247     holder = 0;
00248     return;
00249 }
00250 
00251 void collisions() //all the collisions
00252 {
00253     //pc.printf("Collisions/n");
00254     for(int i = 1; i < shots.size(); i++) { //Checking all shots to make sure they are erased if they leave the screen
00255         if(shots.at(i).get_x()>84 | shots.at(i).get_x()<1 | shots.at(i).get_y()>48 | shots.at(i).get_y()<1) {
00256             shots.erase(shots.begin()+i);
00257         }
00258     }
00259 
00260     for(int i = 0; i < enemies.size(); i++) {   //Checking all enemy-player collisions and enemy-bullet collisions
00261         enemies.at(i).update(p1.get_x()+1, p1.get_y()+1);   //update enemies to save processing time of having another large for loop in updates function
00262 
00263         //enemy player collisions
00264         if(enemies.at(i).get_x() >= p1.get_x()-1 & enemies.at(i).get_x() <= p1.get_x()+3 & enemies.at(i).get_y() >= p1.get_y()-1 & enemies.at(i).get_y() <= p1.get_y()+3) {
00265             Current_State = fsm[Current_State].next_state[1];
00266             return;
00267         }
00268 
00269         for(int j = 0; j < shots.size(); j++) { //enemy bullet collisions
00270             if(shots.at(j).get_x() >= enemies.at(i).get_x() & shots.at(j).get_x() <= enemies.at(i).get_x()+3 & shots.at(j).get_y() >= enemies.at(i).get_y() & shots.at(j).get_y() <= enemies.at(i).get_y()+3) {
00271                 shots.at(j).dead();
00272                 enemies.at(i).reset(timer, lcd);
00273                 score++;
00274             }
00275         }
00276     }
00277 }
00278 
00279 void draws()    //All the draw functions w/ clear and refresh
00280 {
00281     //pc.printf("Draw Functions/n");
00282     lcd.clear();
00283     for(int i = 0; i < enemies.size(); i++) {
00284         enemies.at(i).draw(lcd);
00285     }
00286     for(int i = 0; i < shots.size(); i++) {
00287         shots.at(i).draw(lcd);
00288     }
00289     p1.draw(lcd);
00290     lcd.refresh();
00291 }
00292 
00293 void updates(Direction dir)     //Updates objects after every frame(enemy update is in collisions)
00294 {
00295     //pc.printf("Update Functions/n");
00296     p1.update(dir);
00297     for(int i = 0; i < shots.size(); i++) {
00298         shots.at(i).update();
00299     }
00300 }
00301 
00302 void DeathAnimation()      //falling blood animation on death
00303 {
00304     for(int i = 1; i <= 65; i++) {
00305         Bitmap sprite(falling_blood, 17, 84);
00306         sprite.render(lcd, 0, i-17);
00307         lcd.drawRect(84, i, 0, 0, FILL_BLACK);
00308         lcd.refresh();
00309         wait(0.03);
00310     }
00311 }