Game For ECE 2035

Dependencies:   mbed wave_player 4DGL-uLCD-SE MMA8452

Committer:
rconnorlawson
Date:
Fri Mar 30 17:07:25 2018 +0000
Revision:
0:35660d7952f7
Child:
2:1ca97843a334
Hollowed out shell code.

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