ECE2035 class project

Dependencies:   4DGL-uLCD-SE SDFileSystem mbed wave_player

Fork of missile_command by ECE 2035 TA

main.cpp

Committer:
slin77
Date:
2014-11-17
Revision:
5:3f356592ee9c
Parent:
4:0dc720aa3c71

File content as of revision 5:3f356592ee9c:

/* Gatech ECE2035 2014 FALL missile command
 * Copyright (c) 2014 Gatech ECE2035
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */
/** @file main.cpp */
// Include header files for platform
#include "mbed.h"
#include "uLCD_4DGL.h"
#include "wave_player.h"
#include "SDFileSystem.h"
#include "segment_display.h"

// Include header files for missile command project
#include "globals.h"
#include "city_landscape_public.h"
#include "missile_public.h"
#include "player.h"
#include <stdio.h>
#include <stdlib.h>

// Platform initialization
DigitalIn left_pb(p23); DigitalIn right_pb(p21); DigitalIn fire_pb(p22);
DigitalIn fouth_pb(p24);
uLCD_4DGL uLCD(p28,p27,p29);
AnalogOut DACout(p18);
wave_player waver(&DACout);
SDFileSystem sd(p5, p6, p7, p8, "sd"); // mosi, miso, sck, cs

// Example of the decleration of your implementation
void playSound(char * wav);
void check_interception();
int within_range(MISSILE m, ANTIMISSILE a);
int check_destruction_range(MISSILE m,CITY c);
void check_city_destruction();
void display_victory();
void display_failure();
void advance_level();


PLAYER current_player;
CITY city_record[];
MISSILE missile_record[];
ANTIMISSILE am[];
EXPLOSION ex[];

int number_of_cities = 4;

/** Main() is where you start your implementation
    @brief The hints of implementation are in the comments. <br>
    @brief You are expected to implement your code in main.cpp and player.cpp. But you could modify any code if you want to make the game work better.
*/


int main()
{   
 
    setup_sequence();
    seg_driver_initialize(); 
    city_landscape_init(number_of_cities); 
    // Initialize the buttons        
    left_pb.mode(PullUp);  // The variable left_pb will be zero when the pushbutton for moving the player left is pressed    
    right_pb.mode(PullUp); // The variable rightt_pb will be zero when the pushbutton for moving the player right is pressed        
    fire_pb.mode(PullUp); 
    fouth_pb.mode(PullUp); //the variable fouth_pb will be zero when the pushbutton for firing a missile is pressed
    player_init();//initalize the player
    antimissile_init();
    explosion_init();
    //display the game menu
    int k;
    while (1) {
        char str1[] = "Easy";
        char str2[] = "Medium";
        char str3[] = "hard";
        if (right_pb == 0) {
            k++;
        } 
        k = k % 3;
        if(k == 1) {
            uLCD.text_string(str1, 3, 3, FONT_7X8, GREEN);    
        } else {
            uLCD.text_string(str1,3, 3,  FONT_7X8, WHITE);    
        }
        
        if(k == 2) {
            uLCD.text_string(str2, 3, 4, FONT_7X8, GREEN);    
        } else {
            uLCD.text_string(str2, 3, 4,  FONT_7X8, WHITE);    
        } 
        
        if(k == 0) {
            uLCD.text_string(str3, 3, 5, FONT_7X8, GREEN);    
        } else {
            uLCD.text_string(str3, 3, 5,  FONT_7X8, WHITE);    
        } 
        
        if (fire_pb == 0) {
            if (k == 0) {
                current_player.current_level = 3; 
            } else {
                current_player.current_level = k;
            }
            set_missile_speed(5 - current_player.current_level);
            set_missile_interval(10 - current_player.current_level);
            uLCD.text_string(str1, 3, 3, FONT_7X8, BACKGROUND_COLOR);  
            uLCD.text_string(str2, 3, 4, FONT_7X8, BACKGROUND_COLOR);
            uLCD.text_string(str3, 3, 5, FONT_7X8, BACKGROUND_COLOR);
            char go[] = "READY!";
            uLCD.text_string(go, 6, 6, FONT_7X8, GREEN);
            playSound("/sd/wavfiles/BUZZER.wav");
            uLCD.text_string(go, 6, 6, FONT_7X8, BACKGROUND_COLOR);
            break;
        }
        
        
    }
    
    /// 2.Begin the game loop
    while(1){
        current_player.timer++;
        char str[] = {'s', 'c', 'o', 'r', 'e', ':', '0' + current_player.score};
        char life_str[] = {'l','i','f', 'e',':', '0' + current_player.life};
        char level_str[] = {'l', 'e', 'v', 'e', 'l' ,':','0' + current_player.current_level};
        uLCD.text_string(str, 11, 0, FONT_7X8, WHITE);
        uLCD.text_string(life_str, 0, 1, FONT_7X8, WHITE);
        uLCD.text_string(level_str, 0, 0, FONT_7X8, GREEN);
        
        seg_driver(current_player.am_remain);
        /// 3.Example of drawing the player
        player_draw(); // draws a player at the center of the screen
        draw_antimissiles();
        /// 4.Example of calling the missile API.
        missile_generator(); /// It updates all incoming missiles on the screen
        update_explosion();
        draw_explosion();
        if (current_player.timer % 150 == 0 && current_player.life < 6) {
            current_player.life++;
        }
        /// 5.Implement the code to get user input and update the player
            /// -[Hint] You could see city_landscape.cpp to get some ideas about how to implement your player. <br>
        if(left_pb == 0){
            /// -[Hint] Implement the code to move player left <br>
            player_move_left();
        }
        if(right_pb == 0){
            /// -[Hint] Implement the code to move player right <br>
            player_move_right();
        }
        if(fire_pb == 0){
            /// -[Hint] Implement the code to fire player-missile <br>
            shoot();
            // [Demo of play sound file]
            //playSound("/sd/wavfiles/BUZZER.wav");
        }
        if(fouth_pb == 0 && current_player.protector_num > 0) {
            current_player.protector.is_active = 1;
            current_player.protector.timer = 0;
            current_player.protector_num--;
        }
        if(left_pb == 0 && right_pb == 0 && fouth_pb != 0 && fire_pb != 0) {
            big_shoot();
        }
        update_protector();
        update_antimissile_positions();
        check_interception();
        check_city_destruction();
        /// 6.Implement the code to draw a user missile
            /// -[Hint] You could see missile.cpp or missile_generator() for your reference <br>
        if (current_player.score > 9 || (!left_pb && !right_pb && !fire_pb && !fouth_pb)) {
            advance_level(); 
            //display_victory();   
        } else if(!is_any_left()) {
            current_player.life--;
            city_landscape_init(number_of_cities);
            
        } else if(current_player.current_level >= 4) {
            display_victory();
            break;    
        } 
        
        if (current_player.life == 0) {
            display_failure();
            break;   
        }
            
        /// 7.Implement the code to detect the collision between missiles and cities
            /// -[Hint] You could use city_get_info() and  missile_get_info() <br>
            /// -[Hint] You could use missile_set_exploded() to notify the missile module that the missile was exploded. <br>
            /// -[Hint] You need to check which city was hit by the missile, and call city_destroy() to destroy it. <br>
            /// -[Hint] You might also check whether the missile hit the land <br>
        
        /// 8.Implement the code to detect a collision between player-missiles and incoming missiles
            /// -[Hint] You could use missile_get_info() to get the position of incoming missile <br>
            /// -[Hint] You could use missile_set_exploded() to notify the missile module that the missile was exploded. <br>
            /// -[Hint] You might also check whether the missile hit the player <br>
        
        /// 9.Implement the code to check the end of game
            /// -[Hint] For example, if there is no more city, it should be gameover. <br>
        
    }
}

// Example of implementation of your functions
void playSound(char * wav)
{
    // open wav file
    FILE *wave_file;
    wave_file=fopen(wav,"r");

    // play wav file
    waver.play(wave_file);

    // close wav file
    fclose(wave_file);
}

void advance_level() {
    current_player.timer = 0;
    current_player.current_level++;
    set_missile_speed(5 - current_player.current_level);
    set_missile_interval(10 - current_player.current_level);
    city_landscape_init(4);
    current_player.score = 0;
    current_player.protector_num = 3;
    char str[] = "Enter NEXT LEVEL";
    uLCD.text_string(str, 2, 6, FONT_7X8, WHITE);
    wait(1);
    uLCD.text_string(str, 2, 6, FONT_7X8, BACKGROUND_COLOR);
    int i;
    for (i = 0;i < MAX_NUM_MISSILE;i++) {
        missile_set_exploded(i);
    }
}
void check_interception() {
    int i,j,k;
    for (i = 0;i < MAX_NUM_MISSILE; i++) {
        for (j = 0; j < current_player.max_am; j++) {
            if (missile_record[i].status == MISSILE_ACTIVE && am[j].status == ACTIVE
             && within_range(missile_record[i], am[j])) {
                for (k = 0; k < current_player.max_am; k++) {
                    if (ex[k].exploded == NO) {
                        //find a unused explosion activate it
                        ex[k].x = am[j].x;
                        ex[k].y = am[j].y;
                        ex[k].exploded = YES;
                        ex[k].color = PLAYER_COLOR;
                        break;   
                    }    
                }
                //set both the missile and anti missile to DEACTIVE
                missile_record[i].status = MISSILE_EXPLODED;
                am[j].status = DEACTIVE;
                current_player.am_remain++;
                current_player.score++;        
            }    
        }   
    }

}

void check_city_destruction() {
    int i,j,k;
    for (i = 0; i < MAX_NUM_MISSILE; i++) {
        for(j = 0;j < number_of_cities;j++) {
            if (missile_record[i].status == MISSILE_ACTIVE && city_get_info(j).status == EXIST && check_destruction_range(missile_record[i], city_get_info(j))) {
                 for (k = 0; k < current_player.max_am; k++) {
                    if (ex[k].exploded == NO) {
                        //find a unused explosion activate it
                        ex[k].x = missile_record[i].x;
                        ex[k].y = missile_record[i].y;
                        ex[k].exploded = YES;
                        ex[k].color = LANDSCAPE_COLOR;
                        break;   
                    }    
                }
                missile_record[i].status = MISSILE_EXPLODED;
                city_destroy(j);
            }
        }
    }


}

void display_victory() {
    uLCD.cls();
    char str[] = "You Are Winnner";
    uLCD.text_string(str, 2, 9, FONT_7X8, WHITE);
    playSound("/sd/wavfiles/ding_dong.wav");
}

void display_failure() {
    uLCD.cls();
    char str[] = "Game Over";
    uLCD.text_string(str, 3, 9, FONT_7X8, WHITE);
    playSound("/sd/wavfiles/ding_dong.wav");
}




int check_destruction_range(MISSILE m,CITY c) {
    if(c.x  <= m.x
        && m.x <= c.x + c.width
        && c.y <= m.y
        && m.y <= c.y + c.height) {
        return 1;
    }
    return 0;    
}
      
int within_range(MISSILE m, ANTIMISSILE a) {
         if(m.x - 2 <=a.x 
            && a.x <= m.x  + 2
            && m.y - 2 <=a.y
            && a.y <= m.y + 2) {
                 return 1;
        }
        return 0;
}