#include <allegro.h>
#include <time.h> //per il tempo
#include <sstream>
#define largo 1000
#define lunghezza 720
#define limite_nodi 200 //limite di pezzi che può avere il serpente
#define sopra 0
#define giu 1
#define sinistra 2
#define destra 3
//Bitmap trasforma un immagine in formato digitale(pixel)
BITMAP *buffer, //buffer serve per visualizzare il contenuto su schermo
*teste, //4 teste
*testa, //testa principale
*corpo,
*vita,
*cibo,
*muro,
*fondo,
*menu1,
*menu2,
*cursore;
//le posizioni per muovere
int limite_x=largo/40;
int limite_y=lunghezza/40;
int partenza_nodi=3; //il serpente parte da 3 nodi + testa[0] =4
int dir=destra; //direzione di partenza è la destra
int cibo_x, cibo_y; //X e Y per la posizione del cibo
int punti=0, vitaa=3; //score iniziale e vite
int muro_x, muro_y;
//vettore per i nodi
struct nodo{
int x,y; //per il corpo
};
nodo corpi[limite_nodi];
void setupt()
{
allegro_init();
install_keyboard(); //installa la tastiera
install_mouse();
set_color_depth(32); //qualita colori
set_gfx_mode(GFX_AUTODETECT,largo,lunghezza,0,0);
srand(time(NULL));
buffer=create_bitmap(160,40);
teste=create_bitmap(40,40);
testa=create_bitmap(40,40);
corpo=create_bitmap(40,40);
vita=create_bitmap(40,40);
cibo=create_bitmap(40,40);
muro=create_bitmap(40,40);
fondo=create_bitmap(1000,720);
menu1=create_bitmap(1000,720);
menu2=create_bitmap(1000,720);
cursore=create_bitmap(13,22);
//ASSEGRNAZIONE IMMAGINI
teste=load_bitmap("imm/testa.bmp" , NULL); //per parametro nullo
corpo=load_bitmap("imm/corpo.bmp" , NULL);
vita=load_bitmap("imm/vita.bmp" , NULL);
muro=load_bitmap("imm/muro.bmp" , NULL);
cibo=load_bitmap("imm/cibo.bmp" , NULL);
fondo=load_bitmap("imm/fondo.bmp" , NULL);
menu1=load_bitmap("imm/munu1.bmp" , NULL);
menu2=load_bitmap("imm/meni2.bmp" , NULL);
cursore=load_bitmap("imm/cursore.bmp" , NULL);
}
void menuu()
{
bool x=false;
while(x=false)
{ //quando ci ci trova su queste coordinate viene visualizzato il menu 2
if((mouse_x>370)and(mouse_x<498)and(mouse_y>410)and(mouse_y<590))
{/* il comando 'blit' prende il contenuto che è stato disegnato nel buffer e lo visualizza su schermo
partendo da un certo angolo (x1=0,y1=0) fino all'angolo opposto dello schermo (x2=1000, y2=720) */
blit(menu2,buffer,0,0,0,0,1000,720);
//Se si preme il pulsante sinistro del mouse, quando viene chiamata la funzione mouse_b , restituisce un 1
//quando non viene premuto niente restiturisce 0
if(mouse_b&1) (x=true);
else
{
blit(menu1,buffer,0,0,0,0,1000,720);
/*masked_blit salta i pixel trasparenti, che sono contrassegnati da un rosa brillante 0
i dati TrueColor (massimo rosso e blu, verde)*/
masked_blit(cursore,buffer,0,0,mouse_x,mouse_y,13,22);
blit(buffer,screen,0,0,0,0,1000,720);
}
}
}
}
void aggiornamento() //per aggiornare dello sfondo, cioè permette di non far finire la partita quando appena l'utente preme start
{
blit(buffer,screen,0,0,0,0,largo/*1000*/,lunghezza/*720*/);
}
//per i muri
void bordi()
{
//draw_sprite fa una copia della bitmap, nella bitmap di destinazione e rende trasparenti i pixel rosa
draw_sprite(buffer,fondo,0,40);
//muro superiore
for (int muro_x=0;muro_x<26;muro_x++){
muro_y=1;
draw_sprite(buffer,muro,muro_x*40,muro_y*40);
}
//muro inferiore
for(int muro_x=0;muro_x<26;muro_x++){
muro_y=17;
draw_sprite(buffer,muro,muro_x*40,muro_x*40);
}
//muro sinistra veriticale
for(int muro_y=1;muro_y<18;muro_y++){
muro_x=0;
draw_sprite(buffer,muro,muro_x*40,muro_y*40);
}
//muro destra verticale
for(int muro_y=1;muro_y<18;muro_y++){
muro_x=24;
draw_sprite(buffer,muro,muro_x*40,muro_y*40);
}
}
void genera() //indica le posizioni
{
corpi[0].x=10; //per la posizione iniziale
corpi[0].y=10;
for(int i=1;i<=partenza_nodi;i++){
corpi[i].x=corpi[0].x-i;
corpi[i].y=corpi[0].y;
}
}
void per_cibo()
{ //rand() genera la posizione random di cibo
cibo_x=(rand()%(limite_x-2))+1; //(25-2) +1
cibo_y=(rand()%(limite_y-3))+2;
}
void disegno_cibo()
{
draw_sprite(buffer,cibo,cibo_x*40,cibo_y*40);
}
void disegno_serpente()
{
switch(dir){
case sopra: blit(teste,testa,0,0,0,0,40,40);
case giu: blit(teste,testa,40,0,0,0,40,40);
case destra: blit(teste,testa,80,0,0,0,40,40);
case sinistra :blit(teste,testa,120,0,0,0,40,40);
}
draw_sprite(buffer,testa,corpi[0].x*40,corpi[0].y*40);
//per corpo
for(int i=1;i<=partenza_nodi;i++)
{
draw_sprite(buffer,corpo,corpi[i].x*40,corpi[0].y*40);
}
}
void direzione_attuale()
{
if(key[KEY_UP]){
if(dir!=giu) dir=sopra; //0
}
else
if(key[KEY_DOWN]){
if (dir!=sopra) dir=giu; //1
}
else if (key[KEY_RIGHT]){
if(dir!=sinistra) //2
dir=destra;
}
else if(key[KEY_LEFT]){
if(dir!=destra) dir=sinistra; //3
}
}
void perdita_vita()
{
vitaa--; //ogni volta che perde una vita
if (vitaa>0){
clear(screen); //pulisce l'intero schermo
textout_ex(screen,font,"HAI PERSO UNA VITA",40*10,40*9,0xFFFFFF,0x000000);
rest(2000); //per quanto tempo rimane la scritta
}
else
{
clear(screen);
textout_ex(screen,font,"GAME OVER",40*10,40*9,0xFFFFFF,0x000000);
rest(2000);
exit(0);
}//a questo punto il gioco finisce
}
void movimento()
{
for (int i=partenza_nodi;i>0;i--){
corpi[i]=corpi[i-1];
}
switch(dir){
case sopra: corpi[0].y--;
case giu: corpi[0].y++;
case destra: corpi[0].x++;
case sinistra :corpi[0].x--;
}
//quando tocca cibo
if ((corpi[0].x==cibo_x)and(corpi[0].y==cibo_y)){
per_cibo();
partenza_nodi++;
corpi[partenza_nodi]=corpi[partenza_nodi-1];//per lampeggiare
punti=punti+5;
}
//quando si scontra con il bordo
if((corpi[0].x<1)or(corpi[0].x>(limite_x-2))or(corpi[0].y<2)or(corpi[0].y>(limite_y-2)))
{
perdita_vita();
genera();
dir=destra;
}
//quando si scontra con il suo stesso corpo
for(int i=1;9<=partenza_nodi;i++){
if((corpi[0].x==corpi[i].x)and(corpi[0].y==corpi[i].y)){
perdita_vita();
}
}
}
void muri()
{
for(int muro_x=10;muro_x<10;muro_x++){
muro_y=6;
draw_sprite(buffer,muro,muro_x*40,muro_y*40);
if ((corpi[0].x==muro_x)and(corpi[0].y==muro_y)) {perdita_vita();}
}
for(int muro_x=15;muro_x<19;muro_x++){
muro_y=11;
draw_sprite(buffer,muro,muro_x*40,muro_y*40);
if ((corpi[0].x==muro_x)and(corpi[0].y==muro_y)) {perdita_vita();}
}
for(int muro_y=6;muro_y<10;muro_x++){
muro_x=15;
draw_sprite(buffer,muro,muro_x*40,muro_y*40);
if ((corpi[0].x==muro_x)and(corpi[0].y==muro_y)) {perdita_vita();}
}
}
void punteggio()
{
std::stringstream ss; //questa classe serve per formattare una stringa in base al punteggio (serve sia per gli input che per gli output
ss<<"SCORE: "<<punti;
std::string p=ss.str();
char point[20];
strcpy(point,p.c_str());
textout_ex(buffer,font,point,50,15,0xFFFFFF,0x000000);
}
void pos_vite()
{
textout_ex(buffer,font,"VITE: ",largo-180,14,0xFFFFFF,0x000000);
for(int i=0;i<vitaa;i++){
draw_sprite(buffer,vita,i*40+(largo-120),0);
}
}
int main()
{
setupt();
menuu();
bordi();
genera();
disegno_serpente();
per_cibo();
disegno_cibo();
punteggio();
muri();
pos_vite();
aggiornamento();
while(!key[KEY_ESC]){
clear(buffer);
aggiornamento();
bordi();
muri();
disegno_serpente();
disegno_cibo();
punteggio();
pos_vite();
aggiornamento();
rest(200);
}
readkey(); //per chiudere la finestra
return 0;
}
END_OF_MAIN();