Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: mbed wave_player 4DGL-uLCD-SE MMA8452
Diff: main.cpp
- Revision:
- 0:35660d7952f7
- Child:
- 2:06c63d567719
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp Fri Mar 30 17:07:25 2018 +0000
@@ -0,0 +1,207 @@
+// Project includes
+#include "globals.h"
+#include "hardware.h"
+#include "map.h"
+#include "graphics.h"
+#include "speech.h"
+
+// Functions in this file
+int get_action (GameInputs inputs);
+int update_game (int action);
+void draw_game (int init);
+void init_main_map ();
+int main ();
+
+/**
+ * The main game state. Must include Player locations and previous locations for
+ * drawing to work properly. Other items can be added as needed.
+ */
+struct {
+ int x,y; // Current locations
+ int px, py; // Previous locations
+ int has_key;
+} Player;
+
+/**
+ * Given the game inputs, determine what kind of update needs to happen.
+ * Possbile return values are defined below.
+ */
+#define NO_ACTION 0
+#define ACTION_BUTTON 1
+#define MENU_BUTTON 2
+#define GO_LEFT 3
+#define GO_RIGHT 4
+#define GO_UP 5
+#define GO_DOWN 6
+int get_action(GameInputs inputs)
+{
+ return NO_ACTION;
+}
+
+/**
+ * Update the game state based on the user action. For example, if the user
+ * requests GO_UP, then this function should determine if that is possible by
+ * consulting the map, and update the Player position accordingly.
+ *
+ * Return values are defined below. FULL_DRAW indicates that for this frame,
+ * draw_game should not optimize drawing and should draw every tile, even if
+ * the player has not moved.
+ */
+#define NO_RESULT 0
+#define GAME_OVER 1
+#define FULL_DRAW 2
+int update_game(int action)
+{
+ // Save player previous location before updating
+ Player.px = Player.x;
+ Player.py = Player.y;
+
+ // Do different things based on the each action.
+ // You can define functions like "go_up()" that get called for each case.
+ switch(action)
+ {
+ case GO_UP: break;
+ case GO_LEFT: break;
+ case GO_DOWN: break;
+ case GO_RIGHT: break;
+ case ACTION_BUTTON: break;
+ case MENU_BUTTON: break;
+ default: break;
+ }
+ return NO_RESULT;
+}
+
+/**
+ * Entry point for frame drawing. This should be called once per iteration of
+ * the game loop. This draws all tiles on the screen, followed by the status
+ * bars. Unless init is nonzero, this function will optimize drawing by only
+ * drawing tiles that have changed from the previous frame.
+ */
+void draw_game(int init)
+{
+ // Draw game border first
+ if(init) draw_border();
+
+ // Iterate over all visible map tiles
+ for (int i = -5; i <= 5; i++) // Iterate over columns of tiles
+ {
+ for (int j = -4; j <= 4; j++) // Iterate over one column of tiles
+ {
+ // Here, we have a given (i,j)
+
+ // Compute the current map (x,y) of this tile
+ int x = i + Player.x;
+ int y = j + Player.y;
+
+ // Compute the previous map (px, py) of this tile
+ int px = i + Player.px;
+ int py = j + Player.py;
+
+ // Compute u,v coordinates for drawing
+ int u = (i+5)*11 + 3;
+ int v = (j+4)*11 + 15;
+
+ // Figure out what to draw
+ DrawFunc draw = NULL;
+ if (init && i == 0 && j == 0) // Only draw the player on init
+ {
+ draw_player(u, v, Player.has_key);
+ continue;
+ }
+ else if (x >= 0 && y >= 0 && x < map_width() && y < map_height()) // Current (i,j) in the map
+ {
+ MapItem* curr_item = get_here(x, y);
+ MapItem* prev_item = get_here(px, py);
+ if (init || curr_item != prev_item) // Only draw if they're different
+ {
+ if (curr_item) // There's something here! Draw it
+ {
+ draw = curr_item->draw;
+ }
+ else // There used to be something, but now there isn't
+ {
+ draw = draw_nothing;
+ }
+ }
+ }
+ else if (init) // If doing a full draw, but we're out of bounds, draw the walls.
+ {
+ draw = draw_wall;
+ }
+
+ // Actually draw the tile
+ if (draw) draw(u, v);
+ }
+ }
+
+ // Draw status bars
+ draw_upper_status();
+ draw_lower_status();
+}
+
+
+/**
+ * Initialize the main world map. Add walls around the edges, interior chambers,
+ * and plants in the background so you can see motion.
+ */
+void init_main_map()
+{
+ // "Random" plants
+ Map* map = set_active_map(0);
+ for(int i = map_width() + 3; i < map_area(); i += 39)
+ {
+ add_plant(i % map_width(), i / map_width());
+ }
+ pc.printf("plants\r\n");
+
+ pc.printf("Adding walls!\r\n");
+ add_wall(0, 0, HORIZONTAL, map_width());
+ add_wall(0, map_height()-1, HORIZONTAL, map_width());
+ add_wall(0, 0, VERTICAL, map_height());
+ add_wall(map_width()-1, 0, VERTICAL, map_height());
+ pc.printf("Walls done!\r\n");
+
+ print_map();
+}
+
+/**
+ * Program entry point! This is where it all begins.
+ * This function orchestrates all the parts of the game. Most of your
+ * implementation should be elsewhere - this holds the game loop, and should
+ * read like a road map for the rest of the code.
+ */
+int main()
+{
+ // First things first: initialize hardware
+ ASSERT_P(hardware_init() == ERROR_NONE, "Hardware init failed!");
+
+ // Initialize the maps
+ maps_init();
+ init_main_map();
+
+ // Initialize game state
+ set_active_map(0);
+ Player.x = Player.y = 5;
+
+ // Initial drawing
+ draw_game(true);
+
+ // Main game loop
+ while(1)
+ {
+ // Timer to measure game update speed
+ Timer t; t.start();
+
+ // Actuall do the game update:
+ // 1. Read inputs
+ // 2. Determine action (get_action)
+ // 3. Update game (update_game)
+ // 3b. Check for game over
+ // 4. Draw frame (draw_game)
+
+ // 5. Frame delay
+ t.stop();
+ int dt = t.read_ms();
+ if (dt < 100) wait_ms(100 - dt);
+ }
+}