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: 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: 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. : 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. |
|
DejaVu |
» 2011-08-22 13:43:54 Dokumentacja |
---|
Sprite | Umożliwia wykonywanie różnych przekształceń sprajtów jak i rysowanie ich na ekranie. (klasa) |
---|
GetSize | Zwraca aktualny rozmiar sprajta. (metoda) |
---|
|
|
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. |
|
DejaVu |
» 2011-08-22 15:16:44 Antyaliasing może powodować tą pewną niedokładność - wyłącz go. |
|
Dawidsoni Temat założony przez niniejszego użytkownika |
» 2011-08-22 18:11:10 Zrobiłem to tak: 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ą: 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. |
|
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: Tworzenie i wyświetlanie sprajtów. |
|
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: 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: 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! |
|
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. |
|
« 1 » |