Nasir Christian / Mbed 2 deprecated rpg_game_shell_FA21_Nasir

Dependencies:   mbed wave_player 4DGL-uLCD-SE MMA8452

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 // Project includes
00002 #include "globals.h"
00003 #include "hardware.h"
00004 #include "map.h"
00005 #include "graphics.h"
00006 #include "speech.h"
00007 #include "spells.h"
00008 #include "actions.h"
00009 #include "SDFileSystem.h"
00010 
00011 // Functions in this file
00012 int get_action (GameInputs inputs);
00013 int update_game (int action);
00014 void draw_game (int init);
00015 void init_main_map ();
00016 int main ();
00017 
00018 FILE *wave_file;
00019 
00020 
00021 
00022 
00023 
00024 /**
00025  * The main game state. Must include Player locations and previous locations for
00026  * drawing to work properly. Other items can be added as needed.
00027  */
00028 struct {
00029     int x,y;    // Current locations
00030     int px, py; // Previous locations
00031     int has_key;
00032     int spell;
00033     int god,god_walk;
00034     int won;
00035     int HP,MP;
00036     int talked;
00037     int gobs_slain,eye_slain;
00038     int money;
00039     // You can add other properties for the player here
00040 } Player;
00041 
00042 int i = 3;
00043 
00044 /**
00045  * Given the game inputs, determine what kind of update needs to happen.
00046  * Possbile return values are defined below.
00047  */
00048 #define NO_ACTION 0
00049 #define ACTION_BUTTON 1
00050 #define MENU_BUTTON 2
00051 #define GO_LEFT 3
00052 #define GO_RIGHT 4
00053 #define GO_UP 5
00054 #define GO_DOWN 6
00055 #define GOD_MODE 7
00056 
00057 #define TILT .25
00058 int get_action(GameInputs inputs)
00059 {
00060 
00061     if(inputs.ay > TILT) {      //Go in north direction if it is not blocked
00062         return GO_UP;
00063     }
00064     if(inputs.ay < TILT *-1) {     //Go in south direction if it is not blocked
00065         return GO_DOWN;
00066     }
00067     if(inputs.ax > TILT) {      //Go in north direction if it is not blocked
00068         return GO_RIGHT;
00069     }
00070     if(inputs.ax < TILT *-1) {     //Go in north direction if it is not blocked
00071         return GO_LEFT;
00072     }
00073     if(!inputs.b1) {
00074         wait(.5);
00075         return ACTION_BUTTON;
00076     }
00077     if(!inputs.b2) {
00078         wait(.5);
00079         return MENU_BUTTON;
00080     }
00081     if (!inputs.b3) {
00082         wait(.5);
00083         return GOD_MODE;
00084     } else {
00085         return NO_ACTION;
00086     }
00087 }
00088 
00089 
00090 /**
00091  * Update the game state based on the user action. For example, if the user
00092  * requests GO_UP, then this function should determine if that is possible by
00093  * consulting the map, and update the Player position accordingly.
00094  *
00095  * Return values are defined below. FULL_DRAW indicates that for this frame,
00096  * draw_game should not optimize drawing and should draw every tile, even if
00097  * the player has not moved.
00098  */
00099 // Game Life and Magic Points
00100 
00101 
00102 int purchase;
00103 bool on_off = false;
00104 
00105 
00106 #define NO_RESULT 0
00107 #define GAME_OVER 1
00108 #define FULL_DRAW 2
00109 int update_game(int action)
00110 {
00111     walk_npc();
00112 
00113 
00114 // Save player previous location before updating
00115     Player.px = Player.x;
00116     Player.py = Player.y;
00117 
00118     // Do different things based on the each action.
00119     // You can define functions like "go_up()" that get called for each case.
00120 
00121     // Need to check if Claue has changed as well if whats in front of me is able to be walked into
00122     switch(action) {
00123         case GO_UP: {
00124             MapItem* north = get_north(Player.x,Player.y);
00125             if (north->walkable && north == NULL || north->type == (PORTAL || PLANT) && Player.y != 0 || Player.god ) {
00126                 Player.y--;
00127 
00128             }
00129             if (north->walkable && north == NULL && Player.god_walk && Player.god ) {
00130                 Player.y-=3;
00131 
00132             }
00133             break;
00134         }
00135         case GO_RIGHT: {
00136             MapItem* east = get_east(Player.x,Player.y);
00137             if (east->walkable && east == NULL || east->type == (PORTAL || PLANT) && Player.x != 0 || Player.god ) {
00138                 Player.x++;
00139             }
00140             if (east->walkable && east == NULL && Player.god_walk && Player.god ) {
00141                 Player.x+=3;
00142             }
00143             break;
00144         }
00145         case GO_DOWN:  {
00146             MapItem* south = get_south(Player.x,Player.y);
00147             if (south->walkable && south == NULL || south->type ==(PORTAL || PLANT) && Player.y != 0 || Player.god ) {
00148                 Player.y++;
00149             }
00150             if (south->walkable && south == NULL && Player.god_walk && Player.god ) {
00151                 Player.y+=3;
00152 
00153             }
00154             break;
00155         }
00156         case GO_LEFT: {
00157             MapItem* west = get_west(Player.x,Player.y);
00158             if (west->walkable && west == NULL || west->type == (PORTAL || PLANT) && Player.x != 0 || Player.god  ) {
00159                 Player.x--;
00160             }
00161             
00162             if (west->walkable && west == NULL && Player.god_walk && Player.god ) {
00163                 Player.x-=3;
00164             }
00165             break;
00166         }
00167         case ACTION_BUTTON: {
00168             MapItem* west = get_west(Player.x,Player.y);
00169             MapItem* south = get_south(Player.x,Player.y);
00170             MapItem* north = get_north(Player.x,Player.y);
00171             MapItem* east = get_east(Player.x,Player.y);
00172             MapItem* curr =  get_here(Player.x,Player.y);
00173 
00174             if(east->type == NPC||west->type == NPC||north->type == NPC||south->type == NPC){
00175                 if( Player.has_key == 1)
00176                  {
00177                 npc_speech2();
00178                 }
00179                 else
00180                     npc_speech1();   
00181             }
00182 
00183            
00184 
00185             if(east->type == NPCT||west->type == NPCT||north->type == NPCT||south->type == NPCT ) {
00186                 if( Player.has_key == 1)
00187                  {
00188                 npc2_speech2();
00189                 }
00190                 else
00191                     npc2_speech1();   
00192             }
00193             
00194 
00195             if(north->type == PORTAL||south->type == PORTAL||east->type == PORTAL||west->type == PORTAL) {
00196                 set_active_map(1);
00197                 Player.x = Player.y = 7;
00198             }
00199             if(north->type == KEY||south->type == KEY||east->type == KEY||west->type == KEY) {
00200             pick_key();
00201             map_erase(26,13);
00202             }
00203 
00204             
00205             if(Player.HP<50){
00206                 heal_up();
00207                 }
00208             if (Player.MP<50){
00209                 mag_up();
00210                 }
00211             
00212 
00213             if(east->type == ENEMY1||west->type == ENEMY1||north->type == ENEMY1||south->type == ENEMY1) {
00214                 Player.HP-=2;
00215                 fire_dmg();
00216                 gob_dmg();
00217                 Player.HP-=10;
00218                 Player.x--;
00219                 Player.y--;
00220                 Player.gobs_slain += 1;
00221                 map_delete(10,10);
00222             }
00223 
00224             if(east->type == ENEMY2||west->type == ENEMY2||north->type == ENEMY2||south->type == ENEMY2) {
00225                 Player.HP-=12;
00226                 gob_dmg();
00227                 Player.x--;
00228                 Player.y--;
00229                 map_delete(5,7);
00230             }
00231 
00232             if(east->type == ENEMY||west->type == ENEMY||north->type == ENEMY||south->type == ENEMY) {
00233                 Player.HP-=10;
00234                 eye_dmg();
00235                 Player.eye_slain += 1;
00236                 Player.x--;
00237                 Player.y--;
00238                 map_delete(15,15);
00239             }
00240 
00241             if(east->type == CHEST||west->type == CHEST||north->type == CHEST||south->type == CHEST  && Player.MP < 100) {
00242                 potion();
00243                 Player.MP += 5;
00244             }
00245 
00246             if(east->type == CHESTT||west->type == CHESTT||north->type == CHESTT||south->type == CHESTT) {
00247                 money_chest();
00248                 Player.money += 2;
00249                 //wave_file = fopen("/sd/rupee-collect.wav","r");
00250                 //waver.play(wave_file);
00251                 //fclose(wave_file);
00252             }
00253 
00254             if(east->type == VILL||west->type == VILL||north->type == VILL||south->type == VILL) {
00255                 merch_speech1();
00256                 init_store();
00257                 purchase = store();
00258 
00259                 if (purchase == POT && Player.money >= 4) {
00260                     poti();
00261                     Player.money -= 4;
00262                     Player.MP += 8;
00263                 }
00264 
00265                 if (purchase == ELX && Player.money >= 5) {
00266                     elx();
00267                     Player.money -= 5;
00268                     Player.HP += 10;
00269                 }
00270 
00271                 if (purchase == FRT && Player.money >= 2) {
00272                     frt();
00273                     Player.money -= 2;
00274                     Player.HP += 6;
00275                 }
00276                 if (Player.money <= 1) {
00277                     cantbuy();
00278                 }
00279 
00280                 merch_speech2();
00281             }
00282 
00283 
00284             if(north->type == DRAGON||south->type == DRAGON||east->type == DRAGON||west->type == DRAGON && i >0) {
00285 
00286                     if ( Player.spell == WATER && Player.gobs_slain == 1 && Player.eye_slain == 1) {
00287                         drg();
00288                         i--;
00289 
00290                     } else
00291                         Player.HP-=50;
00292                     Player.x--;
00293                     Player.y--;
00294                     
00295                 
00296              if (i <=0) {
00297                 slay_dragon();
00298                 map_erase(15,9);
00299                 Player.has_key = 1;
00300                 
00301                 
00302             
00303 }
00304 }
00305             
00306         
00307         
00308 
00309         if(north->type == PORTAl||south->type == PORTAl||east->type == PORTAl||west->type == PORTAl) {
00310             set_active_map(0);
00311             add_key(26,13);
00312             Player.x=20;
00313             Player.y = 36;
00314         }
00315 
00316         if((north->type == DOOR||south->type == DOOR||east->type == DOOR||west->type == DOOR)&&Player.has_key == 1) {
00317             Player.won = door_open();
00318         }
00319 
00320         if((north->type == DOOR||south->type == DOOR||east->type == DOOR||west->type == DOOR)&&Player.has_key == 0) {
00321             door_locked();
00322         }
00323 
00324         if((north->type == PLANT||south->type == PLANT||east->type == PLANT||west->type == PLANT||curr->type == PLANT)&&
00325                 (north->data == FRUIT||south->data == FRUIT||east->data == FRUIT||west->data == FRUIT||curr->data == FRUIT)) {
00326             if(Player.HP < 100) {
00327                 fruit();
00328                 Player.HP += 5;
00329                 
00330             } else
00331                 no_fruit();
00332 
00333 
00334 
00335 
00336 
00337         }
00338     }
00339     break;
00340 case MENU_BUTTON: {
00341         init_spells();
00342 
00343         Player.spell = spell();
00344         Player.MP -= 10;
00345         uLCD.locate(15,15);
00346         uLCD.printf("S:%1i",Player.spell);
00347     }
00348     break;
00349 case GOD_MODE: {
00350 
00351         Player.god = !Player.god;
00352         if (Player.god) {
00353             god_modeOn();
00354             Player.god_walk = !Player.god_walk;
00355         } else
00356             god_modeOff();
00357             Player.god_walk = Player.god_walk;
00358 
00359     }
00360     break;
00361 
00362 default:
00363 
00364     break;
00365 }
00366 
00367 
00368 return NO_RESULT;
00369 
00370 
00371 }
00372 
00373 /**
00374  * Entry point for frame drawing. This should be called once per iteration of
00375  * the game loop. This draws all tiles on the screen, followed by the status
00376  * bars. Unless init is nonzero, this function will optimize drawing by only
00377  * drawing tiles that have changed from the previous frame.
00378  */
00379 
00380 
00381 
00382 void draw_game(int init)
00383 {
00384     // Draw game border first
00385     if(init) draw_border();
00386 
00387     // Iterate over all visible map tiles
00388     for (int i = -5; i <= 5; i++) { // Iterate over columns of tiles
00389         for (int j = -4; j <= 4; j++) { // Iterate over one column of tiles
00390             // Here, we have a given (i,j)
00391 
00392             // Compute the current map (x,y) of this tile
00393             int x = i + Player.x;
00394             int y = j + Player.y;
00395 
00396             // Compute the previous map (px, py) of this tile
00397             int px = i + Player.px;
00398             int py = j + Player.py;
00399 
00400             // Compute u,v coordinates for drawing
00401             int u = (i+5)*11 + 3;
00402             int v = (j+4)*11 + 15;
00403 
00404             // Figure out what to draw
00405             DrawFunc draw = NULL;
00406             if (init && i == 0 && j == 0) { // Only draw the player on init
00407                 draw_player(u, v, Player.has_key);
00408                 continue;
00409             } else if (x >= 0 && y >= 0 && x < map_width() && y < map_height()) { // Current (i,j) in the map
00410                 MapItem* curr_item = get_here(x, y);
00411                 MapItem* prev_item = get_here(px, py);
00412                 if (init || curr_item != prev_item) { // Only draw if they're different
00413                     if (curr_item) { // There's something here! Draw it
00414                         draw = curr_item->draw;
00415                     } else { // There used to be something, but now there isn't
00416                         draw = draw_nothing;
00417                     }
00418                 }
00419             } else if (init) { // If doing a full draw, but we're out of bounds, draw the walls.
00420                 draw = draw_wall;
00421             }
00422 
00423             // Actually draw the tile
00424             if (draw) draw(u, v);
00425         }
00426     }
00427 
00428     // Draw status bars
00429     draw_upper_status(Player.x,Player.y,Player.money);
00430     draw_lower_status(Player.HP,Player.MP);
00431 }
00432 
00433 
00434 /**
00435  * Initialize the main world map. Add walls around the edges, interior chambers,
00436  * and plants in the background so you can see motion. Note: using the similar
00437  * procedure you can init the secondary map(s).
00438  */
00439 void init_main_map()
00440 {
00441     // "Random" plants
00442     Map* map = set_active_map(0);
00443     for(int i = map_width() + 9; i < map_area(); i += 39) {
00444         add_plant(i % map_width(), i / map_width());
00445     }
00446     pc.printf("plants\r\n");
00447 
00448     pc.printf("Adding walls!\r\n");
00449     add_wall(0,              0,              HORIZONTAL, map_width());
00450     add_wall(0,              map_height()-1, HORIZONTAL, map_width());
00451     add_wall(0,              0,              VERTICAL,   map_height());
00452     add_wall(map_width()-1,  0,              VERTICAL,   map_height());
00453     pc.printf("Walls done!\r\n");
00454 
00455 
00456 
00457     for(int i = 7; i < 13; i++) {
00458         for (int j = 23; j <31; j++) {
00459             add_kindom(j,i);
00460         }
00461     }
00462 
00463     add_chest2(20,20);
00464     add_chest2(5,8);
00465     add_chest2(33,20);
00466     add_chest2(14,16);
00467     add_chest2(40,15);
00468 
00469     add_npc(10,5);
00470 
00471     add_npc2(30,30);
00472 
00473     add_npc2(11,11);
00474 
00475     add_npc2(20,9);
00476 
00477     add_merch(12,16);
00478 
00479     for(int i = 11; i <= 13; i++) {
00480         add_store(i,15);
00481     }
00482 
00483     add_fire(27,13);
00484     add_fire(25,13);
00485 
00486     add_door(26,12);
00487 
00488     add_portal(20,35);
00489 
00490     print_map();
00491 }
00492 
00493 /**
00494  * Program entry point! This is where it all begins.
00495  * This function orchestrates all the parts of the game. Most of your
00496  * implementation should be elsewhere - this holds the game loop, and should
00497  * read like a road map for the rest of the code.
00498  */
00499 int main()
00500 {
00501 
00502     Player.HP = 100;
00503     Player.MP = 100;
00504 
00505     // MapItem* north = get_north(Player.x,Player.y);
00506 
00507 
00508     // First things first: initialize hardware
00509     ASSERT_P(hardware_init() == ERROR_NONE, "Hardware init failed!");
00510 
00511     // Initialize the maps
00512     maps_init();
00513     init_main_map();
00514     init_dung();
00515 
00516 
00517 
00518     // Initialize game state
00519     set_active_map(0);
00520     Player.x = Player.y = 5;
00521     Player.money = 0;
00522     Player.spell = NULL;
00523 
00524 
00525     draw_start();
00526 
00527     //wave_file = fopen("/sd/godfather.wav","r");
00528     //waver.play(wave_file);
00529     //fclose(wave_file);
00530 
00531     while(1) {
00532 
00533         Timer t;
00534         t.start();
00535         GameInputs inp =  read_inputs();
00536         int action = get_action(inp);
00537 
00538 
00539         if( action == ACTION_BUTTON) {
00540 
00541             break;
00542         }
00543         t.stop();
00544         int dt = t.read_ms();
00545         if (dt < 100) wait_ms(100-dt);
00546 
00547     }
00548 
00549 
00550     // Initial drawing
00551     draw_game(true);
00552     // Main game loop
00553     while(1) {
00554         // Timer to measure game update speed
00555         Timer t;
00556         t.start();
00557 
00558         // Actually do the game update:
00559         // 1. Read inputs
00560         GameInputs input = read_inputs();
00561         // 2. Determine action (get_action)
00562         int action = get_action(input);
00563         // 3. Update game (update_game)
00564         update_game(action);
00565         // 3b. Check for game over
00566         if(Player.HP <= 0) {
00567             draw_gameover();
00568             break;
00569         }
00570         if(Player.won == 1 ){
00571             draw_win();
00572             break;
00573             }
00574         // 4. Draw frame (draw_game)
00575         draw_game(true);
00576 
00577         // 5. Frame delay
00578         t.stop();
00579         int dt = t.read_ms();
00580         if (dt < 100) wait_ms(100 - dt);
00581     }
00582     //
00583 
00584 
00585 }