diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..5bef432 --- /dev/null +++ b/Makefile @@ -0,0 +1,26 @@ +CC = gcc +CFLAGS = -Wall -Wextra -Iinclude -std=c11 +LDFLAGS = -lncurses + +SRC = $(wildcard src/*.c) +OBJ = $(patsubst src/%.c, build/%.o, $(SRC)) +TARGET = build/space_shooter + +all: $(TARGET) + +build: + mkdir -p build + +build/%.o: src/%.c | build + $(CC) $(CFLAGS) -c $< -o $@ + +$(TARGET): $(OBJ) | build + $(CC) $(OBJ) -o $@ $(LDFLAGS) + +clean: + rm -rf build + +run: all + ./$(TARGET) + +.PHONY: all clean run diff --git a/README.md b/README.md index 249f3d1..b99741e 100644 --- a/README.md +++ b/README.md @@ -4,4 +4,4 @@ > cd space-shooter/ -> gcc -o /build/shooter src/main.c src/gui.c -lncurses \ No newline at end of file +> make \ No newline at end of file diff --git a/build/game.o b/build/game.o new file mode 100644 index 0000000..8ee3cbf Binary files /dev/null and b/build/game.o differ diff --git a/build/gui.o b/build/gui.o new file mode 100644 index 0000000..1c5a1ef Binary files /dev/null and b/build/gui.o differ diff --git a/build/input.o b/build/input.o new file mode 100644 index 0000000..146eea8 Binary files /dev/null and b/build/input.o differ diff --git a/build/logic.o b/build/logic.o new file mode 100644 index 0000000..840ee2a Binary files /dev/null and b/build/logic.o differ diff --git a/build/main.o b/build/main.o new file mode 100644 index 0000000..7d1b69d Binary files /dev/null and b/build/main.o differ diff --git a/build/objects.o b/build/objects.o new file mode 100644 index 0000000..851afdc Binary files /dev/null and b/build/objects.o differ diff --git a/build/space_shooter b/build/space_shooter new file mode 100755 index 0000000..1d636f9 Binary files /dev/null and b/build/space_shooter differ diff --git a/build/utils.o b/build/utils.o new file mode 100644 index 0000000..2a2d079 Binary files /dev/null and b/build/utils.o differ diff --git a/include/game.h b/include/game.h new file mode 100644 index 0000000..0fe58ae --- /dev/null +++ b/include/game.h @@ -0,0 +1,9 @@ +#ifndef GAME_H +#define GAME_H + +#include "objects.h" + +/* Run the main game. Returns 0 on clean exit. */ +int game_run(void); + +#endif /* GAME_H */ diff --git a/include/gui.h b/include/gui.h index 26b7259..34426ed 100644 --- a/include/gui.h +++ b/include/gui.h @@ -2,23 +2,26 @@ #define GUI_H #include -#include -#include +#include "objects.h" +#include "utils.h" -// Aspect constatnts -#define TEXTLINES 4 -#define BORDERLINES 2 +/* color pair ids for gui.c */ +enum { + ENEMY_PAIR = 1, + TITLE_PAIR, + GMOVR_PAIR, + BONUS_PAIR, + WINSC_PAIR +}; -#define ENEMY_PAIR 1 -#define BONUS_PAIR 2 -#define TITLE_PAIR 3 -#define GMOVR_PAIR 4 -#define WINSC_PAIR 5 - -void init_colors(); +/* initialization and screens */ +void init_colors(void); void print_menu(WINDOW* win); void print_gameover(WINDOW* win); void print_win_screen(WINDOW* win); +/* status bar (draws into stdscr or another window) */ +void print_status_bar(WINDOW* main_win, int y, int x, struct status game_status); + +#endif /* GUI_H */ -#endif \ No newline at end of file diff --git a/include/input.h b/include/input.h new file mode 100644 index 0000000..3d35614 --- /dev/null +++ b/include/input.h @@ -0,0 +1,18 @@ +#ifndef INPUT_H +#define INPUT_H + +#include +#include "objects.h" +#include "utils.h" + +/* Process a single key code and apply to game state. + Returns 1 if game should continue, 0 if quit (player inactive). */ +int process_input(int input, + int *pause, + int *auto_shoot, + struct game_obj *player, + struct game_obj bullets[], + int bullet_attivi, + int *next_bullet); + +#endif /* INPUT_H */ diff --git a/include/logic.h b/include/logic.h new file mode 100644 index 0000000..6323722 --- /dev/null +++ b/include/logic.h @@ -0,0 +1,16 @@ +#ifndef LOGIC_H +#define LOGIC_H + +#include "objects.h" +#include "utils.h" +#include + +/* Logic functions used by the game loop */ +void update_bullets(struct game_obj bullets[]); +void handle_collisions(struct game_obj bullets[], struct game_obj enemies[], struct status *game_status, WINDOW *win); +void spawn_enemies(struct game_obj enemies[], int width); +void update_enemies(struct game_obj enemies[], struct status *game_status, int height, WINDOW *win); + +void count_bullets(const struct game_obj bullets[], int *bullet_attivi, int *next_bullet, struct status *game_status); + +#endif /* LOGIC_H */ diff --git a/include/objects.h b/include/objects.h new file mode 100644 index 0000000..44bceff --- /dev/null +++ b/include/objects.h @@ -0,0 +1,31 @@ +#ifndef OBJECTS_H +#define OBJECTS_H + +#include "utils.h" + +/* speed, game_obj, status definitions */ +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; +}; + +/* constructors / initializers */ +void init_player(struct game_obj *player, int win_width, int win_height); +void init_bullets(struct game_obj bullets[]); +void init_enemies(struct game_obj enemies[]); + +#endif /* OBJECTS_H */ diff --git a/include/utils.h b/include/utils.h new file mode 100644 index 0000000..927fdac --- /dev/null +++ b/include/utils.h @@ -0,0 +1,18 @@ +#ifndef UTILS_H +#define UTILS_H + +/* Window/constants shared across modules */ +#define DELAY 30000 +#define ENEMY_N 5 +#define BULLET_N 3 +#define LIVES_N 5 +#define WIN_PTS 100 + +#define WIDTH 52 +#define HEIGHT 30 +#define MIN_COLS 110 + +#define TEXTLINES 4 +#define BORDERLINES 2 + +#endif /* UTILS_H */ diff --git a/src/game.c b/src/game.c new file mode 100644 index 0000000..d351a2e --- /dev/null +++ b/src/game.c @@ -0,0 +1,127 @@ +#include "../include/game.h" +#include "../include/gui.h" +#include "../include/input.h" +#include "../include/logic.h" +#include "../include/objects.h" +#include "../include/utils.h" + +#include +#include +#include +#include +#include +#include + +/* main game runner */ +int game_run(void) { + WINDOW *game_window = NULL; + int height, width, win_startx, win_starty; + char *pause_msg = "PAUSA: premi q per uscire dal gioco..."; + int pause = 0; + int auto_shoot = 0; + + struct game_obj player = {}; + int input = 0; + + struct status game_status = {}; + game_status.top_score = 0; + game_status.score = 0; + game_status.lives = LIVES_N; + game_status.remaining_bullets = BULLET_N; + + struct game_obj bullet[BULLET_N] = {}; + int bullet_attivi = 0; + int next_bullet = -1; + + struct game_obj enemy[ENEMY_N] = {}; + + /* seed */ + srand((unsigned)time(NULL)); + + /* Dimensioni finestra di gioco */ + height = HEIGHT; + width = WIDTH - (WIDTH%4); + win_startx = (COLS - width)/2; + win_starty = (LINES - height)/2; + + if(COLS < MIN_COLS || LINES < HEIGHT) { + printf("Gioco terminato.\nSchermo troppo piccolo\n"); + return 0; + } + + /* show menu */ + print_menu(stdscr); + getch(); + werase(stdscr); + mvprintw(1, 1, "p per pausa, q per uscire"); + refresh(); + + /* create windows */ + game_window = newwin(height, width, win_starty, win_startx); + nodelay(game_window, TRUE); + keypad(game_window, TRUE); + box(game_window, 0, 0); + wrefresh(game_window); + + /* setup objects */ + init_player(&player, width, height); + init_bullets(bullet); + init_enemies(enemy); + + while (player.active) { + input = wgetch(game_window); + + if (!process_input(input, &pause, &auto_shoot, &player, bullet, bullet_attivi, &next_bullet)) { + player.active = 0; + break; + } + + if (!pause) update_bullets(bullet); + if (!pause) handle_collisions(bullet, enemy, &game_status, stdscr); + if (!pause && game_status.score >= WIN_PTS) { + player.active = 0; + print_win_screen(stdscr); + break; + } + + if (!pause) spawn_enemies(enemy, width); + if (!pause) update_enemies(enemy, &game_status, height, stdscr); + if (!pause && game_status.lives <= 0) { + player.active = 0; + print_gameover(stdscr); + break; + } + + count_bullets(bullet, &bullet_attivi, &next_bullet, &game_status); + + /* draw */ + werase(game_window); + box(game_window, 0, 0); + + if (pause) { + wattron(game_window, A_REVERSE); + mvwprintw(game_window, height/2, (width - (int)strlen(pause_msg)) / 2, "%s", pause_msg); + wattroff(game_window, A_REVERSE); + } else { + mvwprintw(game_window, player.y, player.x, "%c", player.symbol); + + 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); + + wattron(game_window, COLOR_PAIR(ENEMY_PAIR)); + 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); + wattroff(game_window, COLOR_PAIR(ENEMY_PAIR)); + + print_status_bar(stdscr, win_starty, (win_startx + width), game_status); + } + + wrefresh(game_window); + usleep(DELAY); + } + + if (game_window) delwin(game_window); + + /* note: no endwin(), no curs_set(1) here */ + return 0; +} diff --git a/src/gui.c b/src/gui.c index 6821549..009b69d 100644 --- a/src/gui.c +++ b/src/gui.c @@ -1,4 +1,5 @@ #include "../include/gui.h" +#include /************** FUNZIONI GUI ***************/ @@ -10,7 +11,7 @@ char* title[] = "# 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..."; @@ -28,7 +29,7 @@ char gameover_desc[] = "HAI PERSO. Premi q per uscire..."; char* win_screen[] = { "o8 o8 o8888o o8 8o o8 8o o8888o o8 8o", -"88 o8 88 888 88 88 oo 88 88 88 888o88", +"88 o8 88 888 88 88 oo 88 88 88 888o88", "888 88 888 88 88 88/\\88 88 88 888", "888 088880 088880 8888 088880 88 88" }; @@ -45,76 +46,78 @@ void init_colors() { } 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(); + wrefresh(win); 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(); + wrefresh(win); while((ch = wgetch(win)) != 'q'); return; } void print_win_screen(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(WINSC_PAIR)); for(int i = 0; i < TEXTLINES; i++) { mvwprintw(win, i+1, (width-(strlen(win_screen[0])))/2, "%s", win_screen[i]); } wattroff(win, COLOR_PAIR(WINSC_PAIR)); - // Stampa della scritta che blinka wattron(win, A_BLINK); mvwprintw(win, TEXTLINES+1, (width-(strlen(win_desc)))/2, "%s", win_desc); wattroff(win, A_BLINK); - // Stampa a video e attendi input - refresh(); + wrefresh(win); while((ch = wgetch(win)) != 'q'); return; -} \ No newline at end of file +} + +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++; + + mvwprintw(main_win, status_y, status_x, "LIVES:\t%d", game_status.lives); + mvwprintw(main_win, status_y+1, status_x, "SCORE:\t%d", game_status.score); + mvwprintw(main_win, status_y+2, status_x, "TOP SCORE:\t%d", game_status.top_score); + mvwprintw(main_win, status_y+3, status_x, "BULLETS:\t%d", game_status.remaining_bullets); + + wrefresh(main_win); + return; +} diff --git a/src/input.c b/src/input.c new file mode 100644 index 0000000..6032560 --- /dev/null +++ b/src/input.c @@ -0,0 +1,41 @@ +#include "../include/input.h" +#include + +/* Returns 1 to continue, 0 if quit requested (player inactive). */ +int process_input(int input, + int *pause, + int *auto_shoot, + struct game_obj *player, + struct game_obj bullets[], + int bullet_attivi, + int *next_bullet) { + + 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)) { + if (*next_bullet != -1) { + bullets[*next_bullet].x = player->x; + bullets[*next_bullet].y = player->y - 1; + bullets[*next_bullet].active = 1; + } + } else if (input == 'p') { + *pause = !(*pause); + } else if (input == 'q') { + /* signal to caller to quit by marking player inactive */ + return 0; + } else if (input == 'g') { + *auto_shoot = !(*auto_shoot); + } + + if (*auto_shoot && bullet_attivi < BULLET_N && !(*pause)) { + if (*next_bullet != -1) { + bullets[*next_bullet].x = player->x; + bullets[*next_bullet].y = player->y - 1; + bullets[*next_bullet].active = 1; + } + } + + return 1; +} diff --git a/src/logic.c b/src/logic.c new file mode 100644 index 0000000..7ed7aa6 --- /dev/null +++ b/src/logic.c @@ -0,0 +1,73 @@ +#include "../include/logic.h" +#include + +void update_bullets(struct game_obj bullets[]) { + for(int i = 0; i< BULLET_N; i++) { + if (bullets[i].active) { + bullets[i].y--; + if (bullets[i].y < 1) { + bullets[i].active = 0; + } + } + } +} + +void handle_collisions(struct game_obj bullets[], struct game_obj enemies[], struct status *game_status, WINDOW *win) { + (void)win; /* kept parameter for parity with original code */ + for(int j = 0; j < BULLET_N; j++) { + if(bullets[j].active) { + for(int i = 0; i < ENEMY_N; i++) { + if(enemies[i].active && bullets[j].x == enemies[i].x && bullets[j].y == enemies[i].y) { + enemies[i].active = 0; + bullets[j].active = 0; + game_status->score++; + } + } + } + } +} + +void spawn_enemies(struct game_obj enemies[], int width) { + for(int i = 0; i < ENEMY_N; i++) { + if(!enemies[i].active) { + enemies[i].y = 2; + enemies[i].x = (rand()%((width-4)/2))*2 + 2; + enemies[i].active = 1; + enemies[i].y_speed.count = 0; + break; + } + } +} + +void update_enemies(struct game_obj enemies[], struct status *game_status, int height, WINDOW *win) { + (void)win; + for(int i = 0; i < ENEMY_N; i++) { + if(enemies[i].active) { + enemies[i].y_speed.count++; + if(enemies[i].y_speed.count > enemies[i].y_speed.slowness) { + enemies[i].y++; + enemies[i].y_speed.count = 0; + } + if(enemies[i].y > height - 2) { + enemies[i].active = 0; + game_status->lives--; + } + } + } +} + +/* Recomputes bullet_attivi and next_bullet, and updates remaining_bullets */ +void count_bullets(const struct game_obj bullets[], int *bullet_attivi, int *next_bullet, struct status *game_status) { + *bullet_attivi = 0; + *next_bullet = -1; + for (int i = 0; i < BULLET_N; i++) { + if (bullets[i].active) { + (*bullet_attivi)++; + } else { + if (*next_bullet == -1 || i < *next_bullet) { + *next_bullet = i; + } + } + } + game_status->remaining_bullets = BULLET_N - (*bullet_attivi); +} diff --git a/src/main.c b/src/main.c index 1f3025a..c87703e 100644 --- a/src/main.c +++ b/src/main.c @@ -1,308 +1,25 @@ #include #include -#include -#include #include -#include -#include -#include + +#include "../include/game.h" #include "../include/gui.h" -/************* STATIC DEFINITIONS ************/ -// Game constants -#define ENEMY_N 5 -#define BULLET_N 3 -#define LIVES_N 5 -#define WIN_PTS 100 - -// Window constants -#define DELAY 30000 -#define WIDTH 52 -#define HEIGHT 30 -#define MIN_COLS 110 - - -/************* 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; -}; - - -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 ***************/ +int main(void) { initscr(); cbreak(); noecho(); keypad(stdscr, TRUE); curs_set(0); - srand(time(NULL)); - // Colori init_colors(); - // 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; + game_run(); - // 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++; - if(game_status.score == WIN_PTS) { - player.active = 0; - print_win_screen(stdscr); - } - } - } - } - } - - // 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++; - if(game_status.score == WIN_PTS) { - player.active = 0; - print_win_screen(stdscr); - } - } - } - } - } - - // 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); + /* cleanup terminal */ curs_set(1); endwin(); + printf("Gioco terminato.\n"); return 0; } - diff --git a/src/objects.c b/src/objects.c new file mode 100644 index 0000000..e06504d --- /dev/null +++ b/src/objects.c @@ -0,0 +1,33 @@ +#include "objects.h" +#include + +void init_player(struct game_obj *player, int win_width, int win_height) { + player->symbol = 'A'; + player->x = win_width / 2; + player->y = win_height - 2; + player->active = 1; + player->y_speed.slowness = 0; + player->y_speed.count = 0; +} + +void init_bullets(struct game_obj bullets[]) { + for (int i = 0; i < BULLET_N; i++) { + bullets[i].symbol = '*'; + bullets[i].active = 0; + bullets[i].x = 0; + bullets[i].y = 0; + bullets[i].y_speed.slowness = 0; + bullets[i].y_speed.count = 0; + } +} + +void init_enemies(struct game_obj enemies[]) { + for (int i = 0; i < ENEMY_N; i++) { + enemies[i].symbol = 'Q'; + enemies[i].active = 0; + enemies[i].y_speed.slowness = 7; + enemies[i].y_speed.count = 0; + enemies[i].x = 0; + enemies[i].y = 0; + } +} diff --git a/src/utils.c b/src/utils.c new file mode 100644 index 0000000..abbb907 --- /dev/null +++ b/src/utils.c @@ -0,0 +1,2 @@ +#include "utils.h" +/* currently no utility functions needed; file exists for future helpers */