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
main.cpp
- Committer:
- rconnorlawson
- Date:
- 2018-03-30
- Revision:
- 0:35660d7952f7
- Child:
- 2:06c63d567719
File content as of revision 0:35660d7952f7:
// 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);
}
}