Se ti può interessare, io mi sono affidato alla libreria ncurses.
Se vuoi lanciare e provare, imposta il terminale a 132x43
Era un giochino, non ricordo se aveva qualche piccolo bug.
Esce da una parte del terminale ed esce dall'altra, se mangi la mela incrementa i punti.
Frecce per direzioni, barra spazio per pausa.
Puoi stabilire in compilazione la velocità e la dimensione iniziale del serpente.
Avevo messo anche una scrittura su file per memorizzare i record, ma quello ignora
Magari ti è utile:
Codice: Seleziona tutto
// gioco bruco 3/2020 by Gila75 //
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include <ncurses.h>
#include <time.h>
#define ROW 43
#define COL 132
#define L_SNAKE 10
#define DX 261
#define SX 260
#define DOWN 258
#define UP 259
#define SIZE_BUFF 10
#define TEMPO 50000
int dir_up_down[4]={0,0,-1,1}; // array per direzioni (variabili globali)
int dir_lat[4]={1,-1,0,0};
int punti=0;
struct gioco
{
int x[1000];
int y[1000];
int rnd;
int tmp_coda_x;
int tmp_coda_y;
int corpo;
int bit_mela;
int canc;
}
snake={.corpo=L_SNAKE, .bit_mela=0,.canc=0};
void game_over(int i);
int cerca_file (FILE **fd, char buff[]);
int aggiorna_record(FILE **fd,char buff[],int old_record);
void init_bruco (struct gioco *punt);
void cambia_dir (struct gioco *punt, int dir_tasto,int mela_x,int mela_y);
void game_over(int i)
{
attroff(COLOR_PAIR(1));
attroff(COLOR_PAIR(2));
attroff(COLOR_PAIR(3));
nodelay (stdscr, FALSE);
move (19,35);
printw("GAME OVER!!!! punti:%d\n",punti);
move (20,35);
printw("premi tasto per uscire\n");refresh();
if (i==1)
{
move (20,35);
printw ("NEW RWCORD: punti %d\n", punti);
move (21,35);
printw ("tasto per uscire\n");refresh();
}
getch();
}
//*******************************************************************************
// aggiorna il record su file, solo se è maggiore del vecchio record
int aggiorna_record(FILE **fd,char buff[],int old_record)
{
*fd=fopen("record.txt", "r");
if(*fd==NULL )
exit(0);
if (punti>old_record)
{
fclose(*fd);
*fd=fopen("record.txt", "w");
if (*fd==NULL)
exit(0);
fprintf (*fd,"%d",punti);
fclose(*fd);
return 1;
}
else
{
fclose(*fd);
return 0;
}
}
//*******************************************************************************
//*******************************************************************************
// cerca il file per memorizzare i record: se non esiste lo crea e
// lo inizializza a zero
// se esiste legge il contenuto per confrontarlo piu avanti
//*******************************************************************************
int cerca_file (FILE **fd,char buff[])
{
int n,x;
*fd=fopen("record.txt", "r");
if( *fd==NULL )
{
move (19,35);
printw("*********************************\n");
move (20,35);
printw ("* nessun record memorizzato *\n");
move (21,35);
printw ("* premi un tasto per proseguire *\n");
move (22,35);
printw("*********************************\n");
*fd=fopen("record.txt", "w");
if( fd==NULL )
{
printw("impossibile creare");refresh();
exit(0);
}
fprintf (*fd,"%d",0);
fclose(*fd);
getch();
erase();refresh();
return 0;
}
else // il file esiste e leggo
{
for(;;)
{
n = fread(buff, 1, SIZE_BUFF, *fd);
if( n == 0 )
break;
}
x=atoi(buff);
move (19,35);
printw ("OLD RECORD:%d\n",x);
move (20,35);
printw ("premi un tasto per proseguire\n");
refresh ();
getch();
erase();
return x;
}
}
//*******************************************************************************
void cambia_dir (struct gioco *punt, int dir_tasto,int mela_x,int mela_y)
{
int j,tmp_x,tmp_y;
attron(COLOR_PAIR(1));
punt->tmp_coda_x=punt->x[punt->corpo-1]; // memorizzo la coda che il padre metterà come spazio
punt->tmp_coda_y=punt->y[punt->corpo-1];
for (j=0; j< punt->corpo-1; j++)
{
tmp_x=punt->x[j+1]; // scalo posizioni per muovere
tmp_y=punt->y[j+1];
punt->x[j+1]=punt->x[0];
punt->y[j+1]=punt->y[0];
punt->x[0]=tmp_x;
punt->y[0]=tmp_y;
}
// se la testa incontra la mela : aumenta corpo, azzera bit mela
// setta bit canc: non deve cancellare la coda...infatti aumenta
if ((mvinch (punt->x[1]+dir_up_down[dir_tasto],punt->y[1]+dir_lat[dir_tasto]) & A_CHARTEXT) == 'X')
{
punt->bit_mela=0;
move (mela_x,mela_y);
addch(' ');
punt->corpo++;
punt->x[punt->corpo-1]=punt->tmp_coda_x;
punt->y[punt->corpo-1]=punt->tmp_coda_y;
punt->canc=1;
punti++;
move (0,0);
printw("punti %d\n",punti);refresh();
}
punt->rnd=dir_tasto;
}
//*******************************************************************************
// inizializzazione bruco
//*******************************************************************************
void init_bruco (struct gioco *punt)
{
int j;
for (j=0; j<punt->corpo; j++)
{
punt->x[j]=10; // creo array bruco
punt->y[j]=10+j; //11
}
for (j=0; j<punt->corpo; j++) // stampo bruco
{
move(punt->x[j], punt->y[j]);
addch('@');
}
move(punt->x[0], punt->y[0]);
addch('<');refresh();
}
//**********************************************************
int main(void)
{
initscr(); // init ncurses
cbreak(); // e funzioni varie per ncurses
noecho();
curs_set(0);
intrflush(stdscr, FALSE);
keypad(stdscr, TRUE);
start_color ();
//*********************************************************
srand((unsigned) time(NULL));
char heads[]="><^V";
int ch=0;
int tmp_dir=1;
int mela_x,mela_y,i,old_record;
char buff[SIZE_BUFF];
FILE *fd;
// iniz. colori
init_pair(1,COLOR_GREEN,COLOR_BLACK); // verde su black (snake)
init_pair(2,COLOR_RED,COLOR_BLACK); // rosso su black (testa)
init_pair(3,COLOR_YELLOW,COLOR_BLACK); // rosso su black (mela)
old_record=cerca_file (&fd,buff);
attron(COLOR_PAIR(1)); //attiva coppia colori 1
init_bruco (&snake);
nodelay (stdscr, TRUE); // getc() NON bloccante
while(1)
{
attron(COLOR_PAIR(1));
ch=getch();
if (ch==-1)
cambia_dir (&snake,tmp_dir,mela_x,mela_y);
else if (ch==DX) //se vai a dx,negato sx
{
if (tmp_dir==1)
cambia_dir (&snake,tmp_dir,mela_x,mela_y);
else
{
cambia_dir (&snake,261-ch,mela_x,mela_y);
tmp_dir=261-ch;
}
}
//--------------------------------------------------------
else if (ch==SX) //0
{
if (tmp_dir==0)
cambia_dir (&snake,tmp_dir,mela_x,mela_y);
else
{
cambia_dir (&snake,261-ch,mela_x,mela_y);
tmp_dir=261-ch;
}
}
//--------------------------------------------------------
else if (ch==DOWN) //2
{
if (tmp_dir==2)
cambia_dir (&snake,tmp_dir,mela_x,mela_y);
else
{
cambia_dir (&snake,261-ch,mela_x,mela_y);
tmp_dir=261-ch;
}
}
//--------------------------------------------------------
else if (ch==UP) //2
{
if (tmp_dir==3)
cambia_dir (&snake,tmp_dir,mela_x,mela_y);
else
{
cambia_dir (&snake,261-ch,mela_x,mela_y);
tmp_dir=261-ch;
}
}
//--------------------------------------------------------
else if (ch==32)
{
while (1)
{
ch=getch();
if (ch==32)
break ;
}
}
else if (ch!=-1)
cambia_dir (&snake,tmp_dir,mela_x,mela_y);
//--------------------------------------------------------
snake.x[snake.corpo]=snake.tmp_coda_x;
snake.y[snake.corpo]=snake.tmp_coda_y;
for (i=1; i<snake.corpo; i++) // stampo corpo
{
move (snake.x[i], snake.y[i]);
addch('@');refresh();
}
// se tocco il corpo muoio
if ((mvinch(snake.x[1]+dir_up_down[snake.rnd],snake.y[1]+dir_lat[snake.rnd])& A_CHARTEXT) == '@')
{
erase();
nodelay (stdscr, FALSE);
i=aggiorna_record(&fd,buff,old_record);
game_over(i);
endwin();
return 0;
}
else
{
snake.x[0]=snake.x[1]+dir_up_down[snake.rnd]; //aggiorno dir testa in base al tasto arrivato
snake.y[0]=snake.y[1]+dir_lat[snake.rnd];
}
attroff(COLOR_PAIR(1));
attron(COLOR_PAIR(2));
if (snake.y[0]>COL-1) // sbuca a col 0
{
snake.y[0]=0;
move (snake.x[0], snake.y[0]);
if ((mvinch(snake.x[0],snake.y[0])& A_CHARTEXT) == '@')
{
game_over(i);
endwin();
return 0;
}
else
addch(heads[snake.rnd]);
}
if (snake.y[0]<0) // sbuca a col 80
{
snake.y[0]=COL-1;
if ((mvinch(snake.x[0],snake.y[0])& A_CHARTEXT) == '@')
{
game_over(i);
endwin();
return 0;
}
else
addch(heads[snake.rnd]);
}
if (snake.x[0]>ROW-1) // sbuca a row 0
{
snake.x[0]=0;
if ((mvinch(snake.x[0],snake.y[0])& A_CHARTEXT) == '@')
{
game_over(i);
endwin();
return 0;
}
else
addch(heads[snake.rnd]);
}
if (snake.x[0]<0) // sbuca a row 24
{
snake.x[0]=ROW-1;
if ((mvinch(snake.x[0],snake.y[0])& A_CHARTEXT) == '@')
{
game_over(i);
endwin();
return 0;
}
else
addch(heads[snake.rnd]);
}
else
{
move (snake.x[0], snake.y[0]);
addch(heads[snake.rnd]);refresh();
}
attroff(COLOR_PAIR(2));
attron(COLOR_PAIR(1));
if (snake.canc==0)
{
move (snake.x[snake.corpo],snake.y[snake.corpo]);
addch(' ');refresh();
}
else
snake.canc=0;
if (snake.bit_mela==0)
{
while(1)
{
mela_x=rand()%(ROW);
mela_y=rand()%(COL);
if ((mvinch(mela_x,mela_y) & A_CHARTEXT)==' ')
{
attron(COLOR_PAIR(3));
move (mela_x,mela_y);
addch('X');
refresh();
attroff(COLOR_PAIR(3));
snake.bit_mela=1;
break;
}
}
}
refresh();
usleep(TEMPO);
}
return 0;
}
https://www.youtube.com/watch?v=EPcP24UGYr8