Oyun için her ne kadar amatör de olsa, bana göre şimdilik yetersiz olan oyun döngüsü ve zamanlayıcı için daha iyi alternatifler arama çabalarım sürüyor :)
Ali beyle bu XNA'in oyun için kullandığı zamanlayıcı nasıl çalışıyor diye konuşuyorduk.
Game Timing in XNA Game Studio 2.0 (http://blogs.msdn.com/b/shawnhar/archive/2007/11/23/game-timing-in-xna-game-studio-2-0.aspx)
Yalnız konuya yabancı olan arkadaşlar için belirli kavramları biraz daha açmak istiyorum. Örneğin oyunumuz 60 kare/saniye FPS'de çalışacak olsun. Bu demekki her saniyede 60 kare çizilecek.
1sn = 1000 ms (milisaniye)
1ms = 1000 ns (nanosaniye)
Saniyede 60 kare çizmek istediğimize göre 1000/60 ms = 16.7 milisaniyede bir kare çizdirmek isteyeceğiz.
XNA'in 1.0 sürümünde sistem şu şekilde çalışıyormuş:
- 60 FPS'de çalışan VSYNC açık 75hz'de çalışan bir monitörümüz var
- güncelle diyelim ki 3 milisaniyede
- çiz 5 milisaniye
- toplam 8 milisaniye tamamlanmış oldu.
- 60 FPS için zaman aralığı 16.7 ms ve süre dolmadığı için tekrar bir güncelleme yapmıyor
- çiz tekrar çağrılıyor
- VSYNC açık olduğu için ekran kartının sürücüsü 13 ms daha bekliyor
- bu yüzden geç kalmış olduk.
Yani süre tamamlanana kadar 'çiz()' metodunu tekrar tekrar çağırıyormuş.
XNA 2.0 sürümünde doğru anladıysam örneğin 'güncelle()' işlevini tam olarak 3ms'de, 'çiz()' 5ms'de ve geriye kalan 8.7 saniyede bekliyormuş.
Ben de Ali beye örneğin sistemi tam olarak sistemi 3ms nasıl bekletebiliriz diye sormuştum. Hatta bu konuda daha önceden yazdığım bir test programını incelemek isteyebilirsiniz.
https://github.com/erdemoncel/oyun/blob/master/src/test.d
Ali bey de güzel bir örnek yazmış. Bunu sizinle paylaşmak istedim. Ve işin güzel tarafı dilin kendi olanaklarını kullanıyor ve daha hassas bir ölçüm yapıyor. Buradaki birim ne bilmiyorum ama karşılıkları şu şekilde:
'
1 nanosaniye = 1/100
1 mikrosaniye = 10
1 milisaniye = 10_000
1 saniye = 10_000_000
'
import std.stdio;
import core.thread;
import std.datetime;
void main()
{
ulong[TickDuration] histogram;
foreach (i; 0 .. 100) {
StopWatch kronometre;
kronometre.start();
Thread.sleep(30_000); // 3ms bekle
kronometre.stop();
auto geçenSüre = kronometre.peek();
++histogram[geçenSüre];
/*
sleep'in bütün kullanımları:
Thread.sleep(1000); // 100 mikrosaniye
Thread.sleep(dur!"msecs"(10)); // 10 milisaniye
Thread.sleep(dur!"seconds"(1)); // 1 saniye
*/
}
foreach (geçenSüre, adet; histogram) {
writeln(geçenSüre.usecs, ": ", adet);
}
}
--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]