James Cummins / Mbed 2 deprecated el17jnc

Dependencies:   mbed

Committer:
JamesCummins
Date:
Thu May 09 01:09:18 2019 +0000
Revision:
38:a85bc227b907
Parent:
37:de1f584bce71
Child:
39:dfc489594f11
Doxygen documentation written out and in line commenting completed. Game working and finished. Tests.h still to write out

Who changed what in which revision?

UserRevisionLine numberNew contents of line
JamesCummins 0:7c96d84b673e 1 /*
JamesCummins 0:7c96d84b673e 2 ELEC2645 Embedded Systems Project
JamesCummins 0:7c96d84b673e 3 School of Electronic & Electrical Engineering
JamesCummins 0:7c96d84b673e 4 University of Leeds
JamesCummins 0:7c96d84b673e 5 Name: James Nathan Cummins
JamesCummins 0:7c96d84b673e 6 Username: el17jnc
JamesCummins 0:7c96d84b673e 7 Student ID Number: 201096364
JamesCummins 0:7c96d84b673e 8 Date: 22/03/19
JamesCummins 0:7c96d84b673e 9 */
JamesCummins 0:7c96d84b673e 10
JamesCummins 0:7c96d84b673e 11 #include "Gamepad.h"
JamesCummins 0:7c96d84b673e 12 #include "mbed.h"
JamesCummins 1:99d524f81566 13 #include "N5110.h"
JamesCummins 20:4a39a1a2be51 14 #include "BrickBreakerEngine.h"
JamesCummins 29:42651f87522b 15 #include "ClassicEngine.h"
JamesCummins 22:4e305ff8a050 16 #include "OptionsEngine.h"
JamesCummins 24:c6415cc74b17 17 #include "SDFileSystem.h"
JamesCummins 13:e5a36fbd48ae 18 #define RADIUS 3
JamesCummins 0:7c96d84b673e 19
JamesCummins 11:2cf0d4ce8677 20
JamesCummins 11:2cf0d4ce8677 21 //Objects
JamesCummins 6:952ac12c7f00 22 Gamepad gamepad;
JamesCummins 0:7c96d84b673e 23 N5110 lcd(PTC9,PTC0,PTC7,PTD2,PTD1,PTC11);
JamesCummins 29:42651f87522b 24 ClassicEngine classic;
JamesCummins 20:4a39a1a2be51 25 BrickBreakerEngine brick;
JamesCummins 22:4e305ff8a050 26 OptionsEngine opt;
JamesCummins 29:42651f87522b 27 Map map;
JamesCummins 11:2cf0d4ce8677 28 AnalogIn randnoise(PTB0);
JamesCummins 12:9982239b7906 29 FXOS8700CQ accelerometer(I2C_SDA,I2C_SCL);
JamesCummins 24:c6415cc74b17 30 Ball ball;
JamesCummins 25:b52aa23df120 31 Pause pause;
JamesCummins 24:c6415cc74b17 32 SDFileSystem sd(PTE3,PTE1,PTE2,PTE4,"sd");
JamesCummins 11:2cf0d4ce8677 33
JamesCummins 37:de1f584bce71 34 /** Enum for start menu options*/
JamesCummins 20:4a39a1a2be51 35 enum StartOption{
JamesCummins 20:4a39a1a2be51 36 CLASSIC,
JamesCummins 20:4a39a1a2be51 37 BRICKBREAKER,
JamesCummins 20:4a39a1a2be51 38 OPTIONS
JamesCummins 20:4a39a1a2be51 39 };
JamesCummins 20:4a39a1a2be51 40
JamesCummins 37:de1f584bce71 41 /**Start selection struct*/
JamesCummins 20:4a39a1a2be51 42 struct StartSelection{
JamesCummins 37:de1f584bce71 43 int output; /**<Integer output for line to print arrows to*/
JamesCummins 37:de1f584bce71 44 StartOption next_state[3]; /**<Array of enums for possible next start option*/
JamesCummins 20:4a39a1a2be51 45 };
JamesCummins 20:4a39a1a2be51 46
JamesCummins 11:2cf0d4ce8677 47 //Methods
JamesCummins 7:6eb9cade57ab 48 void startscreen();
JamesCummins 17:5104ecef5bd0 49 StartOption menu();
JamesCummins 12:9982239b7906 50 void init();
JamesCummins 15:1564bd6b713d 51 void print_start_menu(int output);
JamesCummins 29:42651f87522b 52 void classic_mode();
JamesCummins 25:b52aa23df120 53 void brickbreaker_mode();
JamesCummins 25:b52aa23df120 54 void options_menu();
JamesCummins 8:4e306b16a941 55
JamesCummins 11:2cf0d4ce8677 56
JamesCummins 17:5104ecef5bd0 57 ////////////////Main Function/////////////////
JamesCummins 8:4e306b16a941 58
JamesCummins 29:42651f87522b 59 int fps = 16; //declared globally so it doesn't have to be passed to
JamesCummins 29:42651f87522b 60 //the different game mode functions
JamesCummins 0:7c96d84b673e 61 int main(){
JamesCummins 38:a85bc227b907 62 init(); //first initialise all objects
JamesCummins 38:a85bc227b907 63 startscreen(); //then display the introductory screen
JamesCummins 38:a85bc227b907 64 while(1){ //keep game running until power is removed
JamesCummins 38:a85bc227b907 65 StartOption choice_selected = menu(); //get which mode user wants from the start menu
JamesCummins 38:a85bc227b907 66 if(choice_selected == CLASSIC){ classic_mode();} //jump to a game mode once
JamesCummins 38:a85bc227b907 67 if(choice_selected == BRICKBREAKER){ brickbreaker_mode();} //its respective enum is received
JamesCummins 38:a85bc227b907 68 if(choice_selected == OPTIONS){ options_menu();} //from the start menu
JamesCummins 16:e846864778c4 69 }
JamesCummins 0:7c96d84b673e 70 }
JamesCummins 8:4e306b16a941 71
JamesCummins 8:4e306b16a941 72
JamesCummins 11:2cf0d4ce8677 73
JamesCummins 8:4e306b16a941 74 //////////////Start up functions///////////////////
JamesCummins 11:2cf0d4ce8677 75
JamesCummins 38:a85bc227b907 76 void init(){ //initialise all objects in the game
JamesCummins 10:40c77d69e83c 77 gamepad.init();
JamesCummins 38:a85bc227b907 78 lcd.init(); //some objects are initialised again elsewhere
JamesCummins 38:a85bc227b907 79 lcd.setContrast(0.55); //e.g. to reset a game mode when restart is pressed
JamesCummins 31:c95f1b1d6423 80 classic.init(ball, map);
JamesCummins 23:61fa82f76808 81 brick.init(RADIUS, ball);
JamesCummins 22:4e305ff8a050 82 opt.init();
JamesCummins 29:42651f87522b 83 map.init();
JamesCummins 25:b52aa23df120 84 pause.init();
JamesCummins 18:08046153e6ad 85 accelerometer.init();
JamesCummins 24:c6415cc74b17 86 sd.disk_initialize();
JamesCummins 10:40c77d69e83c 87 wait(1);
JamesCummins 10:40c77d69e83c 88 }
JamesCummins 0:7c96d84b673e 89
JamesCummins 7:6eb9cade57ab 90 void startscreen() {
JamesCummins 1:99d524f81566 91 lcd.clear();
JamesCummins 38:a85bc227b907 92 char gamename[] = {'L', 'A', 'B', 'Y', 'R', 'I', 'N', 'T', 'H', ' ', ' ', '\0'}; //char array containing the game title
JamesCummins 3:f2e5ffd2b94c 93 int i = 0;
JamesCummins 38:a85bc227b907 94 for(int a = 0; a < 35; a++){ //from first letter position to end of the screen at 2 pixel intervals
JamesCummins 4:2f01b85e57f9 95 lcd.clear();
JamesCummins 38:a85bc227b907 96 lcd.drawCircle(24+2*a, 21, 3, FILL_BLACK); //move the ball 2 pixels at a time
JamesCummins 4:2f01b85e57f9 97 for (i = 0; i < a/3; i++) {
JamesCummins 38:a85bc227b907 98 lcd.printChar(gamename[i], 15+i*6, 2); //print the next letter in game title once the ball has moved past
JamesCummins 38:a85bc227b907 99 lcd.refresh(); //display all contents on LCD display
JamesCummins 4:2f01b85e57f9 100 }
JamesCummins 15:1564bd6b713d 101 wait_ms(50);
JamesCummins 4:2f01b85e57f9 102 }
JamesCummins 38:a85bc227b907 103 lcd.printString("Press start", 9, 4); //instruct user how to advance
JamesCummins 5:7e8f5fad7b6b 104 lcd.printString("to play >", 15, 5);
JamesCummins 38:a85bc227b907 105 lcd.refresh();
JamesCummins 6:952ac12c7f00 106 bool advance = false;
JamesCummins 38:a85bc227b907 107 while (!advance){ //check for user advancing
JamesCummins 6:952ac12c7f00 108 if (gamepad.check_event(gamepad.START_PRESSED)){
JamesCummins 38:a85bc227b907 109 lcd.clear(); //if user presses start, clear screen
JamesCummins 38:a85bc227b907 110 lcd.refresh(); //before advancing to start menu
JamesCummins 6:952ac12c7f00 111 advance = true;
JamesCummins 6:952ac12c7f00 112 }
JamesCummins 6:952ac12c7f00 113 else { advance = false; }
JamesCummins 6:952ac12c7f00 114 }
JamesCummins 0:7c96d84b673e 115 }
JamesCummins 7:6eb9cade57ab 116
JamesCummins 17:5104ecef5bd0 117 StartOption menu(){
JamesCummins 38:a85bc227b907 118 StartSelection fsm[3] = { //state machine to power start menu
JamesCummins 38:a85bc227b907 119 {0,{OPTIONS,BRICKBREAKER,CLASSIC}}, //next_state[0] always holds the option above the current one
JamesCummins 38:a85bc227b907 120 {2,{CLASSIC,OPTIONS,BRICKBREAKER}}, //next_state[1] always holds the option below the current one
JamesCummins 38:a85bc227b907 121 {4,{BRICKBREAKER,CLASSIC,OPTIONS}} //next_state[2] always holds the current option
JamesCummins 7:6eb9cade57ab 122 };
JamesCummins 14:108052b6222b 123 StartOption state = CLASSIC; //start with the arrow on the top option
JamesCummins 7:6eb9cade57ab 124 int next = 2; //next_state = 2 so that by default it doesn't change arrow position
JamesCummins 38:a85bc227b907 125 while(!(gamepad.check_event(gamepad.A_PRESSED))){ //select choice with A
JamesCummins 7:6eb9cade57ab 126 state = fsm[state].next_state[next];
JamesCummins 7:6eb9cade57ab 127 lcd.clear();
JamesCummins 38:a85bc227b907 128 if(gamepad.get_direction() == N){ next = 0;} //move arrow up
JamesCummins 38:a85bc227b907 129 else if(gamepad.get_direction() == S){ next = 1;} //move arrow down
JamesCummins 38:a85bc227b907 130 else {next = 2;} //keep arrow in same position
JamesCummins 38:a85bc227b907 131 print_start_menu(fsm[state].output); //print on LCD display
JamesCummins 7:6eb9cade57ab 132 lcd.refresh();
JamesCummins 38:a85bc227b907 133 wait(0.25); //longer wait than 1/fps to reduce the impact of button bounce
JamesCummins 7:6eb9cade57ab 134 }
JamesCummins 7:6eb9cade57ab 135 lcd.clear();
JamesCummins 38:a85bc227b907 136 lcd.refresh(); //clear display before moving on to a game mode
JamesCummins 38:a85bc227b907 137 return state; //tell main which game mode to run
JamesCummins 15:1564bd6b713d 138 }
JamesCummins 15:1564bd6b713d 139
JamesCummins 15:1564bd6b713d 140 void print_start_menu(int output){
JamesCummins 15:1564bd6b713d 141 lcd.printString(">", 0, output);
JamesCummins 15:1564bd6b713d 142 lcd.printString("Classic", 36, 0);
JamesCummins 15:1564bd6b713d 143 lcd.printString("BrickBreak", 18, 2);
JamesCummins 15:1564bd6b713d 144 lcd.printString("Options", 36, 4);
JamesCummins 22:4e305ff8a050 145 lcd.printString("(A = Select)", 12, 5);
JamesCummins 25:b52aa23df120 146 }
JamesCummins 25:b52aa23df120 147
JamesCummins 29:42651f87522b 148 //////////////////Game Mode Functions////////////////////////////////
JamesCummins 29:42651f87522b 149
JamesCummins 29:42651f87522b 150 void classic_mode(){
JamesCummins 29:42651f87522b 151 classic.init(ball, map);
JamesCummins 38:a85bc227b907 152 pause.classic_help(gamepad, lcd); //display how to play instructions before start of game
JamesCummins 38:a85bc227b907 153 bool collision = false; //used to determine whether to keep iterating or not
JamesCummins 31:c95f1b1d6423 154 while(!(collision)){
JamesCummins 38:a85bc227b907 155 classic.classic_update(ball, accelerometer, map); //methods to update the game
JamesCummins 38:a85bc227b907 156 lcd.clear(); //and render it as the user plays
JamesCummins 29:42651f87522b 157 classic.classic_draw(lcd, map, ball);
JamesCummins 29:42651f87522b 158 lcd.refresh();
JamesCummins 29:42651f87522b 159 wait(1/fps);
JamesCummins 38:a85bc227b907 160 if(gamepad.check_event(gamepad.BACK_PRESSED)){ //check for use of the pause menu
JamesCummins 38:a85bc227b907 161 PauseOption choice = pause.pause_menu(gamepad, lcd, fps); //retrieve user's input
JamesCummins 38:a85bc227b907 162 if(choice == RESUME){} //the different options must be processed
JamesCummins 38:a85bc227b907 163 if(choice == RESTART){ classic.init(ball, map); } //in main.cpp as they have different
JamesCummins 38:a85bc227b907 164 if(choice == QUIT){ break; } //return types so can't be passed into main
JamesCummins 38:a85bc227b907 165 if(choice == HELP){ pause.classic_help(gamepad, lcd); } //by one public method in pause.h
JamesCummins 29:42651f87522b 166 }
JamesCummins 33:c2dbad3dd805 167 if(classic.finished()){ //check if the game has been completed
JamesCummins 38:a85bc227b907 168 classic.mode_complete(lcd, gamepad, fps); //display time taken and break from game mode
JamesCummins 33:c2dbad3dd805 169 break;
JamesCummins 33:c2dbad3dd805 170 }
JamesCummins 33:c2dbad3dd805 171 if(map.check_wall_collision(gamepad, ball)){ //end the game if collision with wall
JamesCummins 33:c2dbad3dd805 172 collision = classic.mode_failed(lcd, gamepad, ball, map); //gives the option to restart the game (and stay in while loop) or quit
JamesCummins 33:c2dbad3dd805 173 if(!(collision)){ classic.init(ball, map); }
JamesCummins 33:c2dbad3dd805 174 }
JamesCummins 29:42651f87522b 175 }
JamesCummins 29:42651f87522b 176 }
JamesCummins 29:42651f87522b 177
JamesCummins 25:b52aa23df120 178 void brickbreaker_mode(){
JamesCummins 38:a85bc227b907 179 pause.brickbreaker_help(gamepad, lcd); //display instructions before start of game
JamesCummins 25:b52aa23df120 180 for(int i = 0; i < 45*fps; i++){
JamesCummins 25:b52aa23df120 181 if(i == 1){ brick.set_score(0); } //reset score when game restarts
JamesCummins 38:a85bc227b907 182 ball.read_input(accelerometer); //methods to continue updating and rendering the game
JamesCummins 25:b52aa23df120 183 ball.update();
JamesCummins 25:b52aa23df120 184 /*Vector2D position = _ball.get_position();
JamesCummins 25:b52aa23df120 185 printf("ball_x = %f | ball_y = %f\n", position.x, position.y); //note: running with tests causes the game to run slow and take ~2min30s*/
JamesCummins 25:b52aa23df120 186 brick.check_square_collision(randnoise, ball);
JamesCummins 25:b52aa23df120 187 lcd.clear();
JamesCummins 25:b52aa23df120 188 brick.brickbreaker_draw(lcd, ball);
JamesCummins 25:b52aa23df120 189 lcd.refresh();
JamesCummins 25:b52aa23df120 190 wait_ms(1000/fps);
JamesCummins 38:a85bc227b907 191 if(gamepad.check_event(gamepad.BACK_PRESSED)){ //check for use of the pause menu
JamesCummins 38:a85bc227b907 192 PauseOption choice = pause.pause_menu(gamepad, lcd, fps); //Get the user's selection
JamesCummins 38:a85bc227b907 193 i = pause.brickbreaker_action(choice, gamepad, lcd, i, fps); //returns which frame to jump to
JamesCummins 25:b52aa23df120 194 }
JamesCummins 38:a85bc227b907 195 brick.time_warning(gamepad, i, fps); //Use LEDs to display how much time is left
JamesCummins 25:b52aa23df120 196 }
JamesCummins 38:a85bc227b907 197 brick.end(gamepad, lcd); //display the 'time up' screen with the user score
JamesCummins 38:a85bc227b907 198 brick.write_high_scores(); //update high scores accordingly
JamesCummins 25:b52aa23df120 199 }
JamesCummins 25:b52aa23df120 200
JamesCummins 25:b52aa23df120 201 void options_menu(){
JamesCummins 38:a85bc227b907 202 Option choice = BRIGHTNESS; //variable to store the selected option initialised to the top item in list
JamesCummins 25:b52aa23df120 203 while(!(gamepad.check_event(gamepad.A_PRESSED))){
JamesCummins 38:a85bc227b907 204 lcd.clear(); //keep rendering and updating the position of the
JamesCummins 38:a85bc227b907 205 opt.display_options(lcd); //menu arrows until a choice is made
JamesCummins 25:b52aa23df120 206 choice = opt.option_selection(gamepad, lcd);
JamesCummins 25:b52aa23df120 207 lcd.refresh();
JamesCummins 25:b52aa23df120 208 wait(0.2);
JamesCummins 25:b52aa23df120 209 }
JamesCummins 38:a85bc227b907 210 if(choice == BRIGHTNESS){ opt.change_brightness(gamepad, lcd); } //each menu option called by its
JamesCummins 38:a85bc227b907 211 if(choice == BALL_SPEED){ opt.change_ball_speed(gamepad, lcd, ball); } //respective enum and a method in
JamesCummins 38:a85bc227b907 212 if(choice == HIGH_SCORES){ opt.view_high_scores(gamepad, lcd); } //options engine processes the option
JamesCummins 25:b52aa23df120 213 }
JamesCummins 29:42651f87522b 214
JamesCummins 29:42651f87522b 215