Game For ECE 2035

Dependencies:   mbed wave_player 4DGL-uLCD-SE MMA8452

Committer:
rashidi1saeed
Date:
Mon Oct 28 04:56:07 2019 +0000
Revision:
2:1ca97843a334
Parent:
0:35660d7952f7
Child:
3:e4690ad5a4d2
Added more comments

Who changed what in which revision?

UserRevisionLine numberNew contents of line
rconnorlawson 0:35660d7952f7 1 // Project includes
rconnorlawson 0:35660d7952f7 2 #include "globals.h"
rconnorlawson 0:35660d7952f7 3 #include "hardware.h"
rconnorlawson 0:35660d7952f7 4 #include "map.h"
rconnorlawson 0:35660d7952f7 5 #include "graphics.h"
rconnorlawson 0:35660d7952f7 6 #include "speech.h"
rconnorlawson 0:35660d7952f7 7
rconnorlawson 0:35660d7952f7 8 // Functions in this file
rconnorlawson 0:35660d7952f7 9 int get_action (GameInputs inputs);
rconnorlawson 0:35660d7952f7 10 int update_game (int action);
rconnorlawson 0:35660d7952f7 11 void draw_game (int init);
rconnorlawson 0:35660d7952f7 12 void init_main_map ();
rconnorlawson 0:35660d7952f7 13 int main ();
rconnorlawson 0:35660d7952f7 14
rconnorlawson 0:35660d7952f7 15 /**
rconnorlawson 0:35660d7952f7 16 * The main game state. Must include Player locations and previous locations for
rconnorlawson 0:35660d7952f7 17 * drawing to work properly. Other items can be added as needed.
rconnorlawson 0:35660d7952f7 18 */
rconnorlawson 0:35660d7952f7 19 struct {
rconnorlawson 0:35660d7952f7 20 int x,y; // Current locations
rconnorlawson 0:35660d7952f7 21 int px, py; // Previous locations
rconnorlawson 0:35660d7952f7 22 int has_key;
rashidi1saeed 2:1ca97843a334 23 // You can add other properties for the player here
rconnorlawson 0:35660d7952f7 24 } Player;
rconnorlawson 0:35660d7952f7 25
rconnorlawson 0:35660d7952f7 26 /**
rconnorlawson 0:35660d7952f7 27 * Given the game inputs, determine what kind of update needs to happen.
rconnorlawson 0:35660d7952f7 28 * Possbile return values are defined below.
rconnorlawson 0:35660d7952f7 29 */
rconnorlawson 0:35660d7952f7 30 #define NO_ACTION 0
rconnorlawson 0:35660d7952f7 31 #define ACTION_BUTTON 1
rconnorlawson 0:35660d7952f7 32 #define MENU_BUTTON 2
rconnorlawson 0:35660d7952f7 33 #define GO_LEFT 3
rconnorlawson 0:35660d7952f7 34 #define GO_RIGHT 4
rconnorlawson 0:35660d7952f7 35 #define GO_UP 5
rconnorlawson 0:35660d7952f7 36 #define GO_DOWN 6
rconnorlawson 0:35660d7952f7 37 int get_action(GameInputs inputs)
rconnorlawson 0:35660d7952f7 38 {
rconnorlawson 0:35660d7952f7 39 return NO_ACTION;
rconnorlawson 0:35660d7952f7 40 }
rconnorlawson 0:35660d7952f7 41
rconnorlawson 0:35660d7952f7 42 /**
rconnorlawson 0:35660d7952f7 43 * Update the game state based on the user action. For example, if the user
rconnorlawson 0:35660d7952f7 44 * requests GO_UP, then this function should determine if that is possible by
rconnorlawson 0:35660d7952f7 45 * consulting the map, and update the Player position accordingly.
rconnorlawson 0:35660d7952f7 46 *
rconnorlawson 0:35660d7952f7 47 * Return values are defined below. FULL_DRAW indicates that for this frame,
rconnorlawson 0:35660d7952f7 48 * draw_game should not optimize drawing and should draw every tile, even if
rconnorlawson 0:35660d7952f7 49 * the player has not moved.
rconnorlawson 0:35660d7952f7 50 */
rconnorlawson 0:35660d7952f7 51 #define NO_RESULT 0
rconnorlawson 0:35660d7952f7 52 #define GAME_OVER 1
rconnorlawson 0:35660d7952f7 53 #define FULL_DRAW 2
rconnorlawson 0:35660d7952f7 54 int update_game(int action)
rconnorlawson 0:35660d7952f7 55 {
rconnorlawson 0:35660d7952f7 56 // Save player previous location before updating
rconnorlawson 0:35660d7952f7 57 Player.px = Player.x;
rconnorlawson 0:35660d7952f7 58 Player.py = Player.y;
rconnorlawson 0:35660d7952f7 59
rconnorlawson 0:35660d7952f7 60 // Do different things based on the each action.
rconnorlawson 0:35660d7952f7 61 // You can define functions like "go_up()" that get called for each case.
rconnorlawson 0:35660d7952f7 62 switch(action)
rconnorlawson 0:35660d7952f7 63 {
rconnorlawson 0:35660d7952f7 64 case GO_UP: break;
rconnorlawson 0:35660d7952f7 65 case GO_LEFT: break;
rconnorlawson 0:35660d7952f7 66 case GO_DOWN: break;
rconnorlawson 0:35660d7952f7 67 case GO_RIGHT: break;
rconnorlawson 0:35660d7952f7 68 case ACTION_BUTTON: break;
rconnorlawson 0:35660d7952f7 69 case MENU_BUTTON: break;
rconnorlawson 0:35660d7952f7 70 default: break;
rconnorlawson 0:35660d7952f7 71 }
rconnorlawson 0:35660d7952f7 72 return NO_RESULT;
rconnorlawson 0:35660d7952f7 73 }
rconnorlawson 0:35660d7952f7 74
rconnorlawson 0:35660d7952f7 75 /**
rconnorlawson 0:35660d7952f7 76 * Entry point for frame drawing. This should be called once per iteration of
rconnorlawson 0:35660d7952f7 77 * the game loop. This draws all tiles on the screen, followed by the status
rconnorlawson 0:35660d7952f7 78 * bars. Unless init is nonzero, this function will optimize drawing by only
rconnorlawson 0:35660d7952f7 79 * drawing tiles that have changed from the previous frame.
rconnorlawson 0:35660d7952f7 80 */
rconnorlawson 0:35660d7952f7 81 void draw_game(int init)
rconnorlawson 0:35660d7952f7 82 {
rconnorlawson 0:35660d7952f7 83 // Draw game border first
rconnorlawson 0:35660d7952f7 84 if(init) draw_border();
rconnorlawson 0:35660d7952f7 85
rconnorlawson 0:35660d7952f7 86 // Iterate over all visible map tiles
rconnorlawson 0:35660d7952f7 87 for (int i = -5; i <= 5; i++) // Iterate over columns of tiles
rconnorlawson 0:35660d7952f7 88 {
rconnorlawson 0:35660d7952f7 89 for (int j = -4; j <= 4; j++) // Iterate over one column of tiles
rconnorlawson 0:35660d7952f7 90 {
rconnorlawson 0:35660d7952f7 91 // Here, we have a given (i,j)
rconnorlawson 0:35660d7952f7 92
rconnorlawson 0:35660d7952f7 93 // Compute the current map (x,y) of this tile
rconnorlawson 0:35660d7952f7 94 int x = i + Player.x;
rconnorlawson 0:35660d7952f7 95 int y = j + Player.y;
rconnorlawson 0:35660d7952f7 96
rconnorlawson 0:35660d7952f7 97 // Compute the previous map (px, py) of this tile
rconnorlawson 0:35660d7952f7 98 int px = i + Player.px;
rconnorlawson 0:35660d7952f7 99 int py = j + Player.py;
rconnorlawson 0:35660d7952f7 100
rconnorlawson 0:35660d7952f7 101 // Compute u,v coordinates for drawing
rconnorlawson 0:35660d7952f7 102 int u = (i+5)*11 + 3;
rconnorlawson 0:35660d7952f7 103 int v = (j+4)*11 + 15;
rconnorlawson 0:35660d7952f7 104
rconnorlawson 0:35660d7952f7 105 // Figure out what to draw
rconnorlawson 0:35660d7952f7 106 DrawFunc draw = NULL;
rconnorlawson 0:35660d7952f7 107 if (init && i == 0 && j == 0) // Only draw the player on init
rconnorlawson 0:35660d7952f7 108 {
rconnorlawson 0:35660d7952f7 109 draw_player(u, v, Player.has_key);
rconnorlawson 0:35660d7952f7 110 continue;
rconnorlawson 0:35660d7952f7 111 }
rconnorlawson 0:35660d7952f7 112 else if (x >= 0 && y >= 0 && x < map_width() && y < map_height()) // Current (i,j) in the map
rconnorlawson 0:35660d7952f7 113 {
rconnorlawson 0:35660d7952f7 114 MapItem* curr_item = get_here(x, y);
rconnorlawson 0:35660d7952f7 115 MapItem* prev_item = get_here(px, py);
rconnorlawson 0:35660d7952f7 116 if (init || curr_item != prev_item) // Only draw if they're different
rconnorlawson 0:35660d7952f7 117 {
rconnorlawson 0:35660d7952f7 118 if (curr_item) // There's something here! Draw it
rconnorlawson 0:35660d7952f7 119 {
rconnorlawson 0:35660d7952f7 120 draw = curr_item->draw;
rconnorlawson 0:35660d7952f7 121 }
rconnorlawson 0:35660d7952f7 122 else // There used to be something, but now there isn't
rconnorlawson 0:35660d7952f7 123 {
rconnorlawson 0:35660d7952f7 124 draw = draw_nothing;
rconnorlawson 0:35660d7952f7 125 }
rconnorlawson 0:35660d7952f7 126 }
rconnorlawson 0:35660d7952f7 127 }
rconnorlawson 0:35660d7952f7 128 else if (init) // If doing a full draw, but we're out of bounds, draw the walls.
rconnorlawson 0:35660d7952f7 129 {
rconnorlawson 0:35660d7952f7 130 draw = draw_wall;
rconnorlawson 0:35660d7952f7 131 }
rconnorlawson 0:35660d7952f7 132
rconnorlawson 0:35660d7952f7 133 // Actually draw the tile
rconnorlawson 0:35660d7952f7 134 if (draw) draw(u, v);
rconnorlawson 0:35660d7952f7 135 }
rconnorlawson 0:35660d7952f7 136 }
rconnorlawson 0:35660d7952f7 137
rconnorlawson 0:35660d7952f7 138 // Draw status bars
rconnorlawson 0:35660d7952f7 139 draw_upper_status();
rconnorlawson 0:35660d7952f7 140 draw_lower_status();
rconnorlawson 0:35660d7952f7 141 }
rconnorlawson 0:35660d7952f7 142
rconnorlawson 0:35660d7952f7 143
rconnorlawson 0:35660d7952f7 144 /**
rconnorlawson 0:35660d7952f7 145 * Initialize the main world map. Add walls around the edges, interior chambers,
rashidi1saeed 2:1ca97843a334 146 * and plants in the background so you can see motion. Note: using the similar
rashidi1saeed 2:1ca97843a334 147 * procedusre you can init the secondary map(s).
rconnorlawson 0:35660d7952f7 148 */
rconnorlawson 0:35660d7952f7 149 void init_main_map()
rconnorlawson 0:35660d7952f7 150 {
rconnorlawson 0:35660d7952f7 151 // "Random" plants
rconnorlawson 0:35660d7952f7 152 Map* map = set_active_map(0);
rconnorlawson 0:35660d7952f7 153 for(int i = map_width() + 3; i < map_area(); i += 39)
rconnorlawson 0:35660d7952f7 154 {
rconnorlawson 0:35660d7952f7 155 add_plant(i % map_width(), i / map_width());
rconnorlawson 0:35660d7952f7 156 }
rconnorlawson 0:35660d7952f7 157 pc.printf("plants\r\n");
rconnorlawson 0:35660d7952f7 158
rconnorlawson 0:35660d7952f7 159 pc.printf("Adding walls!\r\n");
rconnorlawson 0:35660d7952f7 160 add_wall(0, 0, HORIZONTAL, map_width());
rconnorlawson 0:35660d7952f7 161 add_wall(0, map_height()-1, HORIZONTAL, map_width());
rconnorlawson 0:35660d7952f7 162 add_wall(0, 0, VERTICAL, map_height());
rconnorlawson 0:35660d7952f7 163 add_wall(map_width()-1, 0, VERTICAL, map_height());
rconnorlawson 0:35660d7952f7 164 pc.printf("Walls done!\r\n");
rconnorlawson 0:35660d7952f7 165
rconnorlawson 0:35660d7952f7 166 print_map();
rconnorlawson 0:35660d7952f7 167 }
rconnorlawson 0:35660d7952f7 168
rconnorlawson 0:35660d7952f7 169 /**
rconnorlawson 0:35660d7952f7 170 * Program entry point! This is where it all begins.
rconnorlawson 0:35660d7952f7 171 * This function orchestrates all the parts of the game. Most of your
rconnorlawson 0:35660d7952f7 172 * implementation should be elsewhere - this holds the game loop, and should
rconnorlawson 0:35660d7952f7 173 * read like a road map for the rest of the code.
rconnorlawson 0:35660d7952f7 174 */
rconnorlawson 0:35660d7952f7 175 int main()
rconnorlawson 0:35660d7952f7 176 {
rconnorlawson 0:35660d7952f7 177 // First things first: initialize hardware
rconnorlawson 0:35660d7952f7 178 ASSERT_P(hardware_init() == ERROR_NONE, "Hardware init failed!");
rconnorlawson 0:35660d7952f7 179
rconnorlawson 0:35660d7952f7 180 // Initialize the maps
rconnorlawson 0:35660d7952f7 181 maps_init();
rconnorlawson 0:35660d7952f7 182 init_main_map();
rconnorlawson 0:35660d7952f7 183
rconnorlawson 0:35660d7952f7 184 // Initialize game state
rconnorlawson 0:35660d7952f7 185 set_active_map(0);
rconnorlawson 0:35660d7952f7 186 Player.x = Player.y = 5;
rconnorlawson 0:35660d7952f7 187
rconnorlawson 0:35660d7952f7 188 // Initial drawing
rconnorlawson 0:35660d7952f7 189 draw_game(true);
rconnorlawson 0:35660d7952f7 190
rconnorlawson 0:35660d7952f7 191 // Main game loop
rconnorlawson 0:35660d7952f7 192 while(1)
rconnorlawson 0:35660d7952f7 193 {
rconnorlawson 0:35660d7952f7 194 // Timer to measure game update speed
rconnorlawson 0:35660d7952f7 195 Timer t; t.start();
rconnorlawson 0:35660d7952f7 196
rconnorlawson 0:35660d7952f7 197 // Actuall do the game update:
rconnorlawson 0:35660d7952f7 198 // 1. Read inputs
rconnorlawson 0:35660d7952f7 199 // 2. Determine action (get_action)
rconnorlawson 0:35660d7952f7 200 // 3. Update game (update_game)
rconnorlawson 0:35660d7952f7 201 // 3b. Check for game over
rconnorlawson 0:35660d7952f7 202 // 4. Draw frame (draw_game)
rconnorlawson 0:35660d7952f7 203
rconnorlawson 0:35660d7952f7 204 // 5. Frame delay
rconnorlawson 0:35660d7952f7 205 t.stop();
rconnorlawson 0:35660d7952f7 206 int dt = t.read_ms();
rconnorlawson 0:35660d7952f7 207 if (dt < 100) wait_ms(100 - dt);
rconnorlawson 0:35660d7952f7 208 }
rconnorlawson 0:35660d7952f7 209 }