Ben Evans / Mbed 2 deprecated Defender_Game

Dependencies:   mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers GameEngine.cpp Source File

GameEngine.cpp

00001 #include "GameEngine.h"
00002 
00003 /** Define accelerometer object */
00004 FXOS8700CQ accelerometer(I2C_SDA,I2C_SCL);
00005 
00006 /** Define SD card object */
00007 SDFileSystem sd(PTE3, PTE1, PTE2, PTE4, "sd");
00008     
00009 GameEngine::GameEngine() {
00010     //attach ticker to isr 
00011     ticker.attach(callback(this, &GameEngine::lcd_frame_time_isr), 0.04 );
00012 }
00013  
00014 GameEngine::~GameEngine() {
00015     
00016 }
00017 
00018 void GameEngine::init() {
00019     // Initialise objects
00020     pad.init();
00021     lcd.init();
00022     spaceship.init();
00023     map.init(pad);
00024     menu.init();
00025     accelerometer.init();
00026     saved.init();
00027     setting.init();
00028     h_score.init();
00029 
00030     // Set first screen to main menu
00031     current_menu_part_= menu.get_current_menu_part();
00032     
00033     // Launch screen
00034     lcd.printString("Evans Studios",3,2); 
00035     lcd.printString("Presents:",15,3);
00036     lcd.refresh();
00037     wait(3); 
00038     
00039     play_music();
00040     
00041     // Set seed value 
00042     srand(pad.read_adc()*64000);
00043     
00044     // Had to include save test here as getting the error sd couldn’t be created
00045     #ifdef SD_TEST
00046         saved.run_save_test(sd,lcd); 
00047         h_score.run_save_test(sd,lcd);      
00048     #endif 
00049 }
00050 
00051 void GameEngine::lcd_frame_time_isr() {
00052     // Set ISR flag
00053     lcd_frame_time_flag_ = 1; 
00054 } 
00055 
00056 // Menu Control-----------------------------------------------------------------
00057 
00058 void GameEngine::game_select_part() {
00059     switch (current_menu_part_) {
00060     case main_menu: run_menu(); break;
00061     case play: run_play(); break;
00062     case settings: run_settings(); break;
00063     case saved_games: run_saved_games(); break;
00064     case high_score: run_highscore(); break;
00065     }
00066 }
00067 
00068 void GameEngine::run_menu() {
00069     lcd.setContrast(pad.read_pot1());          
00070     lcd.clear();
00071     pad.reset_buttons();
00072             
00073     // Scrolls, draws and selects menu parts
00074     read_joystick_direction();
00075     menu.menu_scroll(d_);
00076     menu.draw_part(lcd);  
00077     menu.select_part(pad.A_pressed());
00078              
00079     current_menu_part_ = menu.get_current_menu_part();
00080     
00081     // Sets sound and music setting 
00082     sound_fx_ = setting.get_sound_method();
00083     music_fx_ = setting.get_music_method();
00084     if (music_fx_ == music_off){
00085         stop_music();
00086     }   
00087     music_flag_ = true;
00088     
00089     // printf("sound%d\n",sound_fx_ );
00090          
00091     // Initialise the game if play 
00092     if (current_menu_part_ == play) {
00093         play_init();
00094     }
00095     
00096     pad.reset_buttons();    
00097     lcd.refresh();      
00098 }
00099 
00100 void GameEngine::loading_screen(){
00101     lcd.clear();
00102     
00103     // Draws adding dots 3 times
00104     for (int x = 0; x <= 2; x++) {
00105         lcd.printString("Loading",15,3);
00106         lcd.refresh();
00107         
00108         // Adds loading dots 
00109         for (int i = 0; i <= 3; i++) { 
00110             wait(0.25);
00111             lcd.printString(".",57+(i*6),3);
00112             lcd.refresh();  
00113         }
00114         lcd.clear();
00115     }
00116 }
00117 
00118 
00119 
00120 // Menu Play -------------------------------------------------------------------
00121 
00122 void GameEngine::run_play() {
00123     loading_screen(); 
00124     
00125     // Stops melody playing
00126     stop_music();
00127     
00128     // Main gameplay loop to run playable part of game, pause and save screens
00129     while (1) {             
00130         // Timer interrupt to set frame rate of game
00131         if (lcd_frame_time_flag_) {
00132             // Resets ISR flag 
00133             lcd_frame_time_flag_ = 0; 
00134             
00135             // Selects the different parts of the game
00136             play_select();
00137             
00138             // Break out of run play loop when lives = 0 or exited flag set
00139             if (!spaceship_lives_||exit_flag_) {
00140                 // Only draw game over screen if run out of lives
00141                 if (!spaceship_lives_) {
00142                     draw_game_over_screen();
00143                 }
00144                 reset_map();
00145                 pad.leds_off();
00146                 break;   
00147             } 
00148         }
00149         
00150     // MCU put to sleep between each frame to save power 
00151     sleep();       
00152     } 
00153     play_music();
00154     wait(0.3);
00155 }
00156 
00157 void GameEngine::play_select(){
00158     // Pause button pressed
00159     if (pad.start_pressed() && paused_counter_ > 10 ) {
00160         paused_button_pressed_ =  !paused_button_pressed_; 
00161         paused_counter_ = 0 ;
00162         run_save_a_game_flag_ = false;
00163     }
00164     
00165     // Stopped double press of pause button
00166     paused_counter_++;
00167     
00168     // Draws pause screen if paused button pressed
00169     if (paused_button_pressed_) {
00170         run_paused_game();
00171                
00172     // Otherwise draw gameplay screen
00173     }else{
00174         gameplay_loop(); 
00175     }
00176     
00177        
00178 }
00179 
00180 void GameEngine::play_music() {
00181     if (music_fx_ == music_on) {
00182         pad.play_melody(88, star_wars, star_wars_note_time, 108, true);
00183     }
00184     
00185 }
00186 
00187 void GameEngine::stop_music() {
00188     pad.play_melody(1, melody_off, melody_off_note_time, 1, false);
00189 }
00190 
00191 void GameEngine::play_init() {
00192     // Define variables
00193     spawn_time_multipler_ = 1;
00194     alien_number_ = 5;
00195     spawn_alien_counter_ = 0;
00196     spaceship_lives_ = 3;
00197     reset_map_counter_ = 0;
00198     smart_bomb_counter_ = 4;
00199     create_people();
00200     points_ = 0;
00201     smart_bomb_timer_ =  0;
00202     bullet_timer_ = 0;
00203     lcd_frame_time_flag_ = 0;
00204     paused_counter_ = 25;
00205     
00206     // Flags for screen control
00207     exit_flag_ = false;
00208     run_save_a_game_flag_ = false;
00209     spaceship_destroyed_ = false;
00210     saved.set_error(false);
00211     paused_button_pressed_ = false;
00212 }
00213 
00214 void GameEngine::gameplay_loop() {
00215     // Clear screen and set contrast
00216     lcd.setContrast(pad.read_pot1());          
00217     lcd.clear();
00218     
00219     // Creates aliens and people
00220     spawn_aliens();
00221     spawn_people();
00222 
00223     // If spaceship is destroyed stop joystick input, don’t draw spaceship sprite
00224     spaceship_not_detroyed();
00225     
00226     // Draws objects
00227     map.draw_map(lcd, d_);
00228     draw_aliens();
00229     draw_bullets();
00230     draw_explosions();
00231     draw_people(); 
00232     hud.draw_HUD(lcd, spaceship_lives_, points_, smart_bomb_counter_);
00233     spaceship_lives_leds();
00234     
00235     reset_map_timer();
00236     
00237     // Refresh's screen
00238     lcd.refresh(); 
00239 }
00240 
00241 void GameEngine::spaceship_not_detroyed() {
00242     if (!spaceship_destroyed_) {
00243         
00244         // Changes the control method depending what’s selected in the setting
00245         if (setting.get_control_method() == joy ) {
00246         read_joystick_direction();
00247         }else {
00248         read_accelerometer_direction(accelerometer.get_roll_angle(),
00249         accelerometer.get_pitch_angle());
00250         }
00251         
00252         // Stops movement of spaceship and map after destroyed
00253         spaceship.movement(d_);
00254         spaceship.draw(lcd);
00255         create_weapons_bullets();
00256         create_weapons_smart_bomb();
00257     }
00258 }
00259 
00260 void GameEngine::draw_game_over_screen() {
00261     // Draws game over screen then back to menu
00262     lcd.clear();
00263     lcd.printString("Game Over",15,0);
00264     
00265     // Draws score/highscore part of screen
00266     char buffer[11]; 
00267     sprintf(buffer,"Score = %d",points_);
00268     lcd.printString(buffer,12,2);
00269     h_score.set_error(false);
00270     
00271     // Prints new high score if a high score and no error
00272     if (calculate_new_score()&& !h_score.get_error()) {
00273         lcd.printString("NEW HIGH SCORE",0,4); 
00274         
00275         if (music_fx_ == music_on) {
00276         pad.play_melody(61, take_on_me, take_on_me_note_time, 140, false);
00277         }
00278         
00279     }else if (music_fx_ == music_on) {
00280         pad.play_melody(23, god_farther, god_farther_note_time, 80, false);
00281     }
00282     
00283     lcd.refresh();
00284     wait(6);
00285     current_menu_part_ = main_menu;
00286 }
00287 
00288 void GameEngine::run_paused_game() {
00289     // Lunch save a game screen 
00290     if (pad.B_pressed()||run_save_a_game_flag_) {
00291         run_save_a_game_flag_ = true;
00292         run_save_a_game();
00293         
00294     // Draw pause screen
00295     }else{
00296         draw_pause_screen();
00297     }
00298     
00299     // Exit to main menu
00300     if (pad.A_pressed()||saved.get_error()) {
00301         current_menu_part_ = main_menu;
00302         play_music();
00303         exit_flag_ = true;
00304         saved.set_error(false);
00305         wait(0.037);
00306     }
00307 }
00308 
00309 void GameEngine::draw_pause_screen() {
00310     // Clear screen and set contrast
00311     lcd.setContrast(pad.read_pot1());          
00312     lcd.clear();
00313     
00314     // Draw strings
00315     lcd.printString("Paused!",24,0);
00316     lcd.printString("Exit(A)",24,3);
00317     lcd.printString("Save&Exit(B)",6,4);
00318     
00319     // Refresh's screen
00320     lcd.refresh(); 
00321 }
00322 
00323 void GameEngine::run_save_a_game() {
00324     // Draw and interact with save a game screen
00325     read_joystick_direction();
00326     saved.saved_games_scroll(d_);
00327     saved.save_game_screen(lcd);
00328     
00329     // Save game to save file that is displayed
00330     if (pad.A_pressed()) {  
00331         // Define struct data
00332         SavedGamesData data;
00333         
00334         // Set values in struct data and saves them selected file
00335         data.score = points_;
00336         data.lives = spaceship_lives_;
00337         data.smart_bombs = smart_bomb_counter_;
00338         data.alien_number = alien_number_;
00339         saved.add_saved_data(sd, data, lcd);
00340         
00341         // If error go back to pause screen
00342         if (saved.get_error()) {
00343             run_save_a_game_flag_ = false;
00344             saved.set_error(false);
00345         }else{
00346         // Exit to main menu
00347         current_menu_part_ = main_menu;
00348         exit_flag_ = true; 
00349         }
00350     } 
00351 }
00352 
00353 
00354 
00355 
00356 // Menu Setting ----------------------------------------------------------------
00357 
00358 void GameEngine::run_settings() {      
00359     lcd.clear();
00360     lcd.setContrast(pad.read_pot1());
00361             
00362     // Scrolls, draws and changes different parts
00363     read_joystick_direction();
00364     setting.settings_scroll(d_);
00365     setting.display_settings_screen(lcd, pad.read_pot1());  
00366     setting.change_setting(pad.A_pressed());
00367     
00368     // Stops music immediately changed
00369     music_fx_ = setting.get_music_method();
00370     if (music_fx_ == music_off){
00371         stop_music();
00372         music_flag_ = false;
00373     }   
00374     if (music_fx_ == music_on && !music_flag_ ){
00375         play_music();
00376         music_flag_ = true;
00377     }        
00378     // Go back to main menu if b
00379     if (pad.B_pressed()) { 
00380         current_menu_part_ = main_menu;
00381     }
00382             
00383     lcd.refresh();     
00384 }
00385 
00386 
00387 
00388 // Menu Saved Games ------------------------------------------------------------
00389 
00390 void GameEngine::run_saved_games() {
00391     // Draws and interact with save screen
00392     read_joystick_direction(); 
00393     saved.saved_games_scroll(d_);
00394     saved.display_saved_games(lcd);
00395     
00396     // Go back to main menu
00397     if (pad.B_pressed()) { 
00398         current_menu_part_ = main_menu;
00399     }
00400     
00401     // Press  A to load save, if no file press go back to main menu
00402     if (pad.A_pressed()) {
00403         wait(0.035);  
00404         saved_games_overide_init();
00405         if (saved.get_error()) {
00406             saved.set_error(false);
00407             current_menu_part_ = main_menu;
00408         }else{   
00409             current_menu_part_ = play; 
00410         }
00411     }   
00412 }
00413 
00414 void GameEngine::saved_games_overide_init() {
00415     play_init();
00416     
00417     // Creates data object add sett it values to data saved in the file
00418     SavedGamesData displayed_game;
00419     displayed_game = saved.read_saved_data(sd, lcd);
00420     
00421     // Set the variables to value in the displayed saved struct
00422     points_ = displayed_game.score;
00423     spaceship_lives_ = displayed_game.lives;
00424     smart_bomb_counter_= displayed_game.smart_bombs;
00425     alien_number_ = displayed_game.alien_number;
00426 }
00427 
00428 
00429 
00430 // Menu High score -------------------------------------------------------------
00431 
00432 void GameEngine::run_highscore() {
00433     lcd.clear();
00434     lcd.printString("High Scores",9,0);
00435     lcd.printString("Back(B)",21,5);
00436     
00437     // Sets error to false as may of become true from previous error
00438     h_score.set_error(false);
00439     
00440     // Draws score/highscore part of screen
00441     char buffer[11]; 
00442     sprintf(buffer,"Score = %d",h_score.read_high_score(sd));
00443     lcd.printString(buffer,9,3);
00444     
00445     // If error reading high score just say no high score or sd card
00446     if (h_score.get_error()) {
00447        h_score.no_high_scores(lcd);
00448        wait(3);
00449        current_menu_part_ = main_menu;  
00450     }
00451     
00452     // Go back to main menu when b pressed
00453     if (pad.B_pressed()) { 
00454         current_menu_part_ = main_menu;
00455     }
00456     
00457     lcd.refresh();
00458 }
00459 
00460 bool GameEngine::calculate_new_score() {
00461     bool new_high_score = false;
00462     
00463     // Gets old high score and return true if current score is greater
00464     int saved_high_score = h_score.read_high_score(sd);
00465     if (points_ > saved_high_score) {
00466         new_high_score = true; 
00467         h_score.save_new_high_score(sd, lcd, points_);
00468     }
00469     return new_high_score;
00470 }