Zaman Yönetimi

Zamanın özellikle gerçek zamanlı uygulamalarda doğru şekilde yönetilmesi önemlidir. SFML'de zamanı ölçmek için sf::Clock sınıfı kullanılır. Bu fonksiyon iki fonksiyonu tanımlar: saati yeniden başlatan Reset() ve Reset()'in son çağırılışından o ana dek geçen süreyi gösteren GetElapsedTime(). Zaman, saniye olarak tanımlıdır.
sf::Clock Clock; 
while (App.IsOpened())
{
    // Olayları işle... 
    // Son döngüden sonra geçen süre
    float Time = Clock.GetElapsedTime();
    Clock.Reset(); 
    // Pencereyi göster...
}
Geçen zamanı bilmek eğer bir değişkenin değerini (konum vb. için) her döngüde artırmak istiyorsanız çok önemlidir. Eğer zaman faktörünü dikkate almazsanız simülasyonunuz saniyede 60 karede ya da saniyede 1000 karede çalışırken aynı sonucu vermeyecektir. Örneğin aşağıdaki kod kare oranına bağlıdır:
const float Speed = 50.f;
float Left = 0.f;
float Top  = 0.f; 
while (App.IsOpened())
{
    if (App.GetInput().IsKeyDown(sf::Key::Left))  Left -= Speed;
    if (App.GetInput().IsKeyDown(sf::Key::Right)) Left += Speed;
    if (App.GetInput().IsKeyDown(sf::Key::Up))    Top  -= Speed;
    if (App.GetInput().IsKeyDown(sf::Key::Down))  Top  += Speed;
}
Her donanımda aynı hızı elde etmek istiyorsak:
sf::Clock Clock; 
const float Speed = 50.f;
float Left = 0.f;
float Top  = 0.f; 
while (App.IsOpened())
{
    float ElapsedTime = Clock.GetElapsedTime();
    Clock.Reset(); 
    if (App.GetInput().IsKeyDown(sf::Key::Left))  Left -= Speed * ElapsedTime;
    if (App.GetInput().IsKeyDown(sf::Key::Right)) Left += Speed * ElapsedTime;
    if (App.GetInput().IsKeyDown(sf::Key::Up))    Top  -= Speed * ElapsedTime;
    if (App.GetInput().IsKeyDown(sf::Key::Down))  Top  += Speed * ElapsedTime;
}
Çoğu kez, geçen zamanı son kareden itibaren ölçmeniz gerekir. sf::Window, bir saat oluşturmadan bu zamana erişmeniz için GetFrameTime() isminde faydalı bir fonksiyon sunar. Kodumuzu şu şekilde yazabiliriz:
const float Speed = 50.f;
float Left = 0.f;
float Top  = 0.f; 
while (App.IsOpened())
{
    if (App.GetInput().IsKeyDown(sf::Key::Left))  Left -= Speed * App.GetFrameTime();
    if (App.GetInput().IsKeyDown(sf::Key::Right)) Left += Speed * App.GetFrameTime();
    if (App.GetInput().IsKeyDown(sf::Key::Up))    Top  -= Speed * App.GetFrameTime();
    if (App.GetInput().IsKeyDown(sf::Key::Down))  Top  += Speed * App.GetFrameTime();
}


Kareoranını Ölçmek
Kareoranı, bir kare süresinin tersi olduğundan kareler arasında geçen süreler aracılığıyla kolayca hesaplanabilir:
sf::Clock Clock; 
while (App.IsOpened())
{
    float Framerate = 1.f / Clock.GetElapsedTime();
    Clock.Reset();
}
Ya da:
while (App.IsOpened())
{
    float Framerate = 1.f / App.GetFrameTime();
}
Eğer kareoranınız 60 sbk civarında takılıp kalıyorsa endişelenmeyin. Bu sadece dikey eşzamanlama'nın (vertical synchronization, v-sync) açık olduğundan gerçekleşiyor olabilir. Dikey eşzamanlama aktif olduğunda görüntü, monitörün tazeleme oranıyla eşzamanlanmaktadır. Bu monitörünüzün gösterebileceğinden daha fazla kare elde edemeyeceğiniz anlamına gelmektedir. Bu aslında iyi bir şeydir, uygulamanızın 2000 sbk gibi inanılmaz kareoranlarına çıkmasını, kötü görsel yapıları ve tahmin edilemez davranışları engeller.

Bununla birlikte bazen performans için testler yapmak için en fazla kare oranına çıkmak isteyebilirsiniz. SFML, bunun için size dikey eşzamanlamayı, EnableVerticalSync fonsiyonyla devre dışı bırakma imkanı verir.
App.EnableVerticalSync(false);
Hatırlatmakta fayda var, dikey eşzamanlama öntanımlı olarak devredışıdır.

İsterseniz kareoranını sabit bir değere de ayarlayabilirsiniz:
App.SetFramerateLimit(60); // Saniye başına 60 kare
App.SetFramerateLimit(0);  // Sınırlama yok
Zamana kısaca göz atmış olduk, artık bu konu da bizim için bir bilinmez olmaktan çıkıtığına göre gerçek zamanlı uygulamalar yazmaya daha da yaklaştık demektir.

Gerçekte pek de bir şey yapmayan örneğimizi inceleyelim:



Bu eğitselle ilgili diğer örneklere şu an olmasa da ilerleyen zamanlarda sfml-gelistirme deposundan ulaşabilirsiniz.


Kaynak: Window - Handling time

Yorumlar