Mercurial > hg > pub > prymula > com
diff trix/src/game.c @ 0:2787f5e749ae
INIT
author | prymula <prymula76@outlook.com> |
---|---|
date | Thu, 21 Sep 2023 22:33:57 +0200 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/trix/src/game.c Thu Sep 21 22:33:57 2023 +0200 @@ -0,0 +1,813 @@ +/* + * Trix - klikanie po klockach + * Przemysław R. Pietraszczyk + * + * paźdżiernik 2006 r. + * + * licencja: Public Domain + */ + +#include "trix.h" + +#define X_SCORE_INSCRIPTION 10 +#define X_LEVEL_INSCRIPTION 200 +#define X_HISCORE_INSCRIPTION 340 +#define Y_ALL_INSCRIPTION 0 + +#define X_HIGH_SLAT 1 +#define Y_HIGH_SLAT 40 +#define X_SIZE_HIGH_SLAT (screen->w) +#define Y_SIZE_HIGH_SLAT FIELD_SIZE + +#define X_ACTION 1 +#define Y_ACTION 60 +#define X_SIZE_ACTION (screen->w) +#define Y_SIZE_ACTION (screen->h) + +/* +// z trix.h begin +SDL_Surface * block[8]; +SDL_Surface * explode; +SDL_Surface * bomb; +SDL_Surface * wall; +SDL_Surface * smoke; + +SDL_Surface * net; +SDL_Surface * banner; +SDL_Surface * bg; +SDL_Surface * screen; +TTF_Font* font; + +SDL_Renderer * renderer; +SDL_Texture * tex_screen; + +SDL_Rect source, dest; +int use_net; // zmienna wyswietlania siatki +int start_level; // start gry od poziomu ... +int score; +int bonus; // nalicza premie + +char * hifile; // path do hiscore + + +int use_net; // zmienna wyswietlania siatki +int start_level; // start gry od poziomu ... +int score; +int bonus; // nalicza premie + +char * hifile; // path do hiscore +struct tab tab_hiscores[5]; +char const catalogue[N_PIC][40]; +// z trix.h end + +*/ + + + +static SDL_Surface * var_level_inscription; +static SDL_Surface * var_hiscore_inscription; + +/* tablica struktur przechowuje pozycje kasowanych elementow */ +static struct ghost gh[598]; +static int gh_index; + +SDL_Surface * prepare_text(int r, int b, int g, char *buffer); +void load_background(int n); +void print_inscription(char * buffor, int desx, int desy); +void draw_text (int x, int y, SDL_Surface * image); + +void get_name_of_player(void); + + + +/* sprawdza czy klocki nie osiagnely masymalnej wysokosci */ +int behind_high(void) { + + int i; + + /* jesli znajdzie na szczycie jakis klocek o stalym statusie + zwraca prawde */ + for (i=0; i<23; ++i) { + if (field[i][1].type && field[i][1].status == STAND) + return 1; + } + + return 0; +} + +/* zeruje strukture elementow */ +void zero_field(void) { + + int i, j; + + for (j=0; j<26;++j) { + for (i=0; i<23;++i) { + field[i][j].type = NULL; + field[i][j].status=0; + } + } + +} + + +void set_background(void) { + + SDL_Rect srcrect, destrect; + + destrect = set_rect(0, 0, bg->w, bg->h); + srcrect = set_rect(0,0, bg->w, bg->h); + SDL_BlitSurface(bg,&srcrect,screen,&destrect); +} + +void set_net(void) { + + SDL_Rect srcrect, destrect; + + destrect = set_rect(0, 0, net->w, net->h); + srcrect = set_rect(0,0, net->w, net->h); + SDL_BlitSurface(net,&srcrect,screen,&destrect); +} + + +/* sprawdza czy na planszy sa jakies klocki */ +int shortage_blocks(void) { + + int i, j; + + for (j=1; j<26; j++) { + for (i=0; i<23; i++) { + if (field[i][j].type) { + if (field[i][j].type == wall) continue; + else goto end; + } + } + } + +end: + /* gdy brak klockow */ + if (j==26 && i==23) { + printf ("brak klockow\n"); + return 1; + } + + /* gdy sa klocki */ + return 0; + + +} + + +/* elementy zaczynaja opadac z gornej belki */ +void drop_from_high_slat(void) { + + int i; + + for (i=22; i>=0; --i) { + field[i][0].status = DROP; + } +} + +void set_element(int f, int x, int y) { + + switch(f) { +// od 0 do 49 pustka + case 50 ... 64: + field[x][y].type = bomb; + break; + case 65 ... 73: + field[x][y].type = block[0]; + break; + case 74 ... 80: + field[x][y].type = block[1]; + break; + case 81 ... 85: + field[x][y].type = block[2]; + break; + case 86 ... 90: + field[x][y].type = block[3]; + break; + case 91 ... 99: + field[x][y].type = block[4]; + break; + case 100 ... 106: + field[x][y].type = block[5]; + break; + case 107 ... 111: + field[x][y].type = block[6]; + break; + case 112 ... 116: + field[x][y].type = block[7]; + break; + default: + field[x][y].type = NULL; + break; + } +} + +/* wypelnia studnie elementami */ +void fill_board(struct data_levels * dl) { + + int x, y, f; + + for (y=24; y>2; --y) { + for (x=0; x<23; ++x) { +label: + f=rand()%dl->max; + if (f<40) goto label; + set_element(f, x, y); + + field[x][y].status = DROP; + } + } + +} + + +/* gorna listwa */ +void high_slat(struct data_levels * dl, SDL_bool only_bomb) { + + int i, f; + + /* przesuwamy klocki w prawo */ + for (i=22; i>0; --i) + field[i][0] = field[i-1][0]; + + /* losujemy element dla pozycji 0,0 */ + if (!only_bomb) f=rand()%dl->max; + else f=55; + + set_element(f, 0, 0); + + field[0][0].status = 0; + +} + +/* funkcja sprawdza status elementu i jesli + element opada to obniza element na planszy */ +void drop_elements(void) { + + int j, i; + + + for (j=25; j>=0; --j) { + for (i=0; i<23; ++i) { + if (field[i][j].status == DROP) { + + /* jesli analizowana pozycja jest pusta */ + if (!field[i][j+1].type) { + field[i][j+1] = field[i][j]; + + + // wyzerowanie poprzedniej pozycji + field[i][j].status = 0; + field[i][j].type = NULL; + + /* osiadlo na dnie */ + if (j==24) { + field[i][j+1].status = STAND; + } + } + /* wprzeciwnym wypadku stawiamy element na + elemencie */ + else { + field[i][j].status = STAND; + } + + + + + } + } + } + +} + +/* kasuje elementy po skasowaniu klockow badz wybuchu bomb */ +void delete_elements(void) { + + int x, y; + + /* to musi byc przynajmniej para wiec mozna + tak sprawdzac */ + if (gh_index) { + + /* index jest o jeden wiekszy trzeba go zmnniejszyc */ + gh_index--; + + printf ("gh_index: %d\n", gh_index); + + do { + /* kasowanie elementow po zniknieciu lub wybuchu */ + field[gh[gh_index].x][gh[gh_index].y].type = NULL; + field[gh[gh_index].x][gh[gh_index].y].status = 0; + + printf ("kasowanie x: %d y: %d\n", gh[gh_index].x, gh[gh_index].y); + + x = gh[gh_index].x; + y = gh[gh_index].y - 1; // dotyczy elementu znajdujacego sie nad kasowanym elementem + +// gh[gh_index].x = 0; +// gh[gh_index].y = 0; + + /* zmiana statusu elementom znajdujacym sie wyzej + o ile nie znikaja */ + while (y>1 && field[x][y].status == STAND) { + field[x][y].status = DROP; + --y; + } + + }while(gh_index--); + gh_index = 0; + } +} + + + + +/* wyszukuje klocki o tym samym kolorze i zmienia je w dymek*/ +void search_block(SDL_Surface * color, int x, int y) { + +// printf ("s... type: %p color: %p x: %d y: %d\n", field[x][y].type, color, x, y); + + if (field[x][y].type == color && field[x][y].status == STAND) { + + printf ("Fade : %p color %p x: %d y: %d\n", field[x][y].type, color, x, y); + + field[x][y].status = FADE; + field[x][y].type = smoke; + score++; + bonus++; + + /* zapamietuje pozycje ktora trzeba bedzie pozniej skasowac */ +// printf ("gh_index = %d\n", gh_index); + gh[gh_index].x = x; + gh[gh_index].y = y; + gh_index++; + + /* nastepne klocki do sprawdzenia */ + if (y<25) search_block(color, x, y+1); + if (y>1) search_block(color,x, y-1); + if (x>0) search_block(color, x-1, y); + if (x<22) search_block(color,x+1, y); + + + } + +} + +/* szuka pary do skasowania */ +void pre_delete_block(int x, int y) { + + +// printf ("\npre_delete: %p x: %d y: %d \n\n", field[x][y].type, x, y); + + /* szuka przynajmniej pary */ + if (field[x][y].type == field[x][y+1].type || + field[x][y].type == field[x][y-1].type || + field[x][y].type == field[x+1][y].type || + field[x][y].type == field[x-1][y].type && field[x][y].status == STAND) { + + + if (y<25) search_block(field[x][y].type, x, y+1); + if (y>1) search_block(field[x][y].type, x, y-1); + if (x>0) search_block(field[x][y].type, x-1, y); + if (x<22) search_block(field[x][y].type, x+1, y); + +// raczej niepotrzebne juz +// field[x][y].status = FADE; +// field[x][y].type = smoke; + + } + + +} +/* eksplozja elementow znajdujacych sie wokol bomb */ +void power_strike (int x, int y){ + + if (field[x][y].type != bomb && field[x][y].status == STAND) { + + field[x][y].status = FADE; + field[x][y].type = explode; + + /* zapamietuje pozycje ktora trzeba bedzie pozniej skasowac */ + gh[gh_index].x = x; + gh[gh_index].y = y; + gh_index++; + } + +} + +/* szuka bomb i dokonuje eksplozji */ +void search_bomb(int x, int y) { + + if (field[x][y].type == bomb && field[x][y].status == STAND) { + + printf ("Fade : %p bomb %p x: %d y: %d\n", field[x][y].type, bomb, x, y); + + field[x][y].status = FADE; + field[x][y].type = explode; + + /* zapamietuje pozycje ktora trzeba bedzie pozniej skasowac */ + gh[gh_index].x = x; + gh[gh_index].y = y; + gh_index++; + + /* nastepne klocki do sprawdzenia */ + if (y<25) search_bomb(x, y+1); + if (y>1) search_bomb(x, y-1); + if (x>0) search_bomb(x-1, y); + if (x<22) search_bomb(x+1, y); + if (x>0 && y>1) search_bomb(x-1, y-1); + if (x<22 && y>1) search_bomb(x+1, y-1); + if (x>0 && y<25) search_bomb(x-1, y+1); + if (x<22 && y<25) search_bomb(x+1, y+1); + + /* sila razenia */ + if (y<25) power_strike(x, y+1); + if (y>1) power_strike(x, y-1); + if (x>0) power_strike(x-1, y); + if (x<22) power_strike(x+1, y); + if (x>0 && y>1) power_strike(x-1, y-1); + if (x<22 && y>1) power_strike(x+1, y-1); + if (x>0 && y<25) power_strike(x-1, y+1); + if (x<22 && y<25) power_strike(x+1, y+1); + + + } + +} + +/* szuka pary bomb */ +void pre_delete_bomb(int x, int y) { + + /* szuka przynajmniej pary */ + if (field[x][y].type == field[x][y+1].type || + field[x][y].type == field[x][y-1].type || + field[x][y].type == field[x+1][y].type || + field[x][y].type == field[x-1][y].type && field[x][y].status == STAND) { + + + if (y<25) search_bomb(x, y+1); + if (y>1) search_bomb(x, y-1); + if (x>0) search_bomb(x-1, y); + if (x<22) search_bomb(x+1, y); + + } +} + +/* sprawdza czy mozna dosunac elemnty do prawej strony */ +//void check_before_field(void) { + void on_the_right(void) { + + int i,j,k,l; + + for (i=21; i>=0; --i) { + + /* jesli pole przed elementem jest puste */ + if (!field[i+1][25].type && field[i][25].status == STAND) { + + /* sprawdza jak wysoko siegaja kolocki */ + k=0; +// while(field[i][25-k].type && field[i][25-k].status == STAND)k++; + while(field[i][25-k].type)k++; + ++k; + +// printf (" K: %d\n", k); + + /* sprawdza czy nie wystaja jakies klocki na przedpolu */ + for (l=0; l<k; l++) { + /* jesli jest jakis klocek to wyskakuje z petli */ + if (field[i+1][25-l].type) break; + } +// printf (" L: %d\n", l); + + /* gdy brak elementow na przedpolu mozna przesowac */ + if (k == l) { + j=25; + /* przesowa kolejno elementy ustawione pionowo oprocz + eksplozji i zanikniec */ + while (field[i][j].type && field[i][j].status != FADE) { + + field[i+1][j] = field[i][j]; + + field[i][j].status = 0; + field[i][j].type = NULL; + --j; + } + } + + } + } + +} + + +void start_game(void) { + + int done; + char buffor[100]; + int i, j, x, y; + int move=1; // zmienna odpowiedzialna za przesowanie elem. gornel listwy + int over =-1; // zmienna odpowiedzialna za pojawienie sie napisu game over + int virtual_level, level; + int vis, drop_slat, pic; + SDL_Rect srcrect, destrect; + SDL_bool only_bomb = SDL_FALSE; + + /* + struct data_levels data_level[10] = { + {85, 200, 0}, + {90, 200, 0}, + {99, 150, 0}, + {99, 150, 0}, + {106, 150, 0}, + {111, 100, 0}, + {111, 150, 1}, + {111, 100, 1}, + {116, 150, 1}, + {116, 100, 1}}; +*/ + struct data_levels data_level[10] = { + {85, 200, 0}, + {90, 200, 0}, + {99, 150, 0}, + {99, 150, 0}, + {106, 200, 0}, + {106, 150, 0}, + {85, 200, 1}, + {90, 200, 1}, + {99, 150, 1}, + {111, 100, 1}}; + + virtual_level = level = start_level; + score = 0; + srand(time(NULL)); + + destrect = set_rect(0,0,screen->w,screen->h); + SDL_FillRect(screen,&destrect,0); + //SDL_Flip(screen); + + + sprintf (buffor, "%d", tab_hiscores[0].score); + var_hiscore_inscription = (SDL_Surface *) prepare_text(255, 255, 255, buffor); + +new_level: + bonus = 0; + + sprintf(buffor, "%d", virtual_level); + var_level_inscription = (SDL_Surface *) prepare_text(255, 255, 255, buffor); + + pic = rand()%N_PIC; + load_background(pic); + + + drop_slat = data_level[level-1].drop; + vis = 15; + + /* ustawia murek */ + if (data_level[level-1].wall) { + field[10][25].type = wall; + field[10][25].status = WALL; + } + + + /* wypelnia studnie elementami */ + fill_board(&data_level[level-1]); + + done = 0; + while (!done) + { + + + + + set_background(); + + if (use_net) set_net(); + + /* sprawdza czy na planszy sa jakies klocki */ + if (shortage_blocks()) { + virtual_level++; + if (level < 10) level++; + + SDL_FreeSurface(var_level_inscription); + + score += bonus *3; + goto new_level; + } + + delete_elements(); + + + SDL_Event event; + + /* Check for events */ + while (SDL_PollEvent (&event)) + { + switch (event.type) + { + case SDL_KEYDOWN: + printf("Nacini�o klawisz: %s\n", + SDL_GetKeyName(event.key.keysym.sym)); + + switch (event.key.keysym.sym) { + case SDLK_ESCAPE: + done = 1; + break; + case SDLK_b: + if (only_bomb) only_bomb=SDL_FALSE; + else only_bomb=SDL_TRUE; + break; + } + break; + case SDL_QUIT: + exit(0); + break; + case SDL_MOUSEMOTION: +// if (event.motion.state & SDL_BUTTON(1)) +// printf("Ruch z pierwszym przyciskeim myszy\n"); + +// if (event.motion.state & SDL_BUTTON(2)) +// printf("Ruch z drugim przyciskiem myszy\n"); + +// if (event.motion.state & SDL_BUTTON(3)) +// printf("Ruch z trzecim przyciskiem myszy\n"); + +// printf("Przesuni�o myszk�o %d,%d\n", +// event.motion.xrel, event.motion.yrel); + case SDL_MOUSEBUTTONDOWN: +// printf("Nacini�o przycisk o numerze %d na " +// "punkcie o wsp�rz�nych %d,%d\n", event.button.button, +// event.button.x, event.button.y); + + + if (event.button.button && + event.button.x >= X_HIGH_SLAT +1 && + event.button.y >= Y_HIGH_SLAT && + event.button.x <= X_SIZE_HIGH_SLAT && + event.button.y <= (Y_SIZE_HIGH_SLAT + Y_HIGH_SLAT)) { + + printf ("opadanie\n"); + drop_from_high_slat(); + move = 0; + drop_slat = data_level[level-1].drop; + } + else if (event.button.button && + event.button.x >= X_ACTION && + event.button.y >= Y_ACTION && + event.button.x <= X_SIZE_ACTION && + event.button.y <= Y_SIZE_ACTION) { + + x=event.button.x/FIELD_SIZE; + y=event.button.y/FIELD_SIZE-2; + + if (field[x][y].type == bomb) + pre_delete_bomb(x, y); + else if (field[x][y].type) + pre_delete_block(x, y); + + } + + + } + } + + + drop_slat--; + /* gdy zero program sam zrzuca klocki z gornej listwy */ + if (!drop_slat) { + drop_from_high_slat(); + move = 0; + drop_slat = data_level[level-1].drop; + } + + + /* przesowa klocki na gornej listwie zapobiegajac przy okazji + opadaniu pod katem */ + if (!only_bomb){ + if (move) high_slat(&data_level[level-1], SDL_FALSE); + else move = 1; + } + else { + if (move) high_slat(&data_level[level-1], SDL_TRUE); + else move = 1; + } + + /* przesowa elemnty do prawej strony */ + on_the_right(); + + /* opuszcza elementy */ + drop_elements(); + + +// for (j=0; j<26; ++j) { +// for (i=0; i<23; ++i) { + +// if (field[i][j].type) +// printf ("j: %d i: %d type: %p\n", j, i, field[i][j].type); +// } +// } +// printf("\n\n"); + + + + /* umieszczanie elementow na planszy */ + srcrect = set_rect(0,0,FIELD_SIZE,FIELD_SIZE); + for (j=0; j<26; ++j) { + for (i=0; i<23; ++i) { + +// if (field[i][j].type) +// printf ("j: %d i: %d type: %p\n", j, i, field[i][j].type); + + destrect = set_rect(FIELD_SIZE * i,FIELD_SIZE * j+ 40, FIELD_SIZE, FIELD_SIZE); + SDL_BlitSurface(field[i][j].type,&srcrect, screen,&destrect); + } + } + +// for (j=0; j<20; ++j) { +// for (i=0; i<23; ++i) { +// if (field[i][j].status == DROP) putchar('|'); +// else if (field[i][j].status == STAND) putchar ('='); +// else if (field[i][j].status == 0) putchar(' '); +// } +// putchar('\n'); +// } + + /* przy rozpoczeciu poziomu wyswietla numer poziomu */ + if (vis) { + sprintf (buffor, " LEVEL %d", virtual_level); + print_inscription(buffor, 190, 200); + vis -= 1; + } + + /* sprawdza czy nie ma przepelnienia */ + if (behind_high() && over == -1) + over = 15; + /* wyswietla napis game over */ + if (!over) + done = 1; + else if (over > 0) { + strcpy(buffor, "GAME OVER"); + print_inscription(buffor, 160, 200); + // SDL_UpdateRect(screen, 160, 200, 136, 32); + over -= 1; + } + + sprintf (buffor, "%d", score); + print_inscription(buffor, 20, Y_ALL_INSCRIPTION); + draw_text(X_LEVEL_INSCRIPTION, Y_ALL_INSCRIPTION, var_level_inscription); + draw_text(X_HISCORE_INSCRIPTION, Y_ALL_INSCRIPTION, var_hiscore_inscription); + + // printf ("wysokosc : %d \n", var_hiscore_inscription->h); + + // SDL_Flip(screen); + + + + + + dest = set_rect(0, 0, screen->w, screen->h); + //SDL_FillRect(screen, &dest, SDL_MapRGB(screen->format, 255, 255, 255)); + + source = set_rect(0, 0, screen->w, screen->h); + + tex_screen = SDL_CreateTextureFromSurface(renderer, screen); + SDL_RenderClear ( renderer ); + SDL_RenderCopy(renderer, tex_screen,&source,&dest); + SDL_RenderPresent(renderer); + SDL_DestroyTexture(tex_screen); + + + + + + SDL_Delay(300); + } + + + /* sprawdza czy jest mozliwosc wpisu */ + if (score > tab_hiscores[4].score) { + get_name_of_player(); + } + + zero_field(); + + /* czysci ekran przed powrotem do menu */ + destrect = set_rect(0,0,screen->w,screen->h); + SDL_FillRect(screen,&destrect,0); + // SDL_Flip(screen); + + source = set_rect(0, 0, screen->w, screen->h); + tex_screen = SDL_CreateTextureFromSurface(renderer, screen); + SDL_RenderClear ( renderer ); + SDL_RenderCopy(renderer, tex_screen,&source,&dest); + SDL_RenderPresent(renderer); + SDL_DestroyTexture(tex_screen); + + /* zwalnia pamiec po nieaktualnych obrazkach z liczbami */ + SDL_FreeSurface(var_level_inscription); + SDL_FreeSurface(var_hiscore_inscription); + +} + +