#include "bullet.hpp" #include "enemy.hpp" #include "player.hpp" #include "box.hpp" #include "boss.hpp" #include "powerup.hpp" #include "definitions.hpp" #include "functions.hpp" #include "wall.hpp" using std::cout; using std::endl; using std::min; int main() { typedef std::list b_list; typedef std::list e_list; typedef std::vector w_vec; srand(time(NULL)); //OBJECTS INIZIALIZATION Box box1; player player1; //player is automatically created in [C/2][R] e_list enemies; //vector of enemies b_list bullets; //list of player's bullets b_list bombs; //list of enemies' bombs b_list powerups; //list of powerups int refresh_time; //how long the program waits before refreshing the screen int chflag=0; //cheat flag: 0=normal, 1=cheats allowed, 2=special mode activated, 3=both special mode and cheats. boss boss1; WINDOW *Score,*BossHP; //PARAMETERS/UTILITIES double shootrate; //probability of an enemy shooting a bomb int command; //keyboard input int score=0; //score: gain +100 when an enemy is destroyed and +50 when a bomb is destroyed char level='1'; bool sound=true; //difficulty level //NCURSES STUFF initscr(); curs_set(0); noecho(); cbreak(); keypad(stdscr,TRUE); start_color(); init_pair(0,COLOR_WHITE,COLOR_BLACK); init_pair(1,COLOR_GREEN,COLOR_BLACK); //PLAYER init_pair(2,COLOR_RED,COLOR_BLACK); //ENEMY init_pair(3,COLOR_YELLOW,COLOR_BLACK); //BULLETS-POWERUPS init_pair(4,COLOR_MAGENTA,COLOR_BLACK); //WALLS init_pair(5,COLOR_CYAN,COLOR_BLACK); //BOSS init_pair(6,COLOR_BLUE,COLOR_BLACK); //BOMBS init_pair(7,COLOR_RED,COLOR_RED); init_pair(8,COLOR_GREEN,COLOR_GREEN); //////////PROGRAM START: creation of game objects and set of parameters WALLS_NUM=2; ENEMY_NUM=choose_level(shootrate, refresh_time, boss1, level); //choose difficulty level and set game parameters and boss erase(); if(atoi(&level)==1) WALLS_NUM=3; w_vec walls(WALLS_NUM); Score=newwin(3,10,R/3,C+3); BossHP=newwin(3,15,R/3-3,C+3); load_enemies(enemies,ENEMY_NUM); int i=0; for(w_vec::iterator it=walls.begin(); it!=walls.end(); ++it, ++i) //creating walls (in a quite symmetric pattern) it->create((i+1)*(C/(3*WALLS_NUM+1))+i*(2*C/(3*WALLS_NUM+1)),2*R/3,(int)min(6,2*C/(3*WALLS_NUM+1)),2,3); box1.refresh(bullets, bombs, enemies, player1, score, boss1, walls, powerups); //matrix is loaded for the first time /////////ENTERING MAIN LOOP int childPID0=fork(); if(childPID0==0 && sound){ music(); return 0; } while(1) { napms(refresh_time); //ncurses sleep function (ms) timeout(0); command = getch(); if(command!=ERR) //READING INPUT command = tolower(command); if(command == 'q'){ //q = exit game endwin(); kill_music(childPID0); cout<1) player1.weaponclass--; //decrease weaponclass if(command == '-' && player1.length>2){ //decrease size mvaddch(player1.y,player1.x+player1.length-1,' '); player1.length--; } if(command == '\'' && player1.length<20) player1.length++; //increase size if(command == 'n') //nuke enemies for(e_list::iterator it=enemies.begin();it!=enemies.end();it++){ it->alive=false; mvaddch(it->y,it->x,' '); } } if(chflag!=2 && chflag!=3) get_KonamiCode(command,chflag,boss1,enemies,bullets,bombs,powerups,box1); if(command == 'a' || command == KEY_LEFT || command == 'd' || command == KEY_RIGHT || ((command == 'w'|| command == KEY_UP || command == 's' || command == KEY_DOWN) && (chflag==1 || chflag==3))){ //a or d = move player (if cheats are triggered, also w and s) for(int i=player1.x;ialive) n_enemies++; //counts alive enemies for(e_list::iterator it=enemies.begin(); it!=e_end; ++it) { mvaddch(it->y,it->x,' '); it->next_pos(); //evaluate new positions if(it->alive && (double)rand()/RAND_MAX<(shootrate*ENEMY_NUM/n_enemies)){ //try a bomb-dropping if(sound){ int childPID=fork(); if(childPID==0){ system("beep -f 1500 -l 30 -n -f 1000 -l 30"); return 0; } } it->shoot(bombs); } } } else boss1.alive = true; //if no enemy is alive, boss spawns if(boss1.alive) //if boss is alive, moves and shoots { for(int i=0;iy,it->x,' '); it->next_pos(); } bullets.unique(); //remove duplicates of bullets (i.e. player can't shoot enemies) if(!bombs.empty()) //evaluate new bombs' positions for(b_list::iterator it=bombs.begin(); it!=bombs.end(); ++it){ mvaddch(it->y,it->x,' '); it->next_pos(); } bombs.unique(); //remove duplicates of bombs if(!powerups.empty()) //new powerups' positions for(b_list::iterator it=powerups.begin(); it!=powerups.end(); ++it){ mvaddch(it->y,it->x,' '); it->next_pos(); } powerups.unique(); //FIXME: THIS ONLY WORKS ON CONSECUTIVE ELEMENTS OF THE LIST!! we should at least sort powerups before calling unique() box1.refresh(bullets, bombs, enemies, player1, score, boss1, walls, powerups); ///////ENDGAME CHECKS if(boss1.health<1) //YOU WON!! { if(sound){ kill_music(childPID0); int childPID=fork(); if(childPID==0){ system("beep -f 1000 -l 150 -n -f 800 -l 150 -n -f 1000 -l 150 -n -f 1500 -l 600"); return 0; } } Victory(boss1.name,score,level,chflag); WINDOW *replay; replay=newwin(3,25,26,20); box(replay,ACS_VLINE,ACS_HLINE); if(playagain(replay)) //playagain() returns true if player wants to play again, false otherwise { delwin(replay); timeout(500); score=0; erase(); refresh(); choose_level(shootrate, refresh_time, boss1, level); reset(box1, player1, enemies, boss1, bullets, bombs, walls, powerups, level,chflag); // reset box, player, enemy and deletes all bullets and bombs erase(); refresh(); continue; } else { endwin(); cout<