Witam. Mam pewien problem przy wyświetlaniu w grze. Otóż w momencie, kiedy ustawiam blokadę klatek (np. na 60) - obraz w pewnych momentach zaczyna się przycinać. Kompletnie nie mam pomysłu, czego to może być wina, pewnie ja coś robię źle, albo nie robię czegoś, co powinienem. Korzystam z biblioteki graficznej SFML i kompiluję na Code::Blocks, ale próbowałem również na Visual Studio 2015. Próba przerzucenia się na openFrameworks-a nie pomogła - problem został ten sam mimo, iż tam kod wyglądał nieco inaczej. Próbowałem interpolacji, ale to też nic nie dało (pewnie dlatego, że w przykładzie, który podam poniżej ruch gracza wykonuje się częściej bądź z tą samą częstotliwością, co wyświetlanie). Próbowałem zamienić float-a na int-a i operować przy pozycji gracza na dużych wartościach (dla większej dokładności, bo float może źle zaokrąglać), ale bez skutku. Poniżej kod przykładowego programu:
#include <SFML/Graphics.hpp>
#define FRAMERATE 60
#define ENGINE_TICKS 600
#define SCREEN_WIDTH 1280
#define SCREEN_HEIGHT 720
using namespace std;
using namespace sf;
float PosX = 0;
float PosY = 0;
float Speed;
void Move( Int64 Time )
{
Speed = 0.0005 * Time;
if( Keyboard::isKeyPressed( Keyboard::A ) )
PosX -= Speed;
if( Keyboard::isKeyPressed( Keyboard::W ) )
PosY -= Speed;
if( Keyboard::isKeyPressed( Keyboard::D ) )
PosX += Speed;
if( Keyboard::isKeyPressed( Keyboard::S ) )
PosY += Speed;
if( PosX < 0 )
PosX = SCREEN_WIDTH;
else if( PosX > SCREEN_WIDTH )
PosX = 0;
if( PosY < 0 )
PosY = SCREEN_HEIGHT;
else if( PosY > SCREEN_HEIGHT )
PosY = 0;
}
int main()
{
RenderWindow window( VideoMode( SCREEN_WIDTH, SCREEN_HEIGHT ), "Lag Test" );
window.setFramerateLimit( ENGINE_TICKS ); // Blokada predkosci silnika
Texture texture;
texture.loadFromFile( "player.png" );
Sprite sprite;
sprite.setTexture( texture );
Clock GameClock;
Time GameTime;
Clock FramerateClock;
Time FramerateTime;
// Glowna petla gry
while ( window.isOpen())
{
Event event;
while ( window.pollEvent( event ) )
{
if ( event.type == Event::Closed )
window.close();
}
// Czas w grze
GameTime = GameClock.getElapsedTime();
GameClock.restart();
// Ruch
Move( GameTime.asMicroseconds() );
// Blokada klatek
static int Frame = 0;
FramerateTime = FramerateClock.getElapsedTime();
if( FramerateTime.asMicroseconds() >= ( float( 1000000 / FRAMERATE ) * Frame ) )
{
if( FramerateTime.asMicroseconds() >= 1000000 )
{
FramerateClock.restart();
Frame = 0;
}
Frame++;
//Wyswietlanie
window.clear( Color( 0, 255, 255 ) );
sprite.setPosition( PosX, PosY );
window.draw( sprite );
window.display();
}
}
return 0;
}
To jest przykład napisany przeze mnie na podstawie kodu ze strony SFML-a: http://www.sfml-dev.org/tutorials/2.3/start-cb.php. U znajomego w grze problem przycinania również się pojawiał (zupełnie niezależny projekt od mojego). Próbowałem już różnych modeli pętli głównej gry, ale przy tym efekt był najmniej widoczny.
Myślę, że to najważniejsze informacje dotyczące problemu. Ewentualnie, jeszcze jeżeli chodzi o moje obserwacje to np. jeśli w if-ie, gdzie wyświetlam obraz wstawiłem cout-a, który wyświetla w konsoli cokolwiek (np. pozycję gracza), to w momentach przycinania tekst w konsoli również poddany był temu efektowi, gdy zaś próbowałem blokady do 80 FPS-ów, to przycinki były regularne (nieco słabsze od tych przy 40 klatkach), a problem oczywiście przestaje być widoczny przy odpowiednio wysokim limicie klatek. Mam wrażenie, jakby niektóre klatki były generowane z opóźnieniem i stąd to wrażenie "przeskakiwania" gracza.
Dodam jeszcze, że szukałem różnych poradników i przeszukiwałem to forum, ale nie znalazłem podobnego tematu, ani żadnej pomocnej informacji.
Z góry dziękuję za pomoc i wyrozumiałość :)