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

[SFML 2.0] miganie sprite

Ostatnio zmodyfikowano 2013-10-26 10:28
Autor Wiadomość
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:

C/C++
otwarcie_walizki( i, walizka_graj[ i ], okno, pf_otwarcie_walizki[ i ] );

Funkcja:
C/C++
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.
P-94155
RazzorFlame
» 2013-10-20 20:22:38
Podaj kod petli głownej.
P-94158
oputyk
Temat założony przez niniejszego użytkownika
» 2013-10-20 20:26:18
C/C++
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 ] ); //to tutaj
            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:
C/C++
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;
    }
};
P-94160
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.
P-94177
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.
P-94180
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 )
P-94251
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).
P-94264
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ź.
P-94330
« 1 » 2
  Strona 1 z 2 Następna strona