Albert Tan Mulligan Submission

Dependencies:   mbed

Committer:
Albutt
Date:
Tue May 26 19:52:01 2020 +0000
Revision:
16:a3a47fcba272
Parent:
15:3dbb3f4d7ae6
Child:
17:c81c09625d92
Finished Game Copy 2 (New Title)

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Albutt 15:3dbb3f4d7ae6 1 /*
eencae 0:b7f1f47bb26a 2 ELEC2645 Embedded Systems Project
eencae 0:b7f1f47bb26a 3 School of Electronic & Electrical Engineering
eencae 0:b7f1f47bb26a 4 University of Leeds
eencae 0:b7f1f47bb26a 5 2019/20
eencae 0:b7f1f47bb26a 6
Albutt 1:a52187d01a78 7 Name: Albert Tan Mulligan
Albutt 1:a52187d01a78 8 Username: el18ajst
Albutt 1:a52187d01a78 9 Student ID Number:201241153
Albutt 1:a52187d01a78 10 Date:10/4/2020
eencae 0:b7f1f47bb26a 11 */
eencae 0:b7f1f47bb26a 12
eencae 0:b7f1f47bb26a 13 // includes
eencae 0:b7f1f47bb26a 14 #include "mbed.h"
eencae 0:b7f1f47bb26a 15 #include "Gamepad.h"
eencae 0:b7f1f47bb26a 16 #include "N5110.h"
Albutt 2:c25ec0da7636 17 #include "Character.h"
Albutt 4:b16b6078a432 18 #include "Bullets.h"
Albutt 5:51fd6635141f 19 #include "Enemy.h"
Albutt 15:3dbb3f4d7ae6 20 #include "Bitmaps.h"
Albutt 6:546eba371942 21 #include <vector>
Albutt 15:3dbb3f4d7ae6 22 #include <Bitmap.h>
Albutt 2:c25ec0da7636 23 Serial pc(USBTX, USBRX);
Albutt 3:fcc9cf213a61 24 //STRUCTS
Albutt 3:fcc9cf213a61 25 struct State {
Albutt 15:3dbb3f4d7ae6 26 int number;
Albutt 15:3dbb3f4d7ae6 27 int next_state[2];
Albutt 3:fcc9cf213a61 28 };
Albutt 3:fcc9cf213a61 29
Albutt 3:fcc9cf213a61 30 //OBJECTS
eencae 0:b7f1f47bb26a 31 Gamepad pad;
eencae 0:b7f1f47bb26a 32 N5110 lcd;
Albutt 2:c25ec0da7636 33 Character p1;
Albutt 7:0434857199cf 34 vector<Bullets> shots;
Albutt 6:546eba371942 35 vector<Enemy> enemies;
Albutt 13:217c6102ffc0 36
Albutt 13:217c6102ffc0 37 //Variables
Albutt 10:71ced616a64f 38 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
Albutt 10:71ced616a64f 39 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};
Albutt 15:3dbb3f4d7ae6 40 int dead_music[6] = {0, 0, 220, 220, 220, 175};
Albutt 15:3dbb3f4d7ae6 41 int dead_duration[6] = {8,8,8,8,8,1};
Albutt 10:71ced616a64f 42 State fsm[4] = {
Albutt 15:3dbb3f4d7ae6 43 {0,{1,1}},
Albutt 15:3dbb3f4d7ae6 44 {1,{2,3}},
Albutt 15:3dbb3f4d7ae6 45 {2,{1,1}},
Albutt 15:3dbb3f4d7ae6 46 {3,{0,0}}
Albutt 15:3dbb3f4d7ae6 47 };
Albutt 3:fcc9cf213a61 48 volatile int Current_State = 0;
Albutt 6:546eba371942 49 volatile int timer = 0;
Albutt 10:71ced616a64f 50 volatile int score = 0;
Albutt 12:c557b6c9b17a 51 volatile int holder;
Albutt 13:217c6102ffc0 52
Albutt 3:fcc9cf213a61 53 //PROTOTYPES
Albutt 3:fcc9cf213a61 54 void menu();
Albutt 3:fcc9cf213a61 55 void GameRun();
Albutt 3:fcc9cf213a61 56 void Pause();
Albutt 10:71ced616a64f 57 void AddEnemy();
Albutt 10:71ced616a64f 58 void PlayerDead();
Albutt 10:71ced616a64f 59 void animation();
Albutt 10:71ced616a64f 60 void reset();
Albutt 12:c557b6c9b17a 61 void collisions();
Albutt 12:c557b6c9b17a 62 void draws();
Albutt 12:c557b6c9b17a 63 void updates(Direction dir);
Albutt 15:3dbb3f4d7ae6 64 void DeathAnimation();
Albutt 13:217c6102ffc0 65
Albutt 3:fcc9cf213a61 66 //FUNCTIONS
Albutt 15:3dbb3f4d7ae6 67 int main() //pc.printf("Main Open");
Albutt 15:3dbb3f4d7ae6 68 {
Albutt 15:3dbb3f4d7ae6 69 pad.init(); //initial setups
Albutt 2:c25ec0da7636 70 lcd.init();
Albutt 3:fcc9cf213a61 71 lcd.clear();
Albutt 3:fcc9cf213a61 72 //pc.printf("CoolTerm is Connected\n");
Albutt 15:3dbb3f4d7ae6 73 lcd.setContrast(0.3 + (pad.read_pot1() / 5.0));
Albutt 15:3dbb3f4d7ae6 74 while(1) {
Albutt 15:3dbb3f4d7ae6 75 //pc.printf("CurrentState = %d\n", Current_State);
Albutt 15:3dbb3f4d7ae6 76 if(Current_State == 0) {
Albutt 15:3dbb3f4d7ae6 77 menu();
Albutt 15:3dbb3f4d7ae6 78 } else if (Current_State == 1) {
Albutt 15:3dbb3f4d7ae6 79 GameRun();
Albutt 15:3dbb3f4d7ae6 80 } else if (Current_State == 2) {
Albutt 15:3dbb3f4d7ae6 81 Pause();
Albutt 15:3dbb3f4d7ae6 82 } else if (Current_State == 3) {
Albutt 15:3dbb3f4d7ae6 83 PlayerDead();
Albutt 15:3dbb3f4d7ae6 84 reset();
Albutt 3:fcc9cf213a61 85 }
Albutt 15:3dbb3f4d7ae6 86 }
Albutt 3:fcc9cf213a61 87 }
Albutt 3:fcc9cf213a61 88
Albutt 15:3dbb3f4d7ae6 89 void menu()
Albutt 15:3dbb3f4d7ae6 90 {
Albutt 3:fcc9cf213a61 91 //pc.printf("Menu Open");
Albutt 10:71ced616a64f 92 lcd.clear();
Albutt 16:a3a47fcba272 93 Bitmap sprite(Title, 17, 60);
Albutt 16:a3a47fcba272 94 sprite.render(lcd, 10, 6);
Albutt 15:3dbb3f4d7ae6 95 lcd.printString(" Press A to ",0,3);
Albutt 15:3dbb3f4d7ae6 96 lcd.printString("Start",27,4);
Albutt 3:fcc9cf213a61 97 lcd.refresh();
Albutt 12:c557b6c9b17a 98 while (1) {
Albutt 3:fcc9cf213a61 99 //pc.printf("While Loop + %d", g_pad.Button_A_flag);
Albutt 13:217c6102ffc0 100 if (pad.A_held()) {
Albutt 13:217c6102ffc0 101 //pc.printf("Button_A");
Albutt 13:217c6102ffc0 102 animation();
Albutt 13:217c6102ffc0 103 Current_State = fsm[0].next_state[0];
Albutt 13:217c6102ffc0 104 enemies.push_back(Enemy(timer));
Albutt 15:3dbb3f4d7ae6 105 timer = 0;
Albutt 13:217c6102ffc0 106 p1.init(40,22);
Albutt 13:217c6102ffc0 107 return;
Albutt 15:3dbb3f4d7ae6 108 }
Albutt 4:b16b6078a432 109 sleep();
Albutt 15:3dbb3f4d7ae6 110 }
Albutt 3:fcc9cf213a61 111 }
Albutt 15:3dbb3f4d7ae6 112 //Runs actual game code
Albutt 15:3dbb3f4d7ae6 113 void GameRun()
Albutt 15:3dbb3f4d7ae6 114 {
Albutt 3:fcc9cf213a61 115 //pc.printf("Game Open");
Albutt 2:c25ec0da7636 116 Direction dir = pad.get_direction();
Albutt 10:71ced616a64f 117 pad.play_melody(46, melody,durations,180.0,true);
Albutt 15:3dbb3f4d7ae6 118 while(1) { //main game run loop
Albutt 15:3dbb3f4d7ae6 119
Albutt 15:3dbb3f4d7ae6 120 timer++; //Timer to seed random functions/spawn enemies intermittently
Albutt 15:3dbb3f4d7ae6 121 if(timer % 100 == 0) {
Albutt 15:3dbb3f4d7ae6 122 AddEnemy();
Albutt 15:3dbb3f4d7ae6 123 }
Albutt 2:c25ec0da7636 124 dir = pad.get_direction();
Albutt 15:3dbb3f4d7ae6 125
Albutt 15:3dbb3f4d7ae6 126 if(dir == N) {
Albutt 15:3dbb3f4d7ae6 127 holder = 0; //setting a placeholder for last direction, because bullets should travel in facing direction if the joystick is in neutral position
Albutt 15:3dbb3f4d7ae6 128 } else if(dir == S) {
Albutt 15:3dbb3f4d7ae6 129 holder = 2;
Albutt 15:3dbb3f4d7ae6 130 } else if(dir == E) {
Albutt 15:3dbb3f4d7ae6 131 holder = 1;
Albutt 15:3dbb3f4d7ae6 132 } else if(dir == W) {
Albutt 15:3dbb3f4d7ae6 133 holder = 3;
Albutt 15:3dbb3f4d7ae6 134 }
Albutt 13:217c6102ffc0 135 //pc.printf("Direction holder = %d\n", holder);
Albutt 15:3dbb3f4d7ae6 136
Albutt 15:3dbb3f4d7ae6 137 if (pad.A_pressed()) { //shoot if A is pressed
Albutt 15:3dbb3f4d7ae6 138 shots.push_back( Bullets( p1.get_x() + 2, p1.get_y() + 2, holder));
Albutt 15:3dbb3f4d7ae6 139 }
Albutt 15:3dbb3f4d7ae6 140
Albutt 15:3dbb3f4d7ae6 141 //lcd updates, collsions and draws
Albutt 12:c557b6c9b17a 142 updates(dir);
Albutt 12:c557b6c9b17a 143 draws();
Albutt 12:c557b6c9b17a 144 collisions();
Albutt 15:3dbb3f4d7ae6 145
Albutt 13:217c6102ffc0 146 if (pad.start_held()) {
Albutt 15:3dbb3f4d7ae6 147 Current_State = fsm[Current_State].next_state[0]; //Brings up pause menu if you press start
Albutt 15:3dbb3f4d7ae6 148 return;
Albutt 15:3dbb3f4d7ae6 149 }
Albutt 15:3dbb3f4d7ae6 150
Albutt 15:3dbb3f4d7ae6 151 if(Current_State != 1) {
Albutt 15:3dbb3f4d7ae6 152 return; //Collisions could change current state to 3 (Dead state)
Albutt 15:3dbb3f4d7ae6 153 }
Albutt 13:217c6102ffc0 154 //setting frames
Albutt 4:b16b6078a432 155 wait(1.0f/10.0f);
Albutt 2:c25ec0da7636 156 }
eencae 0:b7f1f47bb26a 157 }
Albutt 13:217c6102ffc0 158
Albutt 15:3dbb3f4d7ae6 159 void Pause() //Creates the Pause menu
Albutt 15:3dbb3f4d7ae6 160 {
Albutt 15:3dbb3f4d7ae6 161 lcd.printString(" PAUSED",0,1);
Albutt 15:3dbb3f4d7ae6 162 lcd.refresh();
Albutt 15:3dbb3f4d7ae6 163 lcd.printString(" Press B to",0,4);
Albutt 15:3dbb3f4d7ae6 164 lcd.printString("Unpause",21,5);
Albutt 15:3dbb3f4d7ae6 165 if (pad.B_held()) { //B goes back to main game run code
Albutt 15:3dbb3f4d7ae6 166 Current_State = fsm[Current_State].next_state[0];
Albutt 15:3dbb3f4d7ae6 167 lcd.clear();
Albutt 15:3dbb3f4d7ae6 168 return;
Albutt 15:3dbb3f4d7ae6 169 }
Albutt 15:3dbb3f4d7ae6 170 sleep(); //sleep function for interrupt
Albutt 15:3dbb3f4d7ae6 171 }
Albutt 15:3dbb3f4d7ae6 172
Albutt 15:3dbb3f4d7ae6 173 void AddEnemy() //Add enemies
Albutt 15:3dbb3f4d7ae6 174 {
Albutt 15:3dbb3f4d7ae6 175 enemies.push_back(Enemy(timer)); //adds an enemy to the vector of enemy class
Albutt 15:3dbb3f4d7ae6 176 return;
Albutt 15:3dbb3f4d7ae6 177 }
Albutt 15:3dbb3f4d7ae6 178
Albutt 15:3dbb3f4d7ae6 179 void PlayerDead() //Called When Player Dies, B returns the game to menu
Albutt 15:3dbb3f4d7ae6 180 {
Albutt 15:3dbb3f4d7ae6 181 pad.play_melody(6, dead_music, dead_duration,90.0,false);
Albutt 15:3dbb3f4d7ae6 182 DeathAnimation();
Albutt 15:3dbb3f4d7ae6 183 lcd.inverseMode();
Albutt 15:3dbb3f4d7ae6 184 lcd.clear();
Albutt 15:3dbb3f4d7ae6 185 lcd.printString("YOU DIED",18,1);
Albutt 15:3dbb3f4d7ae6 186 char buffer[14];
Albutt 15:3dbb3f4d7ae6 187 if(score > 10) { //score displays differently if below 10 to make sure the text is centered
Albutt 15:3dbb3f4d7ae6 188 sprintf(buffer, " Score:%d", score);
Albutt 15:3dbb3f4d7ae6 189 lcd.printString(buffer,0,2);
Albutt 15:3dbb3f4d7ae6 190 } else {
Albutt 15:3dbb3f4d7ae6 191 sprintf(buffer, "Score:0%d", score);
Albutt 15:3dbb3f4d7ae6 192 lcd.printString(buffer,18,2);
Albutt 15:3dbb3f4d7ae6 193 }
Albutt 15:3dbb3f4d7ae6 194 lcd.printString(" Press B to ",0,4);
Albutt 15:3dbb3f4d7ae6 195 lcd.printString("Restart",21,5);
Albutt 15:3dbb3f4d7ae6 196 lcd.refresh();
Albutt 15:3dbb3f4d7ae6 197 while(1) {
Albutt 15:3dbb3f4d7ae6 198 if(pad.B_held()) {
Albutt 15:3dbb3f4d7ae6 199 Current_State =fsm[Current_State].next_state[1];
Albutt 15:3dbb3f4d7ae6 200 lcd.normalMode();
Albutt 3:fcc9cf213a61 201 return;
Albutt 3:fcc9cf213a61 202 }
Albutt 3:fcc9cf213a61 203 sleep();
Albutt 3:fcc9cf213a61 204 }
Albutt 15:3dbb3f4d7ae6 205 }
Albutt 15:3dbb3f4d7ae6 206
Albutt 15:3dbb3f4d7ae6 207 void animation() //Small animation for transition between main menus
Albutt 15:3dbb3f4d7ae6 208 {
Albutt 15:3dbb3f4d7ae6 209
Albutt 15:3dbb3f4d7ae6 210 for(int i = 1; i <= 42; i++) {
Albutt 15:3dbb3f4d7ae6 211 lcd.drawRect(0, 0, i, 48, FILL_BLACK);
Albutt 15:3dbb3f4d7ae6 212 lcd.drawRect(84-i, 0, i, 48, FILL_BLACK);
Albutt 15:3dbb3f4d7ae6 213 lcd.refresh();
Albutt 15:3dbb3f4d7ae6 214 wait(0.005);
Albutt 3:fcc9cf213a61 215 }
Albutt 15:3dbb3f4d7ae6 216
Albutt 15:3dbb3f4d7ae6 217 for(int i = 1; i <= 42; i++) {
Albutt 13:217c6102ffc0 218 lcd.drawRect(0, 0, i, 48, FILL_WHITE);
Albutt 13:217c6102ffc0 219 lcd.drawRect(84-i, 0, i, 48, FILL_WHITE);
Albutt 13:217c6102ffc0 220 lcd.refresh();
Albutt 13:217c6102ffc0 221 wait(0.005);
Albutt 10:71ced616a64f 222 }
Albutt 15:3dbb3f4d7ae6 223
Albutt 10:71ced616a64f 224 return;
Albutt 15:3dbb3f4d7ae6 225 }
Albutt 15:3dbb3f4d7ae6 226
Albutt 15:3dbb3f4d7ae6 227 void reset() //Resets the game variables when you die
Albutt 15:3dbb3f4d7ae6 228 {
Albutt 11:e60b40963095 229 score = 0;
Albutt 15:3dbb3f4d7ae6 230 while(enemies.size() >= 1) {
Albutt 11:e60b40963095 231 enemies.pop_back();
Albutt 11:e60b40963095 232 }
Albutt 15:3dbb3f4d7ae6 233
Albutt 15:3dbb3f4d7ae6 234 while(shots.size() >= 1) {
Albutt 11:e60b40963095 235 shots.pop_back();
Albutt 11:e60b40963095 236 }
Albutt 15:3dbb3f4d7ae6 237
Albutt 11:e60b40963095 238 p1.reset();
Albutt 13:217c6102ffc0 239 holder = 0;
Albutt 11:e60b40963095 240 return;
Albutt 15:3dbb3f4d7ae6 241 }
Albutt 15:3dbb3f4d7ae6 242
Albutt 15:3dbb3f4d7ae6 243 void collisions() //all the collisions
Albutt 15:3dbb3f4d7ae6 244 {
Albutt 15:3dbb3f4d7ae6 245
Albutt 15:3dbb3f4d7ae6 246 for(int i = 1; i < shots.size(); i++) { //Checking all shots to make sure they are erased if they leave the screen
Albutt 15:3dbb3f4d7ae6 247 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) {
Albutt 15:3dbb3f4d7ae6 248 shots.erase(shots.begin()+i);
Albutt 15:3dbb3f4d7ae6 249 }
Albutt 12:c557b6c9b17a 250 }
Albutt 15:3dbb3f4d7ae6 251
Albutt 15:3dbb3f4d7ae6 252 for(int i = 0; i < enemies.size(); i++) { //Checking all enemy-player collisions and enemy-bullet collisions
Albutt 15:3dbb3f4d7ae6 253 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
Albutt 15:3dbb3f4d7ae6 254
Albutt 13:217c6102ffc0 255 //enemy player collisions
Albutt 15:3dbb3f4d7ae6 256 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) {
Albutt 13:217c6102ffc0 257 Current_State = fsm[Current_State].next_state[1];
Albutt 13:217c6102ffc0 258 return;
Albutt 15:3dbb3f4d7ae6 259 }
Albutt 15:3dbb3f4d7ae6 260
Albutt 15:3dbb3f4d7ae6 261 for(int j = 0; j < shots.size(); j++) { //enemy bullet collisions
Albutt 15:3dbb3f4d7ae6 262 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) {
Albutt 13:217c6102ffc0 263 shots.at(j).dead();
Albutt 14:2d7e41f46879 264 enemies.at(i).reset(timer, lcd);
Albutt 13:217c6102ffc0 265 score++;
Albutt 13:217c6102ffc0 266 }
Albutt 13:217c6102ffc0 267 }
Albutt 12:c557b6c9b17a 268 }
Albutt 15:3dbb3f4d7ae6 269 }
Albutt 15:3dbb3f4d7ae6 270
Albutt 15:3dbb3f4d7ae6 271 void draws() //All the draw functions w/ clear and refresh
Albutt 15:3dbb3f4d7ae6 272 {
Albutt 15:3dbb3f4d7ae6 273 lcd.clear();
Albutt 15:3dbb3f4d7ae6 274 for(int i = 0; i < enemies.size(); i++) {
Albutt 15:3dbb3f4d7ae6 275 enemies.at(i).draw(lcd);
Albutt 12:c557b6c9b17a 276 }
Albutt 15:3dbb3f4d7ae6 277 for(int i = 0; i < shots.size(); i++) {
Albutt 15:3dbb3f4d7ae6 278 shots.at(i).draw(lcd);
Albutt 15:3dbb3f4d7ae6 279 }
Albutt 15:3dbb3f4d7ae6 280 p1.draw(lcd);
Albutt 15:3dbb3f4d7ae6 281 lcd.refresh();
Albutt 15:3dbb3f4d7ae6 282 }
Albutt 15:3dbb3f4d7ae6 283
Albutt 15:3dbb3f4d7ae6 284 void updates(Direction dir) //Updates objects after every frame(enemy update is in collisions)
Albutt 15:3dbb3f4d7ae6 285 {
Albutt 12:c557b6c9b17a 286 p1.update(dir);
Albutt 15:3dbb3f4d7ae6 287 for(int i = 0; i < shots.size(); i++) {
Albutt 12:c557b6c9b17a 288 shots.at(i).update();
Albutt 12:c557b6c9b17a 289 }
Albutt 15:3dbb3f4d7ae6 290 }
Albutt 15:3dbb3f4d7ae6 291
Albutt 15:3dbb3f4d7ae6 292 void DeathAnimation() //falling blood animation on death
Albutt 15:3dbb3f4d7ae6 293 {
Albutt 15:3dbb3f4d7ae6 294 for(int i = 1; i <= 65; i++) {
Albutt 15:3dbb3f4d7ae6 295 Bitmap sprite(falling_blood, 17, 84);
Albutt 15:3dbb3f4d7ae6 296 sprite.render(lcd, 0, i-17);
Albutt 15:3dbb3f4d7ae6 297 lcd.drawRect(84, i, 0, 0, FILL_BLACK);
Albutt 15:3dbb3f4d7ae6 298 lcd.refresh();
Albutt 15:3dbb3f4d7ae6 299 wait(0.03);
Albutt 15:3dbb3f4d7ae6 300 }
Albutt 12:c557b6c9b17a 301 }