Missile Command Game
Dependencies: mbed wave_player 4DGL-uLCD-SE MMA8452
main.cpp@1:5724f2947554, 2021-05-11 (annotated)
- Committer:
- lwills
- Date:
- Tue May 11 18:26:14 2021 +0000
- Revision:
- 1:5724f2947554
- Parent:
- 0:09aa1ecd6c39
- Child:
- 2:a09accf52491
Updated comments
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
lwills | 0:09aa1ecd6c39 | 1 | //================================================================= |
lwills | 0:09aa1ecd6c39 | 2 | // The main program file. |
lwills | 0:09aa1ecd6c39 | 3 | // |
lwills | 1:5724f2947554 | 4 | // Copyright 2021 Georgia Tech. All rights reserved. |
lwills | 0:09aa1ecd6c39 | 5 | // The materials provided by the instructor in this course are for |
lwills | 0:09aa1ecd6c39 | 6 | // the use of the students currently enrolled in the course. |
lwills | 0:09aa1ecd6c39 | 7 | // Copyrighted course materials may not be further disseminated. |
lwills | 0:09aa1ecd6c39 | 8 | // This file must not be made publicly available anywhere. |
lwills | 0:09aa1ecd6c39 | 9 | //================================================================== |
lwills | 0:09aa1ecd6c39 | 10 | |
lwills | 0:09aa1ecd6c39 | 11 | // External libs |
lwills | 0:09aa1ecd6c39 | 12 | #include <stdlib.h> |
lwills | 0:09aa1ecd6c39 | 13 | |
lwills | 0:09aa1ecd6c39 | 14 | // Project includes |
lwills | 0:09aa1ecd6c39 | 15 | #include "globals.h" |
lwills | 0:09aa1ecd6c39 | 16 | #include "hardware.h" |
lwills | 0:09aa1ecd6c39 | 17 | #include "city_landscape_public.h" |
lwills | 0:09aa1ecd6c39 | 18 | #include "missile_public.h" |
lwills | 0:09aa1ecd6c39 | 19 | #include "player_public.h" |
lwills | 0:09aa1ecd6c39 | 20 | |
lwills | 0:09aa1ecd6c39 | 21 | #define CITY_HIT_MARGIN 1 |
lwills | 0:09aa1ecd6c39 | 22 | #define CITY_UPPER_BOUND (SIZE_Y-(LANDSCAPE_HEIGHT+MAX_BUILDING_HEIGHT)) |
lwills | 0:09aa1ecd6c39 | 23 | |
lwills | 0:09aa1ecd6c39 | 24 | int num_city_g = 4; |
lwills | 0:09aa1ecd6c39 | 25 | // function prototypes |
lwills | 0:09aa1ecd6c39 | 26 | void set_random_seed(Timer); |
lwills | 0:09aa1ecd6c39 | 27 | int city_landscape_update(void); |
lwills | 0:09aa1ecd6c39 | 28 | int was_player_hit(void); |
lwills | 0:09aa1ecd6c39 | 29 | void missile_contact(void); |
lwills | 0:09aa1ecd6c39 | 30 | |
lwills | 0:09aa1ecd6c39 | 31 | int main() |
lwills | 0:09aa1ecd6c39 | 32 | { |
lwills | 0:09aa1ecd6c39 | 33 | GameInputs inputs; |
lwills | 0:09aa1ecd6c39 | 34 | // First things first: initialize hardware |
lwills | 0:09aa1ecd6c39 | 35 | ASSERT_P(hardware_init() == ERROR_NONE, "Hardware init failed!"); |
lwills | 0:09aa1ecd6c39 | 36 | pc.printf("Program Starting"); |
lwills | 0:09aa1ecd6c39 | 37 | |
lwills | 0:09aa1ecd6c39 | 38 | // Game state variables |
lwills | 0:09aa1ecd6c39 | 39 | int num_remain_city; // number of cities currently on the landscape |
lwills | 0:09aa1ecd6c39 | 40 | int player_alive; // 1 if alive, 0 if hit |
lwills | 0:09aa1ecd6c39 | 41 | |
lwills | 0:09aa1ecd6c39 | 42 | testDLL(); |
lwills | 0:09aa1ecd6c39 | 43 | // Timer to measure game update speed (secondarily used to generate random seed) |
lwills | 0:09aa1ecd6c39 | 44 | Timer t; |
lwills | 0:09aa1ecd6c39 | 45 | int dt; // delta time |
lwills | 0:09aa1ecd6c39 | 46 | set_random_seed(t); // Already implemented. |
lwills | 0:09aa1ecd6c39 | 47 | |
lwills | 0:09aa1ecd6c39 | 48 | //Initialization functions (already implemented) |
lwills | 0:09aa1ecd6c39 | 49 | city_landscape_init(num_city_g); |
lwills | 0:09aa1ecd6c39 | 50 | missile_init(); |
lwills | 0:09aa1ecd6c39 | 51 | player_init(); |
lwills | 0:09aa1ecd6c39 | 52 | pc.printf("Initialization complete\n"); |
lwills | 0:09aa1ecd6c39 | 53 | |
lwills | 0:09aa1ecd6c39 | 54 | while(1) |
lwills | 0:09aa1ecd6c39 | 55 | { |
lwills | 0:09aa1ecd6c39 | 56 | t.start(); |
lwills | 0:09aa1ecd6c39 | 57 | // Generate new missiles and draw all active missiles at current |
lwills | 0:09aa1ecd6c39 | 58 | // positions. (Already implemented.) |
lwills | 0:09aa1ecd6c39 | 59 | missile_generator(); |
lwills | 0:09aa1ecd6c39 | 60 | |
lwills | 0:09aa1ecd6c39 | 61 | // Draw all active anti-missiles (aka player missiles) at current |
lwills | 0:09aa1ecd6c39 | 62 | // positions. (Already implemented.) |
lwills | 0:09aa1ecd6c39 | 63 | player_missile_draw(); |
lwills | 0:09aa1ecd6c39 | 64 | |
lwills | 0:09aa1ecd6c39 | 65 | // Detect missile collisions with city/land and update status. |
lwills | 0:09aa1ecd6c39 | 66 | // You need to implement this (see specification below). |
lwills | 0:09aa1ecd6c39 | 67 | num_remain_city = city_landscape_update(); |
lwills | 0:09aa1ecd6c39 | 68 | |
lwills | 0:09aa1ecd6c39 | 69 | // Detect missile collision with player aircraft. |
lwills | 0:09aa1ecd6c39 | 70 | // You need to implement this (see specification below). |
lwills | 0:09aa1ecd6c39 | 71 | player_alive = was_player_hit(); //returns 0 if player is hit; else 1 |
lwills | 0:09aa1ecd6c39 | 72 | |
lwills | 0:09aa1ecd6c39 | 73 | // Detect missile collisions with player anti-missiles. |
lwills | 0:09aa1ecd6c39 | 74 | // You need to implement this (see specification below). |
lwills | 0:09aa1ecd6c39 | 75 | missile_contact(); |
lwills | 0:09aa1ecd6c39 | 76 | |
lwills | 0:09aa1ecd6c39 | 77 | // You must complete the implementation of this function in hardware.cpp: |
lwills | 0:09aa1ecd6c39 | 78 | inputs = read_inputs(); |
lwills | 0:09aa1ecd6c39 | 79 | |
lwills | 0:09aa1ecd6c39 | 80 | // You must write the code to dispatch to the correct action (e.g., |
lwills | 0:09aa1ecd6c39 | 81 | // player_moveLeft/Right, player_fire, etc.) based on the inputs read. |
lwills | 0:09aa1ecd6c39 | 82 | // You must also implement player_moveLeft/moveRight/fire (see player |
lwills | 0:09aa1ecd6c39 | 83 | // module). |
lwills | 0:09aa1ecd6c39 | 84 | |
lwills | 0:09aa1ecd6c39 | 85 | |
lwills | 0:09aa1ecd6c39 | 86 | // You must write code to detect and implement game over. |
lwills | 0:09aa1ecd6c39 | 87 | if (player_alive) break; // replace this line |
lwills | 0:09aa1ecd6c39 | 88 | |
lwills | 0:09aa1ecd6c39 | 89 | // Compute update time to control timing of the game loop. |
lwills | 0:09aa1ecd6c39 | 90 | // (Already implemented... you're welcome.) |
lwills | 0:09aa1ecd6c39 | 91 | t.stop(); |
lwills | 0:09aa1ecd6c39 | 92 | dt = t.read_ms(); |
lwills | 0:09aa1ecd6c39 | 93 | if (dt < 100) wait_ms(100 - dt); |
lwills | 0:09aa1ecd6c39 | 94 | } |
lwills | 0:09aa1ecd6c39 | 95 | pc.printf("out of main loop\n"); |
lwills | 0:09aa1ecd6c39 | 96 | |
lwills | 0:09aa1ecd6c39 | 97 | // You must write code to free up any dynamically allocated objects such |
lwills | 0:09aa1ecd6c39 | 98 | // as lists of missiles (hint: destroyList can be used for doubly linked |
lwills | 0:09aa1ecd6c39 | 99 | // lists). |
lwills | 0:09aa1ecd6c39 | 100 | |
lwills | 0:09aa1ecd6c39 | 101 | return 0; |
lwills | 0:09aa1ecd6c39 | 102 | } |
lwills | 0:09aa1ecd6c39 | 103 | |
lwills | 0:09aa1ecd6c39 | 104 | /** Detect whether any missile has hit a city and if so, call |
lwills | 0:09aa1ecd6c39 | 105 | city_demolish (hint: city_get_info may be useful). |
lwills | 0:09aa1ecd6c39 | 106 | Also, if any missile has hit a city or the landscape, |
lwills | 0:09aa1ecd6c39 | 107 | mark the missile's status as MISSILE_EXPLODED |
lwills | 0:09aa1ecd6c39 | 108 | which will cue the missile's deletion and erasure from the screen |
lwills | 0:09aa1ecd6c39 | 109 | on the next missile_generator call. |
lwills | 0:09aa1ecd6c39 | 110 | @return Number of remaining cities. |
lwills | 0:09aa1ecd6c39 | 111 | */ |
lwills | 0:09aa1ecd6c39 | 112 | int city_landscape_update(void){ |
lwills | 0:09aa1ecd6c39 | 113 | // Complete this function. |
lwills | 0:09aa1ecd6c39 | 114 | return num_city_g; |
lwills | 0:09aa1ecd6c39 | 115 | } |
lwills | 0:09aa1ecd6c39 | 116 | |
lwills | 0:09aa1ecd6c39 | 117 | /** Detect whether any missile has hit the player aircraft and if so, call |
lwills | 0:09aa1ecd6c39 | 118 | player_destroy (hint: player_get_info may be useful) and mark the |
lwills | 0:09aa1ecd6c39 | 119 | missile's status as MISSILE_EXPLODED which will cue the missile's deletion |
lwills | 0:09aa1ecd6c39 | 120 | and erasure from the screen on the next missile_generator call. |
lwills | 0:09aa1ecd6c39 | 121 | @return 1 if the player aircraft was hit and 0 otherwise. |
lwills | 0:09aa1ecd6c39 | 122 | */ |
lwills | 0:09aa1ecd6c39 | 123 | int was_player_hit(){ |
lwills | 0:09aa1ecd6c39 | 124 | return 0; |
lwills | 0:09aa1ecd6c39 | 125 | } |
lwills | 0:09aa1ecd6c39 | 126 | |
lwills | 0:09aa1ecd6c39 | 127 | /** Detect whether any missile has hit any player missile and if so, |
lwills | 0:09aa1ecd6c39 | 128 | mark the status of both the missile and the player missile as |
lwills | 0:09aa1ecd6c39 | 129 | MISSILE_EXPLODED which will cue the missile's deletion and erasure |
lwills | 0:09aa1ecd6c39 | 130 | from the screen on the next missile_generator call. |
lwills | 0:09aa1ecd6c39 | 131 | */ |
lwills | 0:09aa1ecd6c39 | 132 | void missile_contact(void) { |
lwills | 0:09aa1ecd6c39 | 133 | } |
lwills | 0:09aa1ecd6c39 | 134 | |
lwills | 0:09aa1ecd6c39 | 135 | /* We need a random number generator (e.g., in missile_create to generate |
lwills | 0:09aa1ecd6c39 | 136 | random positions for the missiles to start, making the game different |
lwills | 0:09aa1ecd6c39 | 137 | every time). C provides a pseudo random number generator (in stdlib) but |
lwills | 0:09aa1ecd6c39 | 138 | it requires that we give it a different seed for each new game. A common |
lwills | 0:09aa1ecd6c39 | 139 | way to do this is to sample a clock and use the time as the seed. However |
lwills | 0:09aa1ecd6c39 | 140 | if we do this by starting a simple Timer t when the mbed starts running the |
lwills | 0:09aa1ecd6c39 | 141 | program and then sample it (t.read_ms), we will always get exactly the same |
lwills | 0:09aa1ecd6c39 | 142 | time sample -- t.read_ms will always occur at the same time in the program's |
lwills | 0:09aa1ecd6c39 | 143 | execution. We introduce variability in when we sample the time by waiting |
lwills | 0:09aa1ecd6c39 | 144 | for the user to push any button before we call t.read_ms. |
lwills | 0:09aa1ecd6c39 | 145 | */ |
lwills | 0:09aa1ecd6c39 | 146 | void set_random_seed(Timer t) { |
lwills | 0:09aa1ecd6c39 | 147 | GameInputs inputs; |
lwills | 0:09aa1ecd6c39 | 148 | t.start(); |
lwills | 0:09aa1ecd6c39 | 149 | uLCD.printf("Push any button to start.\n"); |
lwills | 0:09aa1ecd6c39 | 150 | while(1){ |
lwills | 0:09aa1ecd6c39 | 151 | inputs = read_inputs(); |
lwills | 0:09aa1ecd6c39 | 152 | if (inputs.b1 || inputs.b2 || inputs.b3) break; |
lwills | 0:09aa1ecd6c39 | 153 | } |
lwills | 0:09aa1ecd6c39 | 154 | uLCD.cls(); |
lwills | 0:09aa1ecd6c39 | 155 | t.stop(); |
lwills | 0:09aa1ecd6c39 | 156 | int seed = t.read_ms(); |
lwills | 0:09aa1ecd6c39 | 157 | srand(seed); |
lwills | 0:09aa1ecd6c39 | 158 | } |
lwills | 0:09aa1ecd6c39 | 159 |