#include #include #include #include #include #include #define DELAY 30000 #define ENEMY_N 5 #define BULLET_N 3 #define WIDTH 52 #define HEIGHT 30 #define MIN_COLS 110 struct speed { int slowness; int count; }; struct game_obj { char symbol; int x, y; int active; struct speed y_speed; }; /************** FUNZIONI GUI ***************/ #define TITLE_LINES 6 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 un tasto qualsiasi per giocare..."; void print_menu(WINDOW* win) { int height; int width; getmaxyx(win, height, width); for(int i = 0; i < TITLE_LINES; i++) { mvwprintw(win, i+1, (width-(strlen(title[0])))/2, "%s", title[i]); } wattron(win, A_BLINK); mvwprintw(win, TITLE_LINES+1, (width-(strlen(menu_desc)))/2, "%s", menu_desc); wattroff(win, A_BLINK); refresh(); getch(); 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; // 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)); // 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) { delwin(game_window); curs_set(1); endwin(); printf("Gioco terminato.\n"); printf("Schermo troppo piccolo \n"); return 0; } // MENU print_menu(stdscr); 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; // TODO aggiorna punteggio } } } } // 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; // TODO aggiorna punteggio } } } // 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; // TODO aggiorna punteggio } } } } // 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; } } // 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++) { if (enemy[i].active) mvwprintw(game_window, enemy[i].y, enemy[i].x, "%c", enemy[i].symbol); } } wrefresh(game_window); usleep(DELAY); } /***************** CHIUSURA *****************/ delwin(game_window); curs_set(1); endwin(); printf("Gioco terminato.\n"); return 0; }