Gra w C++ i Allegro

Witam, piszę grę w języku C++ z wykorzystaniem biblioteki Allegro (grafika i muzyka) po uruchomieniu programu i wejściu do procedury gry która odpowiada za poruszanie się i interakcję postaci sterowanej strzałkami program działa dobrze przez pewien czas potem zaczyna się zacinać, aż w końcu staje całkowicie. Windows Vista pokazuje komunikat, że program przestał działać. Na Windows XP po zacieńciu sie otrzymuję komunikat, że pamięć wirtualna została przeładowana czy coś takiego… :confused: nie mam pojęcia z czym to może być związane. Jeśli ktoś by miał pomysł albo ma podobne doświadczenia jak temu zapobiec to proszę o pomoc.

Kod gry:

# include 

# include 


using namespace std;


void increment_speed();

void gra();

void autorzy();

void myszka();

void pokaz_myche();                


int mx = 0, my =0, mb = 0;

int pozycja = 1;

int obrazeniabroni = 0;

int bron = 0;

int zycie = 100;

int numermapy = 1;

int itemquesta = 0;


volatile long speed = 0;




int main()

{

    allegro_init();

    install_keyboard();

    set_color_depth(16);

    set_gfx_mode(GFX_AUTODETECT_WINDOWED,1024,768,0,0);

    install_timer();

    install_int_ex(increment_speed, BPS_TO_TIMER(80));

    install_sound(DIGI_AUTODETECT,MIDI_AUTODETECT,"");

    install_mouse();

    set_volume(255,255);

    set_palette(default_palette);


    BITMAP *intro = NULL;

    BITMAP *menu = NULL;

    SAMPLE *dzwiekmenu = NULL;


    intro = load_bmp("intro.bmp",default_palette);

    menu = load_bmp("menu.bmp",default_palette);

    dzwiekmenu = load_sample("menumusic.wav");


    blit(intro,screen,0,0,0,0,1024,768);


    rest(3000);

    loop:

    play_sample(dzwiekmenu,255,127,1000,1); 

    loop1:  

    pokaz_myche();  

    blit(menu,screen,0,0,0,0,1024,768);


    while (!(mx >= 402 && mx <= 622 && my >= 620 && my <= 679 && mb == 1))

    {

          myszka();

          if (mx >= 402 && mx <= 622 && my >= 284 && my <= 343 && mb == 1)

          {

                         stop_sample(dzwiekmenu);

                         unscare_mouse();

                         gra();

                         goto loop;

                         }

          if (mx >= 402 && mx <= 622 && my >= 508 && my <= 576 && mb == 1)

          {

                         autorzy();

                         mb = 0;

                         goto loop1;

                         }

    }


    allegro_exit();

    return 0;

}

END_OF_MAIN();


void increment_speed()

{

     speed++;

}

END_OF_FUNCTION(increment_speed);


LOCK_VARIABLE(speed);

LOCK_FUNCTION(increment_speed);


void gra()

{

     install_timer();

     install_int_ex(increment_speed, BPS_TO_TIMER(80));


     BITMAP *bufor = NULL;

     BITMAP *ludek0 = NULL;

     BITMAP *ludek1 = NULL;

     BITMAP *ludek2 = NULL;

     BITMAP *ludek3 = NULL;

     BITMAP *ludek10 = NULL;

     BITMAP *ludek11 = NULL;

     BITMAP *ludek12 = NULL;

     BITMAP *ludek13 = NULL;

     BITMAP *downbar = NULL;

     BITMAP *pasekzycia100 = NULL;

     SAMPLE *dzwiekgra = NULL;


     bufor = create_bitmap(1024,768);


     if (!bufor)

     {

                set_gfx_mode(GFX_TEXT,0,0,0,0);

                allegro_message("Nie moge utworzyc bufora!");

                allegro_exit();

     }


     ludek0 = load_bmp("bobek00.bmp",default_palette);

     ludek1 = load_bmp("bobek01.bmp",default_palette);

     ludek2 = load_bmp("bobek02.bmp",default_palette);

     ludek3 = load_bmp("bobek03.bmp",default_palette);

     ludek10 = load_bmp("bobek10.bmp",default_palette);

     ludek11 = load_bmp("bobek11.bmp",default_palette);

     ludek12 = load_bmp("bobek12.bmp",default_palette);

     ludek13 = load_bmp("bobek13.bmp",default_palette);

     downbar = load_bmp("downbar.bmp",default_palette);

     pasekzycia100 = load_bmp("pasekzycia.bmp",default_palette);

     dzwiekgra = load_sample("gamemusic.wav");


     int ludek_x = 100, ludek_y = 100;

     int frame = 0;


     play_sample(dzwiekgra,255,127,1000,1);


     while (!key[KEY_ESC])

     {

           while (speed > 0)

           {

                 if(key[KEY_LEFT]) {

                                           if (ludek_x == 0) ludek_x;

                                           if (ludek_x > 0) ludek_x--;

                                           pozycja = 1;

                                           if (numermapy == 2 && ludek_x == 1) {

                                                                                    numermapy = 1;

                                                                                    ludek_x = 948;

                                                                                    }


                                           if (numermapy == 4 && ludek_x == 1) {

                                                                                    numermapy = 3;

                                                                                    ludek_x = 948;

                                                                                    }

                                           }

                 if(key[KEY_RIGHT]) {

                                           if (ludek_x == 950) ludek_x;

                                           if (ludek_x < 950) ludek_x++;

                                           pozycja = 2;

                                           if (numermapy == 1 && ludek_x == 949) {

                                                                                    numermapy = 2;

                                                                                    ludek_x = 2;

                                                                                    }


                                           if (numermapy == 3 && ludek_x == 949) {

                                                                                    numermapy = 4;

                                                                                    ludek_x = 2;

                                                                                    }

                                           }

                 if(key[KEY_UP]) {

                                           if (ludek_y == 0) ludek_y;

                                           if (ludek_y > 0) ludek_y--;

                                           pozycja = 2;

                                           if (numermapy == 1 && ludek_y == 1) {

                                                                                    numermapy = 3;

                                                                                    ludek_y = 578;

                                                                                    }


                                           if (numermapy == 2 && ludek_y == 1) {

                                                                                    numermapy = 4;

                                                                                    ludek_y = 578;

                                                                                    }


                                           }

                 if(key[KEY_DOWN]) {

                                           if (ludek_y == 580) ludek_y;

                                           if (ludek_y < 580) ludek_y++;

                                           pozycja = 1;

                                           if (numermapy == 3 && ludek_y == 579) {

                                                                                    numermapy = 1;

                                                                                    ludek_y = 2;

                                                                                    }


                                           if (numermapy == 4 && ludek_y == 579) {

                                                                                    numermapy = 2;

                                                                                    ludek_y = 2;

                                                                                    }

                                           }

                 speed--;


                 frame++;

                 if(frame > 80) frame = 0;

           }


           if (numermapy == 1) bufor = load_bmp("mapa1.bmp",default_palette); // NIE RUSZAĆ 

           if (numermapy == 2) bufor = load_bmp("mapa2.bmp",default_palette); // NIE RUSZAĆ 

           if (numermapy == 3) bufor = load_bmp("mapa3.bmp",default_palette); // NIE RUSZAĆ 

           if (numermapy == 4) bufor = load_bmp("mapa4.bmp",default_palette); // NIE RUSZAĆ 


           textout_ex(downbar,font,"GameX 2.0",20,20,makecol(255,255,255),-1);

           textout_ex(downbar,font,"Beta 1 Build 450",20,32,makecol(255,255,255),-1);

           textout_ex(downbar,font,"Zycie:",268,20,makecol(255,255,255),-1);

           textout_ex(downbar,font,"Aktualna",628,30,makecol(255,255,255),-1);

           textout_ex(downbar,font,"bron:",628,42,makecol(255,255,255),-1);

           textout_ex(downbar,font,"Item",833,30,makecol(255,255,255),-1);

           textout_ex(downbar,font,"questa:",833,42,makecol(255,255,255),-1);

           textout_ex(downbar,font,"Obrazenia:",628,66,makecol(255,255,255),-1);


           textprintf_ex(downbar,font,720,66,makecol(255,255,255),-1,"%d",obrazeniabroni);


           if (bron == 0) textout_ex(downbar,font,"Brak nazwy",628,54,makecol(255,255,255),-1);

           if (bron == 1) textout_ex(downbar,font,"Laga",628,54,makecol(255,255,255),-1);

           if (bron == 2) textout_ex(downbar,font,"Topor",628,54,makecol(255,255,255),-1);

           if (bron == 3) textout_ex(downbar,font,"Miecz",628,54,makecol(255,255,255),-1);


           if (itemquesta == 0) textout_ex(downbar,font,"Brak nazwy",833,66,makecol(255,255,255),-1);


           if (pozycja == 1) {

                       if (frame < 20) { draw_sprite(bufor,ludek0,ludek_x,ludek_y); }

                       else if (frame >= 20 && frame < 40) { draw_sprite(bufor,ludek1,ludek_x,ludek_y); }

                       else if (frame >= 40 && frame < 60) { draw_sprite(bufor,ludek2,ludek_x,ludek_y); }

                       else if (frame >= 60 && frame < 80) { draw_sprite(bufor,ludek3,ludek_x,ludek_y); }

                       }


           if (pozycja == 2) {

                       if (frame < 20) { draw_sprite(bufor,ludek10,ludek_x,ludek_y); }

                       else if (frame >= 20 && frame < 40) { draw_sprite(bufor,ludek11,ludek_x,ludek_y); }

                       else if (frame >= 40 && frame < 60) { draw_sprite(bufor,ludek12,ludek_x,ludek_y); }

                       else if (frame >= 60 && frame < 80) { draw_sprite(bufor,ludek13,ludek_x,ludek_y); }

                       }


           blit(bufor,screen,0,0,0,0,1024,768);


           masked_blit(downbar,screen,0,0,0,668,1024,768);

           if (zycie == 100) masked_blit(pasekzycia100,screen,0,0,320,682,1024,768);

           if (zycie == 80) masked_blit(pasekzycia100,screen,0,0,320,682,1024,768);

           if (zycie == 60) masked_blit(pasekzycia100,screen,0,0,320,682,1024,768);

           if (zycie == 40) masked_blit(pasekzycia100,screen,0,0,320,682,1024,768);

           if (zycie == 20) masked_blit(pasekzycia100,screen,0,0,320,682,1024,768);

           if (zycie == 0) masked_blit(pasekzycia100,screen,0,0,320,682,1024,768);

     }


     remove_int (increment_speed);

     destroy_bitmap(ludek0);

     destroy_bitmap(ludek1);

     destroy_bitmap(ludek2);

     destroy_bitmap(ludek3);

     destroy_bitmap(ludek10);

     destroy_bitmap(ludek11);

     destroy_bitmap(ludek12);

     destroy_bitmap(ludek13);

     destroy_bitmap(bufor);

     destroy_bitmap(downbar);

     destroy_bitmap(pasekzycia100);

     stop_sample(dzwiekgra);

     clear_keybuf();

}

END_OF_FUNCTION(gra);


void autorzy()

{

     BITMAP *autorzy = NULL;

     autorzy = load_bmp("autorzy.bmp",default_palette);

     blit(autorzy,screen,0,0,0,0,1024,768);


     while (!key[KEY_ESC])

           {

           }   

}

END_OF_FUNCTION(autorzy);  


void myszka()

{

    if (mx != mouse_x || my != mouse_y || mb != mouse_b)

    {

           mx = mouse_x;

           my = mouse_y;

           mb = mouse_b;     

    }      

}       

END_OF_FUNCTION(myszka);          


void pokaz_myche()

{


     BITMAP *kursor = NULL;

     kursor = load_bitmap("kursor.bmp",NULL);

     if (!kursor)

     {

        set_gfx_mode(GFX_TEXT,0,0,0,0);

        allegro_message("Nie moge zaladowac grafiki ( kursor )");

        allegro_exit();

     }


     show_mouse(screen);

     set_mouse_sprite(kursor);

}

END_OF_FUNCTION(pokaz_myche);  


[/code]
  1. NIE UŻYWAJ GOTO , możesz przeczytać jak użyć innych konstrukcji na wikipedii http://pl.wikipedia.org/wiki/Goto

  2. Po drugie przecieka ci pamięć :slight_smile: Program “wyrzuca” dlatego że zabiera całą dostępną pamięć i system operacyjny “awaryjnie” odcina go, żeby ratować stabilność komputera.

Jeśli możesz zuploadować źródła + grafika na serwer w jednym zipie, pomogę ci to przepisać po ludzku.

Poradziłem sobie narazie z problemem pamięci deklarując wskaźniki na początku pętli i usuwając je na końcu… Pamięci już nie zajmuje tak jak to miało miejsce poprzednio ale nie wiem czy nie strace na jakości działania programu narazie nie zauważyłem większych strat. Nie wiem jak to będzie dalej jak dodam ostateczne grafiki :confused: Ew. jak “załatać” takie wyciekanie pamięci w inny sposób ? i czy goto jest takie pamięciożerne czy napisałeś bo uważasz że tu można zastosować coś innego wygodniejszego ? Zastosowałem GOTO bo ten fragment kodu pisałem na szybko i brałem co miałem pod ręką.

Pozdrawiam.

Napisz do mnie na PM to zrobię refactoring tej twojej prostej gry w wolnej chwili.

Refactoring? Przecież to można tylko skasować i napisać jeszcze raz od nowa. Przynajmniej z użyciem tablic i struktur, jeśli nie obiektów.

Jestem programistą BASIC, mam GOTO i nie zawaham się go użyć :expressionless:

Wierzę, że można się więcej nauczyć patrząc na prawidłowo zbudowany kod, a następnie na jego podstawie próbować samemu, niż komuś kazać skasować jego wypociny i pisać od nowa, bez żadnego wyznacznika (wzoru).

Programowania można się nauczyć bardzo dobrze tylko przez praktykę, a dokładając do tego dobry wzór, uczymy przyszłego programistę. Ja wybaczam użycie GOTO początkującemu programiście i z chęcią go “nauczę” użycia pętli oraz innych struktur kontrolnych.

Czytaj: “widzę, że się przynajmniej stara” :slight_smile:

Nie znam książki ani kursu, w której przy okazji omawiania goto nie byłoby stwierdzone, żeby unikać tej instrukcji jak ognia. Jestem przekonany, że po przeczytaniu paru rozdziałów traktujących o programowaniu można napisać znacznie lepszy kod.

Ale jak chcesz się bawić w korepetytora, to proszę bardzo, mi by się nie chciało :wink:

GOTO używa się… No dobra… Tego się już nie używa!

Zrób pętlę główną w mainie wywołującą funkcje, a zmienne se zrób globalne, albo najlepiej obiekty zrób