266 lines
7.9 KiB
C
266 lines
7.9 KiB
C
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <unistd.h>
|
|
#include <ncurses.h>
|
|
#include <time.h>
|
|
|
|
#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 #",
|
|
"###########################################################################################################"
|
|
};
|
|
|
|
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]);
|
|
}
|
|
mvwprintw(win, 7, 1, "BENVENUTO IN SPACE SHOOTER!\n");
|
|
wattron(win, A_BLINK);
|
|
mvwprintw(win, 8, 1, "Premi un tasto qualsiasi per giocare...");
|
|
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;
|
|
}
|