Game For ECE 2035
Dependencies: mbed wave_player 4DGL-uLCD-SE MMA8452
main.cpp
- Committer:
- nasiromar
- Date:
- 2021-12-03
- Revision:
- 18:760dd68e939e
- Parent:
- 16:06a88c0110ff
File content as of revision 18:760dd68e939e:
// Project includes #include "globals.h" #include "hardware.h" #include "map.h" #include "graphics.h" #include "speech.h" #include "spells.h" #include "actions.h" #include "SDFileSystem.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 (); FILE *wave_file; /** * 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; int spell; int god,god_walk; int won; int HP,MP; int talked; int gobs_slain,eye_slain; int money; // You can add other properties for the player here } Player; int i = 3; /** * 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 #define GOD_MODE 7 #define TILT .25 int get_action(GameInputs inputs) { if(inputs.ay > TILT) { //Go in north direction if it is not blocked return GO_UP; } if(inputs.ay < TILT *-1) { //Go in south direction if it is not blocked return GO_DOWN; } if(inputs.ax > TILT) { //Go in north direction if it is not blocked return GO_RIGHT; } if(inputs.ax < TILT *-1) { //Go in north direction if it is not blocked return GO_LEFT; } if(!inputs.b1) { wait(.5); return ACTION_BUTTON; } if(!inputs.b2) { wait(.5); return MENU_BUTTON; } if (!inputs.b3) { wait(.5); return GOD_MODE; } else { 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. */ // Game Life and Magic Points int purchase; bool on_off = false; #define NO_RESULT 0 #define GAME_OVER 1 #define FULL_DRAW 2 int update_game(int action) { walk_npc(); // 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. // Need to check if Claue has changed as well if whats in front of me is able to be walked into switch(action) { case GO_UP: { MapItem* north = get_north(Player.x,Player.y); if (north->walkable && north == NULL || north->type == (PORTAL || PLANT) && Player.y != 0 || Player.god ) { Player.y--; } if (north->walkable && north == NULL && Player.god_walk && Player.god ) { Player.y-=3; } break; } case GO_RIGHT: { MapItem* east = get_east(Player.x,Player.y); if (east->walkable && east == NULL || east->type == (PORTAL || PLANT) && Player.x != 0 || Player.god ) { Player.x++; } if (east->walkable && east == NULL && Player.god_walk && Player.god ) { Player.x+=3; } break; } case GO_DOWN: { MapItem* south = get_south(Player.x,Player.y); if (south->walkable && south == NULL || south->type ==(PORTAL || PLANT) && Player.y != 0 || Player.god ) { Player.y++; } if (south->walkable && south == NULL && Player.god_walk && Player.god ) { Player.y+=3; } break; } case GO_LEFT: { MapItem* west = get_west(Player.x,Player.y); if (west->walkable && west == NULL || west->type == (PORTAL || PLANT) && Player.x != 0 || Player.god ) { Player.x--; } if (west->walkable && west == NULL && Player.god_walk && Player.god ) { Player.x-=3; } break; } case ACTION_BUTTON: { MapItem* west = get_west(Player.x,Player.y); MapItem* south = get_south(Player.x,Player.y); MapItem* north = get_north(Player.x,Player.y); MapItem* east = get_east(Player.x,Player.y); MapItem* curr = get_here(Player.x,Player.y); if(east->type == NPC||west->type == NPC||north->type == NPC||south->type == NPC){ if( Player.has_key == 1) { npc_speech2(); } else npc_speech1(); } if(east->type == NPCT||west->type == NPCT||north->type == NPCT||south->type == NPCT ) { if( Player.has_key == 1) { npc2_speech2(); } else npc2_speech1(); } if(north->type == PORTAL||south->type == PORTAL||east->type == PORTAL||west->type == PORTAL) { set_active_map(1); Player.x = Player.y = 7; } if(north->type == KEY||south->type == KEY||east->type == KEY||west->type == KEY) { pick_key(); map_erase(26,13); } if(Player.HP<50){ heal_up(); } if (Player.MP<50){ mag_up(); } if(east->type == ENEMY1||west->type == ENEMY1||north->type == ENEMY1||south->type == ENEMY1) { Player.HP-=2; fire_dmg(); gob_dmg(); Player.HP-=10; Player.x--; Player.y--; Player.gobs_slain += 1; map_delete(10,10); } if(east->type == ENEMY2||west->type == ENEMY2||north->type == ENEMY2||south->type == ENEMY2) { Player.HP-=12; gob_dmg(); Player.x--; Player.y--; map_delete(5,7); } if(east->type == ENEMY||west->type == ENEMY||north->type == ENEMY||south->type == ENEMY) { Player.HP-=10; eye_dmg(); Player.eye_slain += 1; Player.x--; Player.y--; map_delete(15,15); } if(east->type == CHEST||west->type == CHEST||north->type == CHEST||south->type == CHEST && Player.MP < 100) { potion(); Player.MP += 5; } if(east->type == CHESTT||west->type == CHESTT||north->type == CHESTT||south->type == CHESTT) { money_chest(); Player.money += 2; //wave_file = fopen("/sd/rupee-collect.wav","r"); //waver.play(wave_file); //fclose(wave_file); } if(east->type == VILL||west->type == VILL||north->type == VILL||south->type == VILL) { merch_speech1(); init_store(); purchase = store(); if (purchase == POT && Player.money >= 4) { poti(); Player.money -= 4; Player.MP += 8; } if (purchase == ELX && Player.money >= 5) { elx(); Player.money -= 5; Player.HP += 10; } if (purchase == FRT && Player.money >= 2) { frt(); Player.money -= 2; Player.HP += 6; } if (Player.money <= 1) { cantbuy(); } merch_speech2(); } if(north->type == DRAGON||south->type == DRAGON||east->type == DRAGON||west->type == DRAGON && i >0) { if ( Player.spell == WATER && Player.gobs_slain == 1 && Player.eye_slain == 1) { drg(); i--; } else Player.HP-=50; Player.x--; Player.y--; if (i <=0) { slay_dragon(); map_erase(15,9); Player.has_key = 1; } } if(north->type == PORTAl||south->type == PORTAl||east->type == PORTAl||west->type == PORTAl) { set_active_map(0); add_key(26,13); Player.x=20; Player.y = 36; } if((north->type == DOOR||south->type == DOOR||east->type == DOOR||west->type == DOOR)&&Player.has_key == 1) { Player.won = door_open(); } if((north->type == DOOR||south->type == DOOR||east->type == DOOR||west->type == DOOR)&&Player.has_key == 0) { door_locked(); } if((north->type == PLANT||south->type == PLANT||east->type == PLANT||west->type == PLANT||curr->type == PLANT)&& (north->data == FRUIT||south->data == FRUIT||east->data == FRUIT||west->data == FRUIT||curr->data == FRUIT)) { if(Player.HP < 100) { fruit(); Player.HP += 5; } else no_fruit(); } } break; case MENU_BUTTON: { init_spells(); Player.spell = spell(); Player.MP -= 10; uLCD.locate(15,15); uLCD.printf("S:%1i",Player.spell); } break; case GOD_MODE: { Player.god = !Player.god; if (Player.god) { god_modeOn(); Player.god_walk = !Player.god_walk; } else god_modeOff(); Player.god_walk = Player.god_walk; } 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(Player.x,Player.y,Player.money); draw_lower_status(Player.HP,Player.MP); } /** * Initialize the main world map. Add walls around the edges, interior chambers, * and plants in the background so you can see motion. Note: using the similar * procedure you can init the secondary map(s). */ void init_main_map() { // "Random" plants Map* map = set_active_map(0); for(int i = map_width() + 9; 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"); for(int i = 7; i < 13; i++) { for (int j = 23; j <31; j++) { add_kindom(j,i); } } add_chest2(20,20); add_chest2(5,8); add_chest2(33,20); add_chest2(14,16); add_chest2(40,15); add_npc(10,5); add_npc2(30,30); add_npc2(11,11); add_npc2(20,9); add_merch(12,16); for(int i = 11; i <= 13; i++) { add_store(i,15); } add_fire(27,13); add_fire(25,13); add_door(26,12); add_portal(20,35); 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() { Player.HP = 100; Player.MP = 100; // MapItem* north = get_north(Player.x,Player.y); // First things first: initialize hardware ASSERT_P(hardware_init() == ERROR_NONE, "Hardware init failed!"); // Initialize the maps maps_init(); init_main_map(); init_dung(); // Initialize game state set_active_map(0); Player.x = Player.y = 5; Player.money = 0; Player.spell = NULL; draw_start(); //wave_file = fopen("/sd/godfather.wav","r"); //waver.play(wave_file); //fclose(wave_file); while(1) { Timer t; t.start(); GameInputs inp = read_inputs(); int action = get_action(inp); if( action == ACTION_BUTTON) { break; } t.stop(); int dt = t.read_ms(); if (dt < 100) wait_ms(100-dt); } // Initial drawing draw_game(true); // Main game loop while(1) { // Timer to measure game update speed Timer t; t.start(); // Actually do the game update: // 1. Read inputs GameInputs input = read_inputs(); // 2. Determine action (get_action) int action = get_action(input); // 3. Update game (update_game) update_game(action); // 3b. Check for game over if(Player.HP <= 0) { draw_gameover(); break; } if(Player.won == 1 ){ draw_win(); break; } // 4. Draw frame (draw_game) draw_game(true); // 5. Frame delay t.stop(); int dt = t.read_ms(); if (dt < 100) wait_ms(100 - dt); } // }