C++ Builder Wywołanie własnej funckji

0

Witam. Otóż napisałem voida

void zmien_mape(char strona)
{
id_mapy++;

if(strona=='p') Form1->gracz->Left=20;
else Form1->gracz->Left = Form1->tlo->Width-20;

if(id_mapy==1) Form1->tlo->Picture->LoadFromFile("img/tla/1.bmp");
if(id_mapy==2) Form1->tlo->Picture->LoadFromFile("img/tla/2.bmp");

} 

I chcę go wywołać w:

void __fastcall TForm1::lewoTimer(TObject *Sender)
{
        if(gracz->Left>10)
        {

        if(ruch==0) gracz->Picture->LoadFromFile("img/postacie/gracz/l2.bmp"), ruch++;
        else if(ruch==1) gracz->Picture->LoadFromFile("img/postacie/gracz/l3.bmp"), ruch++;
        else if(ruch==2) gracz->Picture->LoadFromFile("img/postacie/gracz/l4.bmp"), ruch++;
        else if(ruch==3) gracz->Picture->LoadFromFile("img/postacie/gracz/l5.bmp"), ruch=0;
        Sleep(80);
        gracz->Left-=20;
        }
        else zmien_mape('l');
}
 

Program się kompiluje i lecz gdy ma dojść do wywołania funkcji zmien_mape(); wywala błąd:

Project raised exception class EAccessViolation with message 'Access violation at addres ### in module 'vcl60.blp'.

Co robię źle?

0

Nikt Ci nie odpowie na to pytanie. Po prostu musisz użyć debuggera i linia po linijce prześledzić działanie programu. Załóż breakpointa na pierwszej linii funkcji zmien_mape i będziesz wiedział gdzie się program wywala. Co więcej będziesz widział wartość zmiennych. Bo taki komunikat sugeruje odnoszenie się do wskaźnika który nie wskazuje na jakiś poprawny obiekt.

0

Problem obszedłem na około w taki sposób:

int id_mapy;
AnsiString zmien_mape()
{
        AnsiString x;
        if(id_mapy==1) return x=("img/tla/1.bmp");
        else if(id_mapy==2) return x=("img/tla/2.bmp");
}
void __fastcall TForm1::lewoTimer(TObject *Sender)
{
        if(gracz->Left>10)
        {

        if(ruch==0) gracz->Picture->LoadFromFile("img/postacie/gracz/l2.bmp"), ruch++;
        else if(ruch==1) gracz->Picture->LoadFromFile("img/postacie/gracz/l3.bmp"), ruch++;
        else if(ruch==2) gracz->Picture->LoadFromFile("img/postacie/gracz/l4.bmp"), ruch++;
        else if(ruch==3) gracz->Picture->LoadFromFile("img/postacie/gracz/l5.bmp"), ruch=0;
        gracz->Left-=20;
        }
        else
        {
                if(id_mapy!=1)
                {
                        gracz->Left = tlo->Width-40;
                        id_mapy--;
                        tlo->Picture->LoadFromFile(zmien_mape());
                }
        }
} 

Tu rodzi się konkretne pytanie.
Dlaczego w własnej funkcji nie mogę zmienić Picture obiektu tło? Jak widać wyżej po przeniesieniu do timera działa poprawnie.

0

Być może chodzi tu o wątki. W Builderze nie wolno zmieniać elementów GUI spoza głównego wątku. A raczej można, tylko trzeba użyć odpowiedniej konstrukcji, chodzi o funkcję Synchronize() Być może tu leży pies pogrzebany?

Ogólnie to widzę, że piszesz kod spaghetti. Dodatkowo używasz funkcji globalnych. Co też wprowadza dodatkowy bałagan w kodzie. Warto by już na samym początku wydzielić to do oddzielnej klasy. Wtedy kod będzie łatwiejszy w zrozumieniu i rozwijaniu.

1 użytkowników online, w tym zalogowanych: 0, gości: 1