Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

[SFML, C++] Algorytm skalowania

Ostatnio zmodyfikowano 2011-08-25 12:48
Autor Wiadomość
Dawidsoni
Temat założony przez niniejszego użytkownika
[SFML, C++] Algorytm skalowania
» 2011-08-22 13:28:58
Witam. Ostatnio napisałem scrollbara pod SFML. W zależności, czy jest pionowy, czy poziomy chcę skalować jego tło i to coś do przesuwania. Napisałem więc tak:
C/C++
void scrollbar::zmien_rozmiar_tla( int ile_px ) {
    if( czy_poziomy ) {
        sk_s_tla = ile_px / szerokosc_tla();
        rysuj_tlo.SetScale( sk_s_tla, 1 );
    } else {
        sk_w_tla = ile_px / wysokosc_tla();
        rysuj_tlo.SetScale( 1, sk_w_tla );
    }
    ustaw_pozycje( x, y );
}

void scrollbar::zmien_rozmiar_scrollbara( int ile_px ) {
    if( czy_poziomy ) {
        sk_s_sb = ile_px / szerokosc_sb();
        rysuj_scroll.SetScale( sk_s_sb, 1 );
    } else {
        sk_w_sb = ile_px / wysokosc_sb();
        rysuj_scroll.SetScale( 1, sk_w_sb );
    }
    ustaw_pozycje( x, y );
}
1 metoda przedłuża scrollbar o żądaną ilość px. Potem trzeba ustawić pozycje innych elementów względem tła. To samo w metodzie 2, tylko z tym przesuwakiem.

Niestety w programie pisząc np. scrollbar.GetWidth() funkcja zwraca mi długość nie przeskalowanego obrazu. Dlatego napisałem 4 funkcje:
C/C++
float wysokosc_tla( void ) {
    return tlo.GetHeight() * sk_w_tla;
}
float szerokosc_tla( void ) {
    return tlo.GetWidth() * sk_s_tla;
}
float wysokosc_sb( void ) {
    return scroll.GetHeight() * sk_w_sb;
}
float szerokosc_sb( void ) {
    return scroll.GetWidth() * sk_s_sb;
}

Teraz w innych funkcjach zamiast pisać np. scroll.GetHeight() piszę wysokosc_sb(). Np. :
C/C++
bool czy_nacisnieto_y( const Input & przycisk ) {
    Vector2f punkt = rysuj_scroll.TransformToLocal( Vector2f(( float ) przycisk.GetMouseX(),( float ) przycisk.GetMouseY() ) );
    if(( punkt.y >= 0 && punkt.y <= wysokosc_sb() ) && przycisk.IsMouseButtonDown( Mouse::Left ) )
         return true;
    else
         return false;
   
}

Niestety algorytm mi działa tylko przy powiększaniu przesuwaka i tła. Do tego jeśli zwiększę je kilkakrotnie to jest pewna niedokładność. Nie wiem dlaczego czasem trudno też złapać za suwak. Myślę, że jest to problem z funkcją sprawdzającą, czy kliknięto na niego.

Dlaczego tak się dzieje? Proszę o pomoc. Jak nie wiecie, to proszę o jakiś inny algorytm.



P-39673
DejaVu
» 2011-08-22 13:43:54
Dokumentacja
SpriteUmożliwia wykonywanie różnych przekształceń sprajtów jak i rysowanie ich na ekranie. (klasa)
GetSizeZwraca aktualny rozmiar sprajta. (metoda)
P-39674
Dawidsoni
Temat założony przez niniejszego użytkownika
» 2011-08-22 13:46:59
Rzeczywiście. Zmienię te miejsca w programie i napiszę, czy teraz działa. Może gdzieś właśnie w tych moich funkcjach są błędy.

edit:

Nadal to samo.
P-39675
DejaVu
» 2011-08-22 15:16:44
Antyaliasing może powodować tą pewną niedokładność - wyłącz go.
P-39676
Dawidsoni
Temat założony przez niniejszego użytkownika
» 2011-08-22 18:11:10
Zrobiłem to tak:
C/C++
strzaka.SetSmooth( false );
scroll.SetSmooth( false );
tlo.SetSmooth( false );
rysuj_strzalke.SetImage( strzaka );
rysuj_strzalke_2.SetImage( strzaka );
rysuj_strzalke_2.Rotate( 180 );
rysuj_scroll.SetImage( scroll );
rysuj_tlo.SetImage( tlo );
i nie działa dalej. Są 2 problemy:
1. Jeśli rozszerzam suwak to jeśli za niego ciągnę to nie reaguje na stronę po prawej, która powstała w wyniku skalowania (jeśli scrollbar jest poziomy).
2. Rozszerzony suwak wychodzi poza swoje pole (poza tło i poza strzałkę po prawej stronie (jeśli scrollbar jest poziomy)).

Co do 1 to może być problem z tą funkcją:
C/C++
bool scrollbar::czy_nacisnieto( const Input & przycisk ) {
    Vector2f punkt = rysuj_scroll.TransformToLocal( Vector2f(( float ) przycisk.GetMouseX(),( float ) przycisk.GetMouseY() ) );
    if(( punkt.x >= 0 && punkt.y >= 0 && punkt.x <= rozmiar_scrollbara.x && punkt.y <= rozmiar_scrollbara.y ) && przycisk.IsMouseButtonDown( Mouse::Left ) )
         return true;
    else
         return false;
   
}

A co do 2 nie mam pojęcia.

edit:

Co do 2 to jest kilka pikseli, więc nie problem, ale z tym 1 to tragedia.
P-39682
DejaVu
» 2011-08-22 18:25:20
No ale to raczej nie jest problem skalowania SFML tylko Twoich złych obliczeń związanych ze scrollem :)

/edit:
Poza tym co rozciągasz? Scrolla czy okno? Jeżeli okno to w kursie został ten przypadek również omówiony: » Kurs SFML 1.6, C++Tworzenie i wyświetlanie sprajtów lekcja.
P-39683
Dawidsoni
Temat założony przez niniejszego użytkownika
» 2011-08-22 18:31:29
Chcę skalować skrollbara. Pewnie moich złych obliczeń, ale problem w tym, że nie mogę ich znaleźć. Algorytm i cała reszta wydają się dobre.

edit:

Znalazłem 1 problem:
Mam 2 funkcje:
C/C++
int zamien_x( const Input & przycisk ) {
    Vector2f punkt = rysuj_scroll.TransformToLocal( Vector2f(( float ) przycisk.GetMouseX(),( float ) przycisk.GetMouseY() ) );
    cout << punkt.x << endl;
    return punkt.x;
}
int zamien_y( const Input & przycisk ) {
    Vector2f punkt = rysuj_scroll.TransformToLocal( Vector2f(( float ) przycisk.GetMouseX(),( float ) przycisk.GetMouseY() ) );
    return punkt.y;
}
Zwracają one, na który pixel paska kliknąłem licząc od 0. Jeśli scrollbar jest poziomy używam 1 funkcji, a jeśli pionowy to 2 funkcji. Jeśli suwak ma 50 px (nie skaluję go) to jeśli kliknę na jego środek to jest dobrze - pisze mi 25px. Wszystko jest OK.

Teraz rozszerzam suwak do 250px. Klikam na jego środek i piszę, że kliknąłem na 22 pixel. (kliknąłem na 125 pixel). Myślę, że to jest ta rzecz, która popsuła mi dzień. Teraz spróbuję to naprawić.

edit:

Działa! Pomnożyłem to razy skalę.

Tylko nie wiem czemu mimo instrukcji:
C/C++
rysuj_tlo.SetPosition( x + strzaka.GetWidth(), y );
rysuj_scroll.SetPosition( x + strzaka.GetWidth(), y );
Po przeskalowaniu kilkadziesiąt razy scrolla odstaje o kilka px od tła!!! To jest bardzo dziwna rzecz! Może ktoś wyjaśni dlaczego źle rozumowałem w poprzednim problemie i dlaczego źle rozumuję przy tym problemie. (przesunąłem tło, strzałke o 0.37 * skala pixeli i jest idealnie). ale chcę wiedzieć dlaczego było źle!
P-39685
DejaVu
» 2011-08-25 12:48:24
Chyba nadal źle rozumujesz :) Jeszcze raz powiem Ci: przeczytaj rozdział kursu, który już wcześniej podałem.
P-39913
« 1 »
  Strona 1 z 1