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
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 }
Generated on Wed Jul 27 2022 10:35:26 by
1.7.2