#include #include #include #include #include #include /************* STATIC DEFINITIONS ************/ // Game constants #define ENEMY_N 5 #define BULLET_N 3 #define LIVES_N 5 // Window constants #define DELAY 30000 #define WIDTH 52 #define HEIGHT 30 #define MIN_COLS 110 // Aspect constatnts #define TEXTLINES 4 #define BORDERLINES 2 #define ENEMY_PAIR 1 #define BONUS_PAIR 2 #define TITLE_PAIR 3 #define GMOVR_PAIR 4 /************* GAME STRUCTURES **************/ struct speed { int slowness; int count; }; struct game_obj { char symbol; int x, y; int active; struct speed y_speed; }; struct status { int lives; int score; int top_score; int remaining_bullets; }; /************** FUNZIONI GUI ***************/ char* title[] = { "###########################################################################################################", "# o8888o o8888o o8888o o8888o o8888o o8888o o8 80 o8888o o8888o o8888o o8888o o8888o #", "# 888o 0oooo0 88 888 88 88oo oo 888o 888o88 88 888 88 888 88 88oo 88oo88 #", "# o888 88 888888 88 88 o888 88 88 88 888 88 888 88 88 88 88 #", "# 088880 88 88 88 888880 088888 088880 08 80 088880 088880 00 088888 88 88o #", "###########################################################################################################" }; char menu_desc[] = "BENVENUTO. Premi qualsiasi tasto per giocare..."; char* gameover[] = { "o8888o o8888o o8oo8o o8888o o8888o 88 8o o8888o o8888o", "888 oo 88 888 88\\/88 88oo oo 88 888 88 88 88oo 88oo88", "888 8 888888 88 88 88 88 888 88 o8 88 88 88 ", "O88880 88 88 88 88 888880 088880 888O 888880 88 88o" }; char gameover_desc[] = "HAI PERSO. Premi q per uscire..."; void print_menu(WINDOW* win) { // Ottieni parametri della finestra int height; int width; getmaxyx(win, height, width); // Scritta colorata wattron(win, COLOR_PAIR(TITLE_PAIR)); for(int i = 0; i < (TEXTLINES+BORDERLINES); i++) { mvwprintw(win, i+1, (width-(strlen(title[0])))/2, "%s", title[i]); } wattroff(win, COLOR_PAIR(TITLE_PAIR)); // Scritta che blinka wattron(win, A_BLINK); mvwprintw(win, (TEXTLINES+BORDERLINES)+1, (width-(strlen(menu_desc)))/2, "%s", menu_desc); wattroff(win, A_BLINK); // stampa a video refresh(); return; } void print_gameover(WINDOW* win) { // Parametri della finestra e pulisci tutto int height; int width; int ch; wclear(win); getmaxyx(win, height, width); // Stampa della scritta colorata wattron(win, COLOR_PAIR(GMOVR_PAIR)); for(int i = 0; i < TEXTLINES; i++) { mvwprintw(win, i+1, (width-(strlen(gameover[0])))/2, "%s", gameover[i]); } wattroff(win, COLOR_PAIR(GMOVR_PAIR)); // Stampa della scritta che blinka wattron(win, A_BLINK); mvwprintw(win, TEXTLINES+1, (width-(strlen(gameover_desc)))/2, "%s", gameover_desc); wattroff(win, A_BLINK); // Stampa a video e attendi input refresh(); while((ch = wgetch(win)) != 'q'); return; } void print_status_bar(WINDOW* main_win, int y, int x, struct status game_status) { int status_x = x + 1; int status_y = y; status_x++; // lives mvwprintw(main_win, status_y, status_x, "LIVES:\t%d", game_status.lives); // score mvwprintw(main_win, status_y+1, status_x, "SCORE:\t%d", game_status.score); // top score mvwprintw(main_win, status_y+2, status_x, "TOP SCORE:\t%d", game_status.top_score); // bullets mvwprintw(main_win, status_y+3, status_x, "BULLETS:\t%d", game_status.remaining_bullets); // refresh window wrefresh(main_win); return; } int main() { /************ VARIABILI **************/ WINDOW *game_window; int height, width, win_startx, win_starty; char *pause_msg = "PAUSA: premi q per uscire dal gioco..."; int pause = 0; int auto_shoot = 0; // Giocatore struct game_obj player = {}; int input; // Status struct status game_status = {}; game_status.top_score = 0; game_status.score = 0; game_status.lives = LIVES_N; game_status.remaining_bullets = BULLET_N; // Proiettile struct game_obj bullet[BULLET_N] = {}; int bullet_attivi = 0; int next_bullet = 0; // Nemici struct game_obj enemy[ENEMY_N] = {}; /**************** INIZIALIZZAZIONE ***************/ initscr(); cbreak(); noecho(); keypad(stdscr, TRUE); curs_set(0); srand(time(NULL)); // Colori start_color(); init_pair(ENEMY_PAIR, COLOR_RED, COLOR_BLACK); init_pair(TITLE_PAIR, COLOR_MAGENTA, COLOR_BLACK); init_pair(GMOVR_PAIR, COLOR_RED, COLOR_BLACK); init_pair(BONUS_PAIR, COLOR_GREEN, COLOR_BLACK); // Dimensioni finestra di gioco e controlli // calcolo delle misure della finestra height = HEIGHT; width = WIDTH - (WIDTH%4); win_startx = (COLS - width)/2; win_starty = (LINES - height)/2; // Schermo troppo piccolo ? if(COLS < MIN_COLS || LINES < HEIGHT) { curs_set(1); endwin(); printf("Gioco terminato.\n"); printf("Schermo troppo piccolo \n"); return 0; } // MENU print_menu(stdscr); getch(); werase(stdscr); mvprintw(1, 1, "p per pausa, q per uscire"); refresh(); // GAME WINDOW game_window = newwin(height, width, win_starty, win_startx); nodelay(game_window, TRUE); // input non bloccante keypad(game_window, TRUE); box(game_window, 0, 0); wrefresh(game_window); // setup giocatore player.symbol = 'A'; player.x = width / 2; player.y = height - 2; player.active = 1; // setup proiettili for(int i = 0; i < BULLET_N; i++) { bullet[i].symbol = '*'; bullet[i].active = 0; } // setup dei nemici for(int i = 0; i < ENEMY_N; i++) { enemy[i].symbol = 'Q'; enemy[i].active = 0; enemy[i].y_speed.slowness = 7; enemy[i].y_speed.count = 0; } //********************* GAME LOOP ***********************/ while (player.active) { // TODO if pausa all'inizio e continue input = wgetch(game_window); // Gestione input if (input == KEY_RIGHT && !pause && player.x < width - 2) { player.x += 2; } else if (input == KEY_LEFT && !pause && player.x > 2) { player.x -= 2; } else if (!auto_shoot && input == ' ' && bullet_attivi < BULLET_N && !pause) { bullet[next_bullet].x = player.x; bullet[next_bullet].y = player.y - 1; bullet[next_bullet].active = 1; } else if (input == 'p') { pause = !pause; } else if (input == 'q') { player.active = 0; } else if (input == 'g') { auto_shoot= !auto_shoot; } if (auto_shoot && bullet_attivi < BULLET_N && !pause) { bullet[next_bullet].x = player.x; bullet[next_bullet].y = player.y - 1; bullet[next_bullet].active = 1; } // Aggiorna proiettile for(int i = 0; i< BULLET_N; i++) { if (bullet[i].active && !pause) { bullet[i].y--; } if (bullet[i].y < 1) { bullet[i].active = 0; } } // Collisioni 1 for(int j = 0; j < BULLET_N; j++) { if(bullet[j].active && !pause) { for(int i = 0; i < ENEMY_N; i++) { if(bullet[j].x == enemy[i].x && bullet[j].y == enemy[i].y) { enemy[i].active = 0; bullet[j].active = 0; game_status.score++; } } } } // Spawna nemici for(int i = 0; !pause && i < ENEMY_N; i++) { if(!enemy[i].active && !pause) { enemy[i].y = 2; enemy[i].x = (rand()%((width-4)/2))*2 + 2; enemy[i].active = 1; break; } } // Aggiorna posizione nemici for(int i = 0; !pause && i < ENEMY_N; i++) { if(enemy[i].active && !pause) { enemy[i].y_speed.count++; if(enemy[i].y_speed.count > enemy[i].y_speed.slowness) { enemy[i].y++; enemy[i].y_speed.count = 0; } if(enemy[i].y > height - 2) { enemy[i].active = 0; game_status.lives--; if(game_status.lives == 0) { player.active = 0; print_gameover(stdscr); } } } } // Collisioni 2 for(int j = 0; j < BULLET_N; j++) { if(bullet[j].active && !pause) { for(int i = 0; i < ENEMY_N; i++) { if(bullet[j].x == enemy[i].x && bullet[j].y == enemy[i].y) { enemy[i].active = 0; bullet[j].active = 0; game_status.score++; } } } } // Conteggio proiettili bullet_attivi = 0; next_bullet = -1; for (int i = 0; i < BULLET_N; i++) { if (bullet[i].active) { bullet_attivi++; } else if (i < next_bullet || next_bullet == -1) { next_bullet = i; } } game_status.remaining_bullets = BULLET_N - bullet_attivi; // Disegna scena werase(game_window); box(game_window, 0, 0); if (pause) { wattron(game_window, A_REVERSE); mvwprintw(game_window, height/2, (width - strlen(pause_msg)) / 2, "%s", pause_msg); wattroff(game_window, A_REVERSE); } else { // Giocatore mvwprintw(game_window, player.y, player.x, "%c", player.symbol); // Proiettile for(int i = 0; i < BULLET_N; i++) { if (bullet[i].active) mvwprintw(game_window, bullet[i].y, bullet[i].x, "%c", bullet[i].symbol); } // Nemici for(int i = 0; i < ENEMY_N; i++) { wattron(game_window, COLOR_PAIR(1)); if (enemy[i].active) mvwprintw(game_window, enemy[i].y, enemy[i].x, "%c", enemy[i].symbol); wattroff(game_window, COLOR_PAIR(1)); } // Status Bar print_status_bar(stdscr, win_starty, (win_startx + width), game_status); } wrefresh(game_window); usleep(DELAY); } /***************** CHIUSURA *****************/ delwin(game_window); curs_set(1); endwin(); printf("Gioco terminato.\n"); return 0; }