akwes Temat założony przez niniejszego użytkownika |
[SFML] Trzęsienie się sf::Sprite gdy powinien tkwić w bezruchu. » 2013-09-17 21:07:32 Witam :) Problem wygląda tak: mam klasę, która porusza sobie sf::Spritem ale co 32 piksele starając się robić płynną animację przejścia z jednego miejsca do drugiego. Można założyć, że porusza się po szachownicy o polach 32x32 piksele. Animacja faktycznie wychodzi z grubsza płynnie. Jednak kiedy włączę pauzę w trakcie trwania animacji to sf::Sprite trzęsie się. Klasa class GridSprite { sf::Texture myTexture; sf::Sprite mySprite; sf::Vector2f delta; sf::Vector2f nextPosition; sf::Vector2f oldPosition; bool animation; float animationProgress; float animationSpeed; void startAnimation() { animation = true; animationProgress = 0; oldPosition = mySprite.getPosition(); delta = nextPosition - oldPosition; } public: GridSprite() : animation( false ) , animationSpeed( 3.f ) { myTexture.loadFromFile( "sprite.png" ); mySprite.setTexture( myTexture ); } void logic( float time ) { if( animation ) { mySprite.setPosition( oldPosition +( delta * animationProgress ) ); animationProgress += time * animationSpeed; if( animationProgress > 1.f ) { animation = false; mySprite.setPosition( nextPosition ); } return; } if( sf::Keyboard::isKeyPressed( sf::Keyboard::Key::D ) ) { nextPosition.x = mySprite.getPosition().x + 32; startAnimation(); } } void draw( sf::RenderWindow & app ) { app.draw( mySprite ); } };
Kod: int main() { sf::RenderWindow app( sf::VideoMode( 800, 600, 32 ), "Testing" ); app.setFramerateLimit( 60 ); GridSprite gs; sf::Clock clock; bool gameRunning = true; while( app.isOpen() ) { sf::Event ev; while( app.pollEvent( ev ) ) { if( ev.type == sf::Event::Closed ) app.close(); if( ev.type == sf::Event::KeyPressed && ev.key.code == sf::Keyboard::P ) gameRunning = !gameRunning; } if( gameRunning ) { app.clear( sf::Color::Black ); gs.logic( clock.restart().asSeconds() ); gs.draw( app ); } app.display(); } return 0; }
Efekt działania na video: download. (chciałem wrzucić na YT ale tamtejsza kompresja sprawia, że tego efektu nie widać na filmie) (martwi mnie rozmiar pliku, bo ma tylko 88 kB, w każdym razie kodek użyty do kompresji tego avi to Xvid MPREG-4 Codec) Co przegapiłem? Gdzie walnąłem byka? |
|
pekfos |
» 2013-09-17 21:24:56 Spróbuj wciągnąć app.display() do warunku if(gameRunning). |
|
Wasilek |
» 2013-09-17 21:29:14 Nie wiem co jest bezpośrednią przyczyną tego drgania, ale warto kilka rzeczy zmienić/dodać. 1. if( ev.type == sf::Event::KeyPressed && ev.key.code == sf::Keyboard::P ) { gameRunning = !gameRunning; clock.restart(); }
2. animationProgress += time * animationSpeed; mySprite.setPosition( oldPosition +( delta * animationProgress ) );
3. if( animationProgress >= 1.f )
|
|
akwes Temat założony przez niniejszego użytkownika |
» 2013-09-17 21:38:49 @Wasilek, to tylko kod pokazujący problem mający niewiele wspólnego z projektem, także nie warto się rozdrabniać nad niczym takim :P
@pekfos, no tak, to by pomogło, tylko że jeżeli chciałbym wyświetlić napis "Pauza" albo cokolwiek innego (np. przeźroczyste menu), to już nie będę mógł.
Zastanawia mnie czemu sf::Sprite zmienia swoją pozycję w trakcie pauzy mimo, że żaden kod się do niego nie odwołuje (oczywiście pozycja sf::Sprite::getPosition również jest stała). |
|
Wasilek |
» 2013-09-17 22:08:29 Skompilowałem u siebie i nie mam żadnych problemów po włączeniu pauzy. Może to nie jest problem z kodem, lecz z komputerem. |
|
MrPoxipol |
» 2013-09-17 22:12:33 Zaokrąglaj ustawianą pozycję (niby pozycja na liczbie rzeczywistej nie powinna robić problemu, ale na niektórych komputerach tak się dzieje). Miałem tak w swoim toolbarze, podczas wysuwania grafika drgała. IMO to wygląda na bug w SFML, ale nie jestem tego pewnien. Najlepszy sposób na błędy w rysowaniu? ... Ustawić sprajta na niecałkowitej pozycji np. 245.5, 10.1..Objawem są najczęściej zdeformowane grafiki (a również drgania).
Wszystko przez niezaokrąglanie wyliczonych współrzędnych obiektu ;) |
.. Grafika na różnych komputerach była zdeformowana w innym miejscu, może to zależne od karty graficznej i może trochę od systemu (co jest zresztą bardzo ciekawe). Dla przykładu: notebook Win7 karta ATI Radeon - wszystko jest OK (i to właśnie było zwodnicze), starszy komputer z kartą starego typu Win XP - grafika w jednym miejscu jest zdeformowana i przy jej animacji (interpolacja liniowa dla płynnego wejścia) grafika się trzęsie, zaś na tym samym komputerze pod Linuksem - zdeformowana grafika w tym samym miejscu co wcześniej, ale brak trzęsień. Co ciekawe na dużo mocniejszym komputerze od wcześniejszych (nie pytałem jakie GPU) grafika posiada skazę w całkiem randomowym miejscu. Tak, więc moja rada: Stawiajcie swoje sprajty na całkowitych pozycjach! :D jak będę miał czas to napisze temat z rozwiązaniem jakby ktoś, kiedyś miał podobny problem :) | http://cpp0x.pl/forum/temat/?id=4756&p=456 |
|
DejaVu |
» 2013-09-17 23:04:41 Zapewne implementacja metody display może sporo powiedzieć dlaczego występują drgania. Scena w końcu się nie zmienia, ale być może położenie kamery jest ponownie obliczane i pojawiają się małe niedokładności w obliczeniach związane z precyzją floatów. |
|
akwes Temat założony przez niniejszego użytkownika |
» 2013-09-17 23:19:26 Ciekawe, przed wysłaniem kilka razy sprawdzałem czy zaokrąglanie jednostek cokolwiek zmienia i nie zmieniało. Jednak wygląda na to, że w przykładzie, który podałem zaokrąglanie jednostek naprawia problem.
Nigdy wcześniej nie było też z tym problemu. Wyczuwam światowy spisek.
// Hm... Co ciekawe, w głównym projekcie faktycznie zmiana pozycji sprajta na całkowitą nie pomaga. No nic, będę musiał pogrzebać dalej. |
|
« 1 » 2 |