oputyk Temat założony przez niniejszego użytkownika |
[SFML 2.0] miganie sprite » 2013-10-20 20:08:18 Jest taki problem, że mam główną pętle gry. Przechodzę do funkcji, w której pozostaje tło, czyli wyrysowane sprity w głównej pętli gry. W tej funkcji wyrysowuję następne elementy, z myślą, że zostanie tło wcześniej wyrysowane. Wtedy pojawia się problem... Opis problemu: Kiedy przechodzę do funkcji, niektóre sprity (wyrysowane w głównej pętli gry) migają... Gdy wychodzę z funkcji i przechodzę znowu do głównej pętli gry, tam problem znika, bo poszczególne elementy już nie migają... Oto kod: Fragment głównej pętli gry: otwarcie_walizki( i, walizka_graj[ i ], okno, pf_otwarcie_walizki[ i ] );
Funkcja: sf::Font font; sf::Event zd; font.loadFromFile( "times.ttf" ); sf::Text liczba( "", font, 60 ); char bufor[ 20 ]; sprintf( bufor, "%f", player.l ); std::string s; s = bufor; if( player.l > 0.01 ) { s.resize( s.size() - 7 ); } else { s.resize( s.size() - 4 ); } s += " $"; liczba.setString( s ); Player p1( "walizkab_graj.png", sf::Color::White ); Player p2( "tylwalizki_graj.png", sf::Color::White ); p1.sprite.setPosition(( 1366 - p1.sprite.getTextureRect().width ) / 2,( 768 - p1.sprite.getTextureRect().height ) / 2 ); p2.sprite.setPosition(( 1366 - p2.sprite.getTextureRect().width ) / 2,( 768 - p2.sprite.getTextureRect().height ) / 2 ); p1.position = sf::Vector2f(( 1366 - p1.sprite.getTextureRect().width ) / 2,( 768 - p1.sprite.getTextureRect().height ) / 2 ); player.sprite.setScale( 6, 6 ); player.sprite.setPosition(( 1366 - 600 ) / 2,( 768 - 330 ) / 2 ); texcenter( liczba, p2 ); player.sprite.setColor( player.color ); sf::Clock czas; czas.restart(); int u; int t = 0; sf::Color e = p1.sprite.getColor(); int o = 255; while( okno.isOpen() ) { if( czas.getElapsedTime().asMilliseconds() < 3000 ) { o = 255 -( czas.getElapsedTime().asMilliseconds() / 10 ); e.a = o; } if( czas.getElapsedTime().asMilliseconds() > 1500 && e.a > 200 ) { e.a = 0; } if( czas.getElapsedTime().asMilliseconds() > 3000 ) { b = false; return true; } p1.sprite.setColor( e ); okno.draw( player.sprite ); okno.draw( p2.sprite ); okno.draw( liczba ); okno.draw( p1.sprite ); okno.display(); } return false;
Jakbym nawet nic nie narysował to też by migało... Proszę o pomoc. |
|
RazzorFlame |
» 2013-10-20 20:22:38 Podaj kod petli głownej. |
|
oputyk Temat założony przez niniejszego użytkownika |
» 2013-10-20 20:26:18 while( okno.isOpen() ) { while( okno.pollEvent( zd ) ) { if( zd.type == sf::Event::MouseButtonReleased && zd.mouseButton.button == sf::Mouse::Left ) { for( int i = 0; i < 26; i++ ) { if( pf_walizka[ i ] == true && walizka_graj[ i ].kolizja_kwadratowa_myszki( sf::Vector2f( sf::Mouse::getPosition().x, sf::Mouse::getPosition().y ) ) ) { if( ruch == 0 ) { obr_walizka.sprite.setColor( col1 ); pierwsza_walizka = walizka_graj[ i ]; ruch++; pf_walizka[ i ] = false; tytul_graj.setString( "Ktora do odstrzalu?" ); tytul_graj.setPosition( texcenter( tytul_graj, gora_graj ).x, texcenter( tytul_graj, gora_graj ).y - 25 ); glowny = walizka_graj[ i ]; texglowny = liczby[ i ]; glowny.sprite.setPosition( ldol_graj.sprite.getPosition().x + 125, ldol_graj.sprite.getPosition().y + 37.5 ); col3 = liczby[ i ].getColor(); col3.a = 0; liczby[ i ].setColor( col3 ); texglowny.setPosition( texcenter( texglowny, glowny ).x, texcenter( texglowny, glowny ).y - 5 ); } else { col2 = walizka_graj[ i ].color; col2.a = 0; obr_walizka.sprite.setColor( col1 ); pf_otwarcie_walizki[ i ] = true; walizka_graj[ i ].sprite.setColor( col2 ); ruch++; pf_walizka[ i ] = false; col3 = liczby[ i ].getColor(); col3.a = 0; zostalo[ i ].l = 0; liczby[ i ].setColor( col3 ); stru = walizka_graj[ i ].string; for( int i = 0; i < 26; i++ ) { if( stru == txtl[ i ].getString() ) { txtl[ i ].setColor( sf::Color::Red ); } } } } } } } for( int i = 0; i < 26; i++ ) { if( pf_otwarcie_walizki[ i ] == true && ruch < 26 ) { otwarcie_walizki( i, walizka_graj[ i ], okno, pf_otwarcie_walizki[ i ] ); tuti = true; } } for( int i = 0; i < 26; i++ ) { if( walizka_graj[ i ].kolizja_kwadratowa_myszki( sf::Vector2f( sf::Mouse::getPosition().x, sf::Mouse::getPosition().y ) ) == false ) { obr[ i ] = false; } if( pf_walizka[ i ] ) { if( walizka_graj[ i ].kolizja_kwadratowa_myszki( sf::Vector2f( sf::Mouse::getPosition().x, sf::Mouse::getPosition().y ) ) == true ) { obr[ i ] = true; obr_walizka.sprite.setPosition( walizka_graj[ i ].sprite.getPosition().x - 2, walizka_graj[ i ].sprite.getPosition().y - 2 ); obr_walizka.sprite.setColor( obrcol ); } } } if( ruch == 25 ) { tytul_graj.setString( "Kasa czy walizka?" ); tytul_graj.setPosition( texcenter( tytul_graj, gora_graj ).x, texcenter( tytul_graj, gora_graj ).y - 25 ); } fl = false; okno.draw( tlo_graj.sprite ); for( int i = 0; i < 26; i++ ) { okno.draw( kwkasa[ i ].sprite ); } for( int i = 0; i < 26; i++ ) { if( obr[ i ] == true ) { okno.draw( obr_walizka.sprite ); } } for( int i = 0; i < 26; i++ ) { if( pf_walizka[ i ] ) { okno.draw( walizka_graj[ i ].sprite ); } } for( int i = 0; i < 26; i++ ) { okno.draw( liczby[ i ] ); } okno.draw( gora_graj.sprite ); for( int i = 0; i < 26; i++ ) { okno.draw( txtl[ i ] ); } okno.draw( ldol_graj.sprite ); okno.draw( tytul_graj ); if( ruch > 0 ) { okno.draw( glowny.sprite ); okno.draw( texglowny ); } if( ruch == 7 && r == false ) { if( res_zeg == false ) { zegar.restart(); res_zeg = true; } if( zegar.getElapsedTime().asMilliseconds() > 300 ) { if( !bankier( okno, zostalo ) ) { ostatnia_walizka( okno, pierwsza_walizka, true ); otwarcie_walizki( 5, pierwsza_walizka, okno, k ); return true; } r = true; } } if( ruch == 8 ) { r = false; res_zeg = false; } if( ruch == 13 && r == false ) { if( res_zeg == false ) { zegar.restart(); res_zeg = true; } if( zegar.getElapsedTime().asMilliseconds() > 300 ) { if( !bankier( okno, zostalo ) ) { ostatnia_walizka( okno, pierwsza_walizka, true ); otwarcie_walizki( 5, pierwsza_walizka, okno, k ); return true; } r = true; } } if( ruch == 14 ) { r = false; res_zeg = false; } if( ruch == 18 && r == false ) { if( res_zeg == false ) { zegar.restart(); res_zeg = true; } if( zegar.getElapsedTime().asMilliseconds() > 300 ) { if( !bankier( okno, zostalo ) ) { ostatnia_walizka( okno, pierwsza_walizka, true ); otwarcie_walizki( 5, pierwsza_walizka, okno, k ); return true; } r = true; } } if( ruch == 19 ) { r = false; res_zeg = false; } if( ruch == 21 && r == false ) { if( res_zeg == false ) { zegar.restart(); res_zeg = true; } if( zegar.getElapsedTime().asMilliseconds() > 300 ) { if( !bankier( okno, zostalo ) ) { ostatnia_walizka( okno, pierwsza_walizka, true ); otwarcie_walizki( 5, pierwsza_walizka, okno, k ); return true; } r = true; } } if( ruch == 22 ) { r = false; res_zeg = false; } if( ruch == 23 && r == false ) { if( res_zeg == false ) { zegar.restart(); res_zeg = true; } if( zegar.getElapsedTime().asMilliseconds() > 300 ) { if( !bankier( okno, zostalo ) ) { ostatnia_walizka( okno, pierwsza_walizka, true ); otwarcie_walizki( 5, pierwsza_walizka, okno, k ); return true; } r = true; } } if( ruch == 24 ) { r = false; res_zeg = false; } if( ruch == 25 && r == false ) { if( res_zeg == false ) { zegar.restart(); res_zeg = true; } if( zegar.getElapsedTime().asMilliseconds() > 300 ) { if( bankier( okno, zostalo ) ) { ost = true; } else { ost = false; ostatnia_walizka( okno, pierwsza_walizka, true ); otwarcie_walizki( 5, pierwsza_walizka, okno, k ); return true; } r = true; } } if( ruch >= 25 && ost ) { ostatnia_walizka( okno, pierwsza_walizka, false ); otwarcie_walizki( 5, pierwsza_walizka, okno, b ); return true; } okno.display();
Jak komuś się chce wiedzieć jak dokładnie jest zbudowana klasa to tu jest kod: class Player { private: public: sf::Sprite sprite; sf::Texture tekstura; sf::Image image; sf::Vector2f position; sf::Color color; float l; float bottom, left, right, top; std::string string; Player( sf::Sprite spr, sf::Vector2f pos = sf::Vector2f( 0, 0 ) ) { sprite = spr; position = pos; sprite.setPosition( position ); color = sprite.getColor(); } Player( sf::Texture tex, sf::Vector2f pos = sf::Vector2f( 0, 0 ) ) { tekstura = tex; sprite.setTexture( tekstura ); position = pos; sprite.setPosition( position ); } Player( sf::Image ima, sf::Vector2f pos = sf::Vector2f( 0, 0 ) ) { image = ima; tekstura.loadFromImage( image ); sprite.setTexture( tekstura ); position = pos; sprite.setPosition( position ); } Player( std::string strplik, sf::Vector2f pos = sf::Vector2f( 0, 0 ) ) { tekstura.loadFromFile( strplik ); sprite.setTexture( tekstura ); color = sprite.getColor(); position = pos; sprite.setPosition( position ); } Player( std::string strplik, sf::Color color, sf::Vector2f pos = sf::Vector2f( 0, 0 ) ) { image.loadFromFile( strplik ); image.createMaskFromColor( color ); tekstura.loadFromImage( image ); sprite.setTexture( tekstura ); color = sprite.getColor(); position = pos; sprite.setPosition( position ); } Player() { } void update() { bottom = sprite.getTextureRect().height + sprite.getPosition().y; left = sprite.getPosition().x; right = sprite.getPosition().x + sprite.getTextureRect().width; top = sprite.getPosition().y; } bool kolizja_kwadratowa( Player p ) { if( right <= p.left || left >= p.right || top >= p.bottom || bottom <= p.top ) { return false; } return true; } bool kolizja_kwadratowa_myszki( sf::Vector2f pos ) { if( sprite.getGlobalBounds().contains( pos ) ) { return true; } else { return false; } } void alakonstruktor( std::string string, sf::Vector2f pos = sf::Vector2f( 0, 0 ) ) { tekstura.loadFromFile( string ); sprite.setTexture( tekstura ); position = pos; color = sprite.getColor(); sprite.setPosition( position ); } void zmiana( float x, float y ) { sprite.setScale( 1 / sprite.getScale().x, 1 / sprite.getScale().y ); sprite.setScale( x / tekstura.getSize().x, y / tekstura.getSize().y ); } void przetworz() { char bufor[ 20 ]; sprintf( bufor, "%f", l ); string = bufor; if( l > 0.01 ) { string.resize( string.size() - 7 ); } if( l <= 0.01 ) { string.resize( string.size() - 4 ); } string += " $"; } float pokaz_l() { return l; } };
|
|
DejaVu |
» 2013-10-21 08:36:33 Najpierw rysuj tło, a potem wszelkie elementy na nim. W SFML-u nic nie może Ci migać, bo:
1) podwójne buforowanie jest częścią integralną SFML-a, stosując domyślną metodę tworzenia okna
2) Rysowanie tekstur w złej kolejności spowoduje co najwyżej, że będą one przesłonięte.
3) Tekstury mogą co najwyżej wyświetlać się w naprzemiennej kolejności ale tylko wtedy, gdy będziesz zmieniał kolejność ich wyświetlania np. poprzez sortowanie listy obiektów
4) Sprawdź najpierw czy 'miga' Ci przykład z tutoriala.
5) Migający sprajt mógłby się również pojawić wtedy, gdybyś rysował coś w pętli z eventami, ale tego (chyba) nie robisz -> eventy nie przychodzą co każdy obieg pętli, stąd sprajt by się wyświetlał tylko gdybyś np. ruszał myszką nad oknem lub wciskał klawisze. |
|
maly |
» 2013-10-21 09:21:16 Dodam jeszcze że nie powinieneś w dwóch miejscach używać okno.display(); co wielce prawdopodobnie jest przyczyną migania. |
|
domin568 |
» 2013-10-21 20:55:59 Najlepiej jeżeli napisalbys to obiektowo, bo trudno jest połapać sie o co chodzi w tym kodzie (kiedyś myślałem "będę to pisał tak żeby działało, potem nic z tego kodu nie rozumiałem, i w trakcie pisania kodu miałem duże problemy, przy pisaniu obiektowym wszystko staje sie prostsze) @maly można używać 2 razy display () jednak jeżeli są one w osobnych pętlach ( while (okno.isOpen())) ( np osobna karta menu ) |
|
DejaVu |
» 2013-10-21 23:31:40 @domin568: on nie kwestionował dwóch wystąpień display w kodzie, tylko wskazywał na inną, alternatywną przyczynę występowania efektu migania (zresztą słuszny argument podał, ale chyba ten scenariusz nie zachodzi w przypadku zamieszczonego kodu). |
|
oputyk Temat założony przez niniejszego użytkownika |
» 2013-10-22 19:30:55 Ja bardzo dobrze wiem, że lepiej by było, gdybym napisał to obiektowo, ale napisałem moją pierwszą grę graficznie i po prostu to jest nauczka, aby pisać obiektowo, a nie przez funkcje. Kod miał w sumie 1600 linijek, a już po jakichś 700 był problem z odnalezieniem się w tym kodzie. Więc wiem - obiektowość przy następnych projektach. Ale wracając do problemu z miganiem, to problem pojawiał się wtedy, gdy jakiś obrazek zmieniał się dynamicznie (np. gdy użytkownik najedzie na dany sprite i chce zmienić mu wtedy kolor). W takiej sytuacji sprite migał - a dokładniej migając zmieniał kolory, raz taki, a raz taki. Oczywiście ten cały problem występował, tak jak napisałem wcześniej - w sytuacji, kiedy wchodzę w funkcję. Jeśli ktoś chce wiedzieć po co taka operacja była mi potrzebna to mogę ją opisać: A więc tak... Toczy się gra... Sprite się ruszają itd. W pewnym momencie gra się zatrzymuje i wyskakuje okienko - choćby wejście w menu. W takim momencie fajnie by było kiedy to całe okienko załatwia niezależna funkcja. Wywołuje się nią i po prostu w pewnym momencie się ona kończy, a rozgrywka w głównej pętli gry trwa dalej... Wszystko pięknie by było, gdyby te sprity nie migały. Miałem pewien pomysł, aby skopiować i przesłać do funkcji texture z sf::RenderWindow, ale to bardzo długo trwa, więc jest to zły pomysł... Następnym pomysłem co ostatnio mi się nasunął jest napisanie klasy, która by miała składnik sf::RenderWindow oraz sf::RenderTexture i to na nich wyrysowywałoby się te sprity. Tylko, że jeszcze tego nie sprawdzałem, więc nie wiem, czy zwracanie textury z sf::RenderTexture spełniło by moje oczekiwania, dotyczące szybkości... No i oto cała historia. Nie wiem, czy ktoś to wszystko przeczytał, ale jeśli tak to serdecznie dziękuje za zainteresowanie moim problemem. Z góry dzięki za odpowiedź. |
|
« 1 » 2 |