ECE2035 class project

Dependencies:   4DGL-uLCD-SE SDFileSystem mbed wave_player

Fork of missile_command by ECE 2035 TA

Files at this revision

API Documentation at this revision

Comitter:
slin77
Date:
Mon Nov 17 13:15:34 2014 +0000
Parent:
1:3da29f1d84b4
Child:
3:fd1f794b7f5d
Commit message:
first commit

Changed in this revision

city_landscape/city_landscape.cpp Show annotated file Show diff for this revision Revisions of this file
city_landscape/city_landscape_private.h Show annotated file Show diff for this revision Revisions of this file
city_landscape/city_landscape_public.h Show annotated file Show diff for this revision Revisions of this file
globals.h Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
missile/missile.cpp Show annotated file Show diff for this revision Revisions of this file
missile/missile_public.h Show annotated file Show diff for this revision Revisions of this file
player.cpp Show annotated file Show diff for this revision Revisions of this file
player.h Show annotated file Show diff for this revision Revisions of this file
--- a/city_landscape/city_landscape.cpp	Wed Oct 29 02:58:53 2014 +0000
+++ b/city_landscape/city_landscape.cpp	Mon Nov 17 13:15:34 2014 +0000
@@ -21,9 +21,11 @@
  */
 
 #include "city_landscape_private.h"
+#include "globals.h"
+//
+//CITY city_record[];
+int building_height[NUM_BUILDING];
 
-CITY city_record[MAX_NUM_CITY];
-int building_height[NUM_BUILDING];
 
 // See the comments in city_landscape_public.h
 void city_landscape_init(int num_city) {
@@ -112,6 +114,17 @@
     }
 }
 
+int is_any_left() {
+    int i, left = 0;
+    for (i = 0; i < MAX_NUM_CITY; i++) {
+        if (city_record[i].status == EXIST) {
+            left = 1;
+            break;
+        }
+    }
+    return left;    
+}
+
 void draw_landscape(void){
     uLCD.filled_rectangle(0, SIZE_Y-1, SIZE_X-1, REVERSE_Y(LANDSCAPE_HEIGHT), LANDSCAPE_COLOR);
 }
\ No newline at end of file
--- a/city_landscape/city_landscape_private.h	Wed Oct 29 02:58:53 2014 +0000
+++ b/city_landscape/city_landscape_private.h	Mon Nov 17 13:15:34 2014 +0000
@@ -51,7 +51,7 @@
 #define BUILDING_WIDTH 2 // pixel on the screen
 #define NUM_BUILDING (CITY_WIDTH/BUILDING_WIDTH)
 #define BUILDING_COLOR 0x00FF00
-#define LANDSCAPE_COLOR 0xCCAA00
+//#define LANDSCAPE_COLOR 0xCCAA00
 
 
 
--- a/city_landscape/city_landscape_public.h	Wed Oct 29 02:58:53 2014 +0000
+++ b/city_landscape/city_landscape_public.h	Mon Nov 17 13:15:34 2014 +0000
@@ -22,6 +22,7 @@
 /** @file city_landscape_public.h */
 #ifndef CITY_LANDSCAPE_PUBLIC_H
 #define CITY_LANDSCAPE_PUBLIC_H
+#define LANDSCAPE_COLOR 0xCCAA00
 
 /// The enum define the status of a city
 typedef enum {
@@ -67,5 +68,7 @@
 */
 void draw_landscape(void);
 
+int is_any_left();
+
 
 #endif //CITY_LANDSCAPE_H
\ No newline at end of file
--- a/globals.h	Wed Oct 29 02:58:53 2014 +0000
+++ b/globals.h	Mon Nov 17 13:15:34 2014 +0000
@@ -21,9 +21,16 @@
  */
 #ifndef GLOBAL_H
 #define GLOBAL_H
-
+#include "missile_public.h"
+#include "player.h"
+#include "city_landscape_public.h"
 // === [global object] ===
 extern uLCD_4DGL uLCD;
+extern PLAYER current_player;
+extern ANTIMISSILE am[5];
+extern EXPLOSION ex[5];
+extern MISSILE missile_record[MAX_NUM_MISSILE];
+extern CITY city_record[MAX_NUM_CITY];
 
 
 // === [global settings] ===
--- a/main.cpp	Wed Oct 29 02:58:53 2014 +0000
+++ b/main.cpp	Mon Nov 17 13:15:34 2014 +0000
@@ -32,9 +32,12 @@
 #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);
@@ -42,64 +45,156 @@
 
 // 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()
 {   
-    // [Demo of 7-segment display]
-    // 1.Initialize the segment display
+ 
     setup_sequence();
-    seg_driver_initialize();
-    // 2.show numbers
-    int i;
-    for(i=0;i<10;i++){
-        seg_driver(i);
-        wait(0.2);
-    }
-    
-    // [Demo of play sound file]
-    playSound("/sd/wavfiles/BUZZER.wav");
-    
-    /// [Example of missile command implementation]
-        /// Here is a rough flow to implement the missile command: <br><br>
-    
-    /// 1.Initialize and draw the city landscape
-    city_landscape_init(4); 
+    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);  //the variable fire_pb will be zero when the pushbutton for firing a missile 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);
+            wait(1.5);
+            uLCD.text_string(go, 6, 6, FONT_7X8, BACKGROUND_COLOR);
+            break;
+        }
+        
+        
+    }
+    
     
     /// 2.Begin the game loop
     while(1){
         
+        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(60,100); // draws a player at the center of the screen
-        
+        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();
         
         /// 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");
+            //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--;
+        }
+        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)) {
+            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>
@@ -130,3 +225,106 @@
     // close wav file
     fclose(wave_file);
 }
+
+void advance_level() {
+    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);
+}
+
+void display_failure() {
+    uLCD.cls();
+    char str[] = "Game Over";
+    uLCD.text_string(str, 3, 9, FONT_7X8, WHITE); 
+}
+
+
+
+
+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;
+}       
+
--- a/missile/missile.cpp	Wed Oct 29 02:58:53 2014 +0000
+++ b/missile/missile.cpp	Mon Nov 17 13:15:34 2014 +0000
@@ -22,7 +22,7 @@
 
 #include "missile_private.h"
 
-MISSILE missile_record[MAX_NUM_MISSILE];
+
 int missile_tick=0;
 int missile_interval = 10;
 int missile_speed = 4;
@@ -121,6 +121,13 @@
             missile_record[i].status = MISSILE_DEACTIVE;
             //resets the missile's internal tick
             missile_record[i].tick = 0;
+        } 
+        
+        if (missile_record[i].y > 128) {
+            //when the missile hit the ground
+             missile_draw(missile_record[i], BACKGROUND_COLOR);
+             missile_record[i].tick = 0;
+             missile_record[i].status = MISSILE_DEACTIVE;
         }
         
     }
--- a/missile/missile_public.h	Wed Oct 29 02:58:53 2014 +0000
+++ b/missile/missile_public.h	Mon Nov 17 13:15:34 2014 +0000
@@ -40,8 +40,11 @@
     MISSILE_STATUS status;   ///< The missile status, see MISSILE_STATUS
 } MISSILE;
 
+
 #define MAX_NUM_MISSILE  5
 
+//MISSILE missile_record[MAX_NUM_MISSILE];
+
 /** This function draw the missiles onto the screen
     Call missile_generator() repeatedly in your game-loop. ex: main()
 */
--- a/player.cpp	Wed Oct 29 02:58:53 2014 +0000
+++ b/player.cpp	Mon Nov 17 13:15:34 2014 +0000
@@ -27,10 +27,187 @@
 #include "player.h"
 
 // Example of drawing the player
-void player_draw(int x, int y) {
-    uLCD.filled_rectangle(x, y, x+PLAYER_WIDTH, y+PLAYER_HEIGHT, PLAYER_COLOR); 
-    uLCD.filled_rectangle(x+PLAYER_DELTA, y-PLAYER_DELTA, x+PLAYER_WIDTH-PLAYER_DELTA, y+PLAYER_HEIGHT, PLAYER_COLOR);  
+
+void player_init() {
+    current_player.x = 60;
+    current_player.y = 100;
+    current_player.am_remain = 5;
+    current_player.max_am = 5;
+    current_player.status = PLAYER_ACTIVE;
+    current_player.score = 0;
+    current_player.current_level = 0;
+    current_player.life = 5;//inital 5 hp  
+    current_player.protector_num = 3;  
+}
+
+void update_protector() {
+    if (current_player.protector.is_active) {
+        current_player.protector.timer++;
+        uLCD.line(0, 80, 128, 80, WHITE);
+        int i,k;
+        for (i = 0; i < MAX_NUM_MISSILE; i++) {
+            if (missile_record[i].status == MISSILE_ACTIVE && missile_record[i].y < 80) {
+                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 = WHITE;
+                        break;   
+                    }    
+                }
+                missile_record[i].status = MISSILE_EXPLODED;
+            }
+        }
+        if (current_player.protector.timer == 10) {
+            current_player.protector.is_active = 0;
+            uLCD.line(0, 80, 128, 80, BACKGROUND_COLOR);
+        }
+    }    
+}
+
+void explosion_init() {
+       int i;
+        for (i = 0; i < current_player.max_am;i++) {
+            ex[i].x = 0;
+            ex[i].y  = 0;
+            ex[i].tick = 0;
+            ex[i].radius = 3;
+            ex[i].exploded = NO;
+            ex[i].color = PLAYER_COLOR;   
+    }     
+}
+
+void update_explosion() {
+    int i;
+    for (i = 0;i < current_player.max_am;i++) {
+        if (ex[i].exploded == YES) {
+            ex[i].tick++;
+            uLCD.circle(ex[i].x, ex[i].y, ex[i].radius - 2, BACKGROUND_COLOR);
+            uLCD.circle(ex[i].x, ex[i].y, ex[i].radius, BACKGROUND_COLOR);
+            draw_landscape();
+            if (ex[i].tick <= 5) {
+                ex[i].radius = ex[i].radius + 2;
+            } else {
+                ex[i].tick = 0;
+                ex[i].radius = 0;
+                ex[i].exploded = NO;
+            }
+        }
+    }
+}
+
+void draw_explosion() {
+    int i;
+    for (i = 0;i < current_player.max_am;i++) {
+        if (ex[i].exploded == YES) {
+            uLCD.circle(ex[i].x, ex[i].y, ex[i].radius - 2, ex[i].color);
+            uLCD.circle(ex[i].x, ex[i].y, ex[i].radius, ex[i].color);    
+        }    
+    } 
+}
+
+void antimissile_init() {
+    int i;
+    for (i = 0; i < current_player.max_am;i++) {
+        am[i].x = current_player.x;
+        am[i].y = current_player.y;
+        am[i].speed = 5;
+        am[i].tick = 0;
+        am[i].status = DEACTIVE;
+    }    
 }
+//(x,y) is the top left corner 
+void player_draw() {
+   int x = current_player.x;
+   int y = current_player.y;
+   uLCD.filled_rectangle(x - 5, y, x- 5 + PLAYER_WIDTH, y+PLAYER_HEIGHT, PLAYER_COLOR);
+   uLCD.line(x - 5, y - 3, x  - 5, y + PLAYER_HEIGHT + 3, PLAYER_COLOR);
+   uLCD.line(x- 5 + PLAYER_WIDTH, y - 3, x- 5 + PLAYER_WIDTH, y + PLAYER_HEIGHT + 3, PLAYER_COLOR);
+   uLCD.line(x, y - 3, x, y + PLAYER_HEIGHT + 3, PLAYER_COLOR); 
+    //uLCD.filled_rectangle(x+PLAYER_DELTA, y-PLAYER_DELTA, x+PLAYER_WIDTH-PLAYER_DELTA, y+PLAYER_HEIGHT, PLAYER_COLOR);  
+}
+
+void player_move_left() {
+     int x = current_player.x;
+     int y = current_player.y;
+    uLCD.filled_rectangle(x - 5, y, x- 5 + PLAYER_WIDTH, y+PLAYER_HEIGHT, BACKGROUND_COLOR);
+    uLCD.line(x - 5, y - 3, x  - 5, y + PLAYER_HEIGHT + 3, BACKGROUND_COLOR);
+    uLCD.line(x- 5 + PLAYER_WIDTH, y - 3, x- 5 + PLAYER_WIDTH, y + PLAYER_HEIGHT + 3, BACKGROUND_COLOR);
+    uLCD.line(x, y - 3, x, y + PLAYER_HEIGHT + 3, BACKGROUND_COLOR); 
+    if (current_player.x - PLAYER_DELTA > 0) {
+        current_player.x = current_player.x - PLAYER_DELTA;    
+    }    
+}
+
+void player_move_right() {
+    int x = current_player.x;
+    int y = current_player.y;
+    uLCD.filled_rectangle(x - 5, y, x- 5 + PLAYER_WIDTH, y+PLAYER_HEIGHT, BACKGROUND_COLOR);
+    uLCD.line(x - 5, y - 3, x  - 5, y + PLAYER_HEIGHT + 3, BACKGROUND_COLOR);
+    uLCD.line(x- 5 + PLAYER_WIDTH, y - 3, x- 5 + PLAYER_WIDTH, y + PLAYER_HEIGHT + 3, BACKGROUND_COLOR);
+    uLCD.line(x, y - 3, x, y + PLAYER_HEIGHT + 3, BACKGROUND_COLOR); 
+    if(current_player.x + PLAYER_DELTA < 126) {
+        current_player.x = current_player.x + PLAYER_DELTA;
+    }
+}
+
+PLAYER get_player_info() {
+    return current_player;
+}
+
+//find a available antimissile and set it active 
+void shoot() {
+    int i;
+    if (current_player.am_remain > 0) {
+            for(i = 0; i < current_player.max_am; i++) {
+                if (am[i].status == DEACTIVE) {
+                     am[i].status = ACTIVE;
+                     am[i].x = current_player.x;
+                     am[i].y = current_player.y;
+                     am[i].speed = 5; // need to be improved
+                     am[i].tick = 0;
+                     current_player.am_remain--;
+                     break;
+                 }
+            }
+    }    
+}
+//update all active missiles position 
+void update_antimissile_positions() {
+        int i, rate;
+        for(i = 0; i < current_player.max_am;i++) {
+            if(am[i].status == ACTIVE) {
+                   am[i].tick++;
+                   rate = 5 / am[i].speed;
+                   if (am[i].y - 2 <= 0) {
+                        //when the missile flies out of the screen
+                        am[i].status = DEACTIVE;
+                        uLCD.line(am[i].x, am[i].y, am[i].x, am[i].y - 2, BACKGROUND_COLOR);
+                        am[i].y = current_player.y;
+                        am[i].x = current_player.x;
+                        current_player.am_remain++;
+                           
+                    } else if (am[i].tick % rate == 0) {
+                        uLCD.line(am[i].x, am[i].y, am[i].x, am[i].y - 2, BACKGROUND_COLOR);
+                        am[i].y = am[i].y - 2;
+                    }
+                    
+            }
+        }
+}
+//find all active antimissiles and draw their current position
+void draw_antimissiles() {
+    int i;
+    for(i = 0; i < current_player.max_am;i++) {
+        if (am[i].status == ACTIVE ) {
+            uLCD.line(am[i].x, am[i].y, am[i].x, am[i].y - 2, PLAYER_COLOR);
+        }
+    }
+}
+
+
 
 // ... You need to implement your own functions for player ...
 
--- a/player.h	Wed Oct 29 02:58:53 2014 +0000
+++ b/player.h	Mon Nov 17 13:15:34 2014 +0000
@@ -31,11 +31,85 @@
 #define PLAYER_COLOR   0x0000FF
 
 
-/** Get the information of city
+typedef enum {
+    PLAYER_ACTIVE = 1,
+    PLAYER_DIED = 0
+} PLAYER_STATUS;
+
+
+typedef struct {
+    int timer;
+    int is_active;
+} PROTECTOR;
+
+typedef struct {
+    int x;// the current x of the player, bottom left
+    int y;//current y position of the player, bottom left point
+    int max_am;
+    int am_remain;//how many missile for the player remain
+    int life;//his hp remain
+    int current_level;
+    PLAYER_STATUS status;//if he is dead
+    int score;//# of interceptions 
+    int protector_num;// number of protector left
+    PROTECTOR protector;  
+} PLAYER;
+/** et the information of city
     @brief x and y are the top left corner of the player drawing
     @param x x-coordinate
     @param y y-coordinate
 */
-void player_draw(int x, int y);
+
+
+
+typedef enum {
+    DEACTIVE = 0,
+    ACTIVE = 1,
+    //MISSLE_EXPLODE = 2
+} ANTIMISSLE_STATUS;
+
+typedef struct {
+    int x;
+    int y;
+    int speed;
+    int tick; //anti missile's internal clock
+    ANTIMISSLE_STATUS status;
+}  ANTIMISSILE;
+
+typedef enum{
+    YES = 1,
+    NO = 0    
+} EXPLOSION_STATUS;
 
+typedef struct{
+    int x;
+    int y;
+    int tick;
+    int radius;
+    EXPLOSION_STATUS exploded;
+    int color;
+} EXPLOSION;
+    
+
+//initialize the player for the game
+void player_init();
+void player_draw();
+void player_move_left();
+void player_move_right();
+void antimissile_init();
+void shoot();
+void update_antimissile_positions();
+void draw_antimissiles();
+void explosion_init();
+void update_explosion();
+void draw_explosion();
+void update_protector();// update protector status and draw it on the screen
+
+//extern PLAYER current_player;
+//extern ANTIMISSILE am[5];
+//extern EXPLOSION ex[5];
+/**
+get the currrent player info
+*/
+PLAYER get_player_info();
 #endif //PLAYER_H
\ No newline at end of file