ECE 2035 final project
Dependencies: mbed wave_player 4DGL-uLCD-SE MMA8452
Diff: main.cpp
- Revision:
- 2:22d36e7740f1
- Parent:
- 0:35660d7952f7
diff -r 399033d39feb -r 22d36e7740f1 main.cpp --- a/main.cpp Wed Apr 04 21:11:07 2018 +0000 +++ b/main.cpp Mon Apr 15 12:25:08 2019 +0000 @@ -5,11 +5,23 @@ #include "graphics.h" #include "speech.h" +int omnipotent = 0; +int mapToggle = 0; +int finished = 0; +int walk = 0; + // Functions in this file int get_action (GameInputs inputs); int update_game (int action); void draw_game (int init); void init_main_map (); +void init_second_map(); +int go_up(int x, int y, int i); +int go_down(int x, int y, int i); +int go_right(int x, int y, int i); +int go_left(int x, int y, int i); +int interact(int x, int y); +int NPC_move(int x, int y); int main (); /** @@ -20,6 +32,12 @@ int x,y; // Current locations int px, py; // Previous locations int has_key; + int omnipotent; + int has_sword; + int has_shield; + int has_platebody; + int health; + int num_phats; } Player; /** @@ -29,13 +47,124 @@ #define NO_ACTION 0 #define ACTION_BUTTON 1 #define MENU_BUTTON 2 +#define OMNIPOTENT 7 #define GO_LEFT 3 +#define GO_LEFT2 10 #define GO_RIGHT 4 +#define GO_RIGHT2 11 #define GO_UP 5 +#define GO_UP2 12 #define GO_DOWN 6 +#define GO_DOWN2 13 +#define BAD_END 8 +#define GOOD_END 9 + +char *questStartLine1 = "Wow a knight!what"; +char *questStartLine2 = "perfect timing!"; +char *questStartLine3 = "I beg you,please"; +char *questStartLine4 = "defeat the evil"; +char *questStartLine5 = "dragon Elvarg!"; +char *questStartLine6 = "He resides in a"; +char *questStartLine7 = "cave to the NEast"; +char *questStartLine8 = "You'll need an"; +char *questStartLine9 = "antifire shield"; +char *questStartLine10 = "and Excalibur!"; +char *questStartLine11 = "I hear Excalibur"; +char *questStartLine12 = "can be found in"; +char *questStartLine13 = "the same cave."; +char *questStartLine14 = "It'll be embedded"; +char *questStartLine15 = "in a stone there."; +char *questStartLine16 = "Take my antifire"; +char *questStartLine17 = "shield, man."; +char *questStartLine18 = "If you do defeat"; +char *questStartLine19 = "Elvarg, take"; +char *questStartLine20 = "the key he drops."; +char *questStartLine21 = "It unlocks his"; +char *questStartLine22 = "treasure room"; +char *questStartLine23 = "to the south."; +char *questStartLine24 = "Good luck!"; +char *questStartLine25 = "Come back when"; +char *questStartLine26 = "you're done!"; + +char *questHasShield1 = "Go to the cave,"; +char *questHasShield2 = "find Excalibur,"; +char *questHasShield3 = "and defeat Elvarg"; + +char *questHasSword1 = "Go fight Evlarg!"; + +char *questHasPlatebody1 = "Thank you!!!!"; +char *questHasPlatebody2 = "You have helped"; +char *questHasPlatebody3 = "me out.I am"; +char *questHasPlatebody4 = "very grateful!"; + +char *findSword1 = "You pull and"; +char *findSword2 = "wield Excalibur."; + +char *elvarg1 = "You approach"; +char *elvarg2 = "Elvarg attacks..."; +char *elvarg3a1 = "With no shield,"; +char *elvarg3a2 = "you are burnt to"; +char *elvarg3a3 = "a crisp.(-10 HP)"; +char *elvarg3b1 = "You have no sword"; +char *elvarg3b2 = "Your punches have"; +char *elvarg3b3 = "no effect so you"; +char *elvarg3b4 = "are badly wounded"; +char *elvarg3b5 = "(-9 HP)"; +char *elvarg3c1 = "Using Excalibur &"; +char *elvarg3c2 = "the shield you"; +char *elvarg3c3 = "defeat Elvarg w/"; +char *elvarg3c4 = "only minor wounds"; +char *elvarg3c5 = "(-3 HP).He drops"; +char *elvarg3c6 = "the key to his"; +char *elvarg3c7 = "treasure room!"; + + int get_action(GameInputs inputs) { - return NO_ACTION; + if(Player.health <= 0) + { + return BAD_END; + } + else if(finished) + { + return GOOD_END; + } + else if(!inputs.b1){ + return ACTION_BUTTON; + } + else if(!inputs.b2){ + return OMNIPOTENT; + } + else if(!inputs.b3){ + return MENU_BUTTON; + } + else if(inputs.ax >= .2){ + if(inputs.ax >= .4) + return GO_LEFT2; + else + return GO_LEFT; + } + else if(inputs.ax <= -.3){ + if(inputs.ax <= -.5) + return GO_RIGHT2; + else + return GO_RIGHT; + } + else if(inputs.ay >= .3){ + if(inputs.ay >= .5) + return GO_DOWN2; + else + return GO_DOWN; + } + else if(inputs.ay <= -.2){ + if(inputs.ay <= -.4) + return GO_UP2; + else + return GO_UP; + } + else{ + return NO_ACTION; + } } /** @@ -50,6 +179,7 @@ #define NO_RESULT 0 #define GAME_OVER 1 #define FULL_DRAW 2 +#define RUN 3 int update_game(int action) { // Save player previous location before updating @@ -60,17 +190,356 @@ // 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; + case GO_UP: + if(go_up(Player.x, Player.y, 0)) + return FULL_DRAW; + break; + case GO_UP2: + if(go_up(Player.x, Player.y,1)) + return RUN; + break; + case GO_LEFT: + if(go_left(Player.x, Player.y, 0)) + return FULL_DRAW; + break; + case GO_LEFT2: + if(go_left(Player.x, Player.y, 1)) + return RUN; + break; + case GO_DOWN: + if(go_down(Player.x, Player.y, 0)) + return FULL_DRAW; + break; + case GO_DOWN2: + if(go_down(Player.x, Player.y, 1)) + return RUN; + break; + case GO_RIGHT: + if(go_right(Player.x, Player.y, 0)) + return FULL_DRAW; + break; + case GO_RIGHT2: + if(go_right(Player.x, Player.y, 1)) + return RUN; + break; + case ACTION_BUTTON: + if(interact(Player.x, Player.y)) + return FULL_DRAW; + break; + case OMNIPOTENT: //toggle omnipotent mode + Player.omnipotent = !omnipotent; + omnipotent = !omnipotent; + break; + case MENU_BUTTON: //open menu + draw_menu(Player.omnipotent, Player.has_sword, Player.has_shield, Player.has_platebody, Player.has_key); + return FULL_DRAW; + case BAD_END: + return BAD_END; + case GOOD_END: + return GOOD_END; + default: + return NPC_move(Player.x, Player.y); } return NO_RESULT; } +//Functions to move player +int go_up(int x, int y, int i) +{ + MapItem *item = get_north(x, y); + MapItem *item2 = get_north(x,y-1); + if((item->walkable && item->type != PLANT2) || Player.omnipotent) + { + if((i && item2->walkable && item2->type != PLANT2) || Player.omnipotent) + { + Player.y = Player.y - 2; + return RUN; + } + Player.y--; + return 1; + } + else if(item->type == PLANT2) + { + Player.health--; + speaker.period(1.0/150.0); // 500hz period + speaker =0.25; //25% duty cycle - mid range volume + wait(.02); + speaker=0.0; // turn off audio + wait(0.5); + return 1; + } + else if(item->type == ROLLING && item2 == NULL) + { + map_erase(x,y-1); + add_rolling(x,y-2); + Player.y--; + return 1; + } + return 0; +} + +int go_down(int x, int y, int i) +{ + MapItem *item = get_south(x, y); + MapItem *item2 = get_south(x, y+1); + if((item->walkable && item->type != PLANT2) || Player.omnipotent) + { + if((i && item2->walkable && item2->type != PLANT2) || Player.omnipotent) + { + Player.y = Player.y + 2; + return RUN; + } + Player.y++; + return 1; + } + else if(item->type == PLANT2) + { + Player.health--; + speaker.period(1.0/150.0); // 500hz period + speaker =0.25; //25% duty cycle - mid range volume + wait(.02); + speaker=0.0; // turn off audio + wait(0.5); + return 1; + } + else if(item->type == ROLLING && item2 == NULL) + { + map_erase(x,y+1); + add_rolling(x,y+2); + Player.y++; + return 1; + } + return 0; +} + +int go_left(int x, int y, int i) +{ + MapItem *item = get_west(x, y); + MapItem *item2 = get_west(x-1,y); + if((item->walkable && item->type != PLANT2) || Player.omnipotent) + { + if((i && item2->walkable && item2->type != PLANT2) || Player.omnipotent) + { + Player.x = Player.x - 2; + return RUN; + } + Player.x--; + return 1; + } + else if(item->type == PLANT2) + { + Player.health--; + speaker.period(1.0/150.0); // 500hz period + speaker =0.25; //25% duty cycle - mid range volume + wait(.02); + speaker=0.0; // turn off audio + wait(0.5); + return 1; + } + else if(item->type == ROLLING && item2 == NULL) + { + map_erase(x-1,y); + add_rolling(x-2,y); + Player.x--; + return 1; + } + return 0; +} + +int go_right(int x, int y, int i) +{ + MapItem *item = get_east(x, y); + MapItem *item2 = get_east(x+1, y); + if((item->walkable && item->type != PLANT2) || Player.omnipotent) + { + if((i && item2->walkable && item2->type != PLANT2) || Player.omnipotent) + { + Player.x = Player.x + 2; + return RUN; + } + Player.x++; + return 1; + } + else if(item->type == PLANT2) + { + Player.health--; + speaker.period(1.0/150.0); // 500hz period + speaker =0.25; //25% duty cycle - mid range volume + wait(.02); + speaker=0.0; // turn off audio + wait(0.5); + return 1; + } + else if(item->type == ROLLING && item2 == NULL) + { + map_erase(x+1,y); + add_rolling(x+2,y); + Player.x++; + return 1; + } + return 0; +} + +int interact(int x, int y) +{ + MapItem *north = get_north(x,y); + MapItem *south = get_south(x,y); + MapItem *east = get_east(x,y); + MapItem *west = get_west(x,y); + if(north->type == STARTNPC || south->type == STARTNPC || east->type == STARTNPC || west->type == STARTNPC) + { + if(Player.has_platebody) + { + speech(questHasPlatebody1, questHasPlatebody2, questHasPlatebody3, questHasPlatebody4); + finished = 1; + return 1; + } + else if(!Player.has_platebody && Player.has_key) + { + speech("Search the", "treasure room", "first! Then", "come talk"); + return 1; + } + else if(Player.has_sword) + { + speech(questHasSword1, "", "", ""); + return 1; + } + else if(Player.has_shield ) + { + speech(questHasShield1, questHasShield2, questHasShield3, ""); + return 1; + } + else + { + speech(questStartLine1, questStartLine2, questStartLine3, questStartLine4); + speech(questStartLine5, questStartLine6, questStartLine7, questStartLine8); + speech(questStartLine9, questStartLine10, questStartLine11, questStartLine12); + speech(questStartLine13, questStartLine14, questStartLine15, questStartLine16); + speech(questStartLine17, questStartLine18, questStartLine19, questStartLine20); + speech(questStartLine21, questStartLine22, questStartLine23, questStartLine24); + speech(questStartLine25, questStartLine26,"",""); + Player.has_shield = 1; + return 1; + } + } + else if(north->type == CAVE || south->type == CAVE || east->type == CAVE || west->type == CAVE) + { + if(mapToggle == 0) + { + mapToggle = !mapToggle; + set_active_map(1); + Player.x = 5; + Player.y = 5; + } + else + { + mapToggle = !mapToggle; + set_active_map(0); + Player.x = 39; + Player.y = 4; + } + return 1; + } + else if(north->type == SWORDINSTONE || south->type == SWORDINSTONE || east->type == SWORDINSTONE || west->type == SWORDINSTONE) + { + if(Player.has_shield) + { + Player.has_sword = 1; + speech(findSword1, findSword2, "", ""); + map_erase(15,15); + draw_plant(15,15); + } + else + { + speech("You should", "talk to the man", "where you started", "first"); + } + return 1; + } + else if(north->type == ELVARG || south->type == ELVARG || east->type == ELVARG || west->type == ELVARG) + { + speech(elvarg1, elvarg2, "", ""); + if(!Player.has_shield) + { + speech(elvarg3a1, elvarg3a2, elvarg3a3, ""); + Player.health = Player.health - 10; + return 1; + } + else if(!Player.has_sword) + { + speech(elvarg3b1, elvarg3b2, elvarg3b3, elvarg3b4); + speech(elvarg3b5, "", "", ""); + Player.health = Player.health - 9; + return 1; + } + else + { + Player.has_key = 1; + speech(elvarg3c1, elvarg3c2, elvarg3c3, elvarg3c4); + speech(elvarg3c5, elvarg3c6, elvarg3c7, ""); + map_erase(10,10); + Player.health = Player.health - 3; + return 1; + } + } + else if(north->type == GATE || south->type == GATE || east->type == GATE || west->type == GATE) + { + if(Player.has_key) + { + speech("You unlock the", "gate with the key", "", ""); + map_erase(10,45); + return 1; + } + else + { + speech("Requires Elvarg's", "key to open", "", ""); + return 1; + } + } + else if(north->type == TREASURE || south->type == TREASURE || east->type == TREASURE || west->type == TREASURE) + { + Player.has_platebody = 1; + speech("You are amazed", "to find a", "legendary rune", "platebody."); + speech("you equip the", "legendary armor.", "Time to return", "to that weird"); + speech("guy. His request", "has been", "fulfilled.", ""); + return 1; + } + else if(north->type == PHAT || south->type == PHAT || east->type == PHAT || west->type == PHAT) + { + if(Player.num_phats == 0) + speech("find all 5", "hidden party", "hats!", ""); + Player.num_phats++; + if(Player.num_phats == 5) + { + speech("you found all", "5 party hats!", "You are very", "special!"); + } + if(north->type == PHAT) + map_erase(x, y-1); + if(south->type == PHAT) + map_erase(x, y+1); + if(east->type == PHAT) + map_erase(x+1, y); + if(west->type == PHAT) + map_erase(x-1, y); + return 1; + } + + return 0; +} + +int NPC_move(int x, int y) +{ + if(!((Player.x == (7+!walk)) && (Player.y == 7)) && (map_width() == 50)) + { + wait_ms(200); + map_erase(7+walk, 7); + walk = !walk; + add_startNPC(7+walk,7); + wait_ms(200); + return FULL_DRAW; + } + return 0; +} + /** * 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 @@ -78,7 +547,24 @@ * drawing tiles that have changed from the previous frame. */ void draw_game(int init) -{ +{ + if(init == BAD_END) + { + speaker.period(1.0/150.0); // 500hz period + speaker =0.25; //25% duty cycle - mid range volume + wait(.5); + speaker=0.0; // turn off audio + wait(0.5); + draw_bad(); + wait(10000); + } + if(init == GOOD_END) + { + draw_good(); + wait(10000); + } + + // Draw game border first if(init) draw_border(); @@ -103,9 +589,21 @@ // Figure out what to draw DrawFunc draw = NULL; - if (init && i == 0 && j == 0) // Only draw the player on init + if (init && i == 0 && j == 0 && get_here(Player.x, Player.y)->walkable != 2) // Only draw the player on init { - draw_player(u, v, Player.has_key); + if(init == RUN) + { + draw_player(u,v,4); + wait_ms(100); + } + if(Player.has_platebody) + draw_player(u, v, 3); + else if(Player.has_sword) + draw_player(u, v, 2); + else if(Player.has_shield) + draw_player(u ,v, 1); + else + draw_player(u ,v, 0); continue; } else if (x >= 0 && y >= 0 && x < map_width() && y < map_height()) // Current (i,j) in the map @@ -135,8 +633,8 @@ } // Draw status bars - draw_upper_status(); - draw_lower_status(); + draw_upper_status(Player.x,Player.y); + draw_lower_status(Player.health, Player.num_phats); } @@ -161,6 +659,59 @@ add_wall(map_width()-1, 0, VERTICAL, map_height()); pc.printf("Walls done!\r\n"); + //draw in treasure room + add_wall(6, 45, VERTICAL, 4); + add_wall(7, 45, HORIZONTAL, 3); + add_gate(10,45); + add_wall(11, 45, HORIZONTAL, 3); + add_wall(14, 45, VERTICAL, 4); + + + add_startNPC(7,7); + pc.printf("NPCs!\r\n"); + + add_boulder(3,3); + + add_cave(40,4); + pc.printf("Cave!\r\n"); + add_rolling(39,4); + add_rolling(41,4); + add_rolling(40,5); + add_rolling(40,3); + + add_treasure(10,47); + pc.printf("Treasure!\r\n"); + + add_phat(45,45); + add_phat(25,25); + add_phat(10,48); + + print_map(); +} + +void init_second_map() +{ + // "Random" plants + Map* map = set_active_map(1); + for(int i = map_width() + 3; i < map_area(); i += 39) + { + add_plant2(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"); + + //add sprites + add_cave(4,5); + add_elvarg(10,10); + add_swordInStone(15,15); + add_phat(3,10); + add_phat(10,17); print_map(); } @@ -175,17 +726,31 @@ // First things first: initialize hardware ASSERT_P(hardware_init() == ERROR_NONE, "Hardware init failed!"); + draw_start(); + // Initialize the maps maps_init(); + init_second_map(); init_main_map(); // Initialize game state set_active_map(0); Player.x = Player.y = 5; + Player.has_key = 0; + Player.has_sword = 0; + Player.has_shield = 0; + Player.has_platebody = 0; + Player.health = 10; // Initial drawing + uLCD.filled_rectangle(0, 0, 127, 8, BLACK); + uLCD.filled_rectangle(0, 119, 127, 127, BLACK); draw_game(true); - + + // Variables + GameInputs in; + int action; + int draw; // Main game loop while(1) { @@ -193,11 +758,15 @@ Timer t; t.start(); // Actuall do the game update: - // 1. Read inputs - // 2. Determine action (get_action) + // 1. Read inputs + in = read_inputs(); + // 2. Determine action (get_action) + action = get_action(in); // 3. Update game (update_game) + draw = update_game(action); // 3b. Check for game over // 4. Draw frame (draw_game) + draw_game(draw); // 5. Frame delay t.stop();