2011-09-09 29 views
10

Oyun döngüsünde sabit hızın ayarlanması kavramlarını anlamaya çalışmak. Başım ağrıyor. deWiTTERS page'u okudum, ama neden/nasıl ... anladığımda göremiyorum ... kayıyor. Zaman tabanlı döngü ve Çerçeve tabanlı döngü

while(true) 
{ 
     player->update() ; 
     player->draw() ; 
} 

Bu

bir işlemci ne kadar hızlı bağlı olarak mümkün olduğunca hızlı çalışacak ... Anladım. Tüm bilgisayarlarda aynı hızda çalıştırmak için

, mantık ben alamadım budur. 60 fps'de koşmaya çalışıyorum, o zaman her 16 ms için nesneler bir çerçeve tarafından hareket eder, evet? Ne anlamadığım, update() veya draw()'un çok yavaş olabileceğidir.

deWiTTERS örneği (60 ile kullanılır): o döngü başlamadan önce geçerli zamanı alır neden anlamıyorum

const int FRAMES_PER_SECOND = 60; 
const int SKIP_TICKS = 1000/FRAMES_PER_SECOND; 

DWORD next_game_tick = GetTickCount(); 
// GetTickCount() returns the current number of milliseconds 
// that have elapsed since the system was started 

int sleep_time = 0; 

bool game_is_running = true; 

while(game_is_running) { 
    update_game(); 
    display_game(); 

    next_game_tick += SKIP_TICKS; 
    sleep_time = next_game_tick - GetTickCount(); 
    if(sleep_time >= 0) { 
     Sleep(sleep_time); 
    } 
    else { 
     // Shit, we are running behind! 
    } 
} 

. Ve SKIP_TICKS tarafından art arda döndüğünde, sonraki 16 ms aralığına artış olduğunu anlıyorum. Ama ben bu bölümü de anlamıyorum: Sleep(sleep_time)Sleep(sleep_time) ne anlama geliyor? İşlemci döngüyü terk ediyor ve başka bir şey mi yapıyor? 60 fps ile nasıl çalışır? 60fps'de tek bir kare aralığından daha kısa bir süre içinde tam

durumlarda
+0

http://msdn.microsoft.com/en-us/library/ms686298%28v=vs.85%29.aspx – Lucian

+0

http://msdn.microsoft.com/en-us/library/ms724408%28v = vs% 85 29.aspx – Lucian

+0

Teşekkürler, GetTickCount() 10-16ms arasında dönmek ister misiniz evet? Ama bunun yerine sonuç olarak 324505599 gibi şeyler görüyorum ... "GetTickCount işlevinin çözünürlüğü, genellikle 10 milisaniye ile 16 milisaniye arasında olan sistem zamanlayıcısının çözünürlüğü ile sınırlıdır." Demek ne anlama geliyor? –

cevap

5

burada update_game() ve display_game() işlev, döngü bu aralık dolana kadar uyku, bir sonraki çerçeve işlenmez sağlamak için çalışır (bloke iş parçacığı) fazla çerçeve süresini keser. Kare hızının 60FPS'ye kadar ve daha yüksek olmamasını sağlamaya çalışıyor gibi görünüyor.

işlemci ziyade uyku saatine kadar (kodunuzun devam yürütülmesi engellenir) sizin döngü engellenir çalıştığı iplik 'döngü terk edin' değildir doldu. Daha sonra bir sonraki kareye devam eder. Bir çok iş parçacıklı oyun motorunda, ana oyun döngüsünün iş parçacığının bu şekilde uyutulması, CPU'nun diğer iş parçacıklarında kod çalıştırmasına izin verir, bu da kurmaya bağlı olarak fizik, AI, ses karıştırma vb.

Neden döngü başlamadan önce GetTickCount'u() denir? Kodunuzdaki yorumdan, sistem önyüklemesinden bu yana GetTickCount() öğesinin milisaniye değerini döndürdüğünü biliyoruz.

Yani programını başlatmak ve en biz vermedi döngü, girmeden önce çağrı GetTickCount() ancak bunun yerine başlatıldı diyelim sistem 30 saniye (30,000ms) çalışmakta olduğu söylemek sağlar next_game_tick

0'a Biz güncelleme yapmak ve daha sonra (bir örnek olarak, onlar 6ms almak) çağrıları çizmek ve:

next_game_tick += SKIP_TICKS; // next_game_tick is now 16 
sleep_time = next_game_tick - GetTickCount(); 

// GetTickCount() returns 30000! 
// So sleep_time is now 16 - 30000 = -29984 !!! 

biz sleep_time pozitif olduğunda (makul) sadece uyku, oyun döngü yana hızlı koşar Mümkün olan (potansiyel olarak 60FPS'den daha hızlı), .

+0

Ancak, her iki işlev de 16 ms'den daha az bir sürede tamamlanırsa, uykuya geçmeyebilir çünkü if (sleepTime> 0) doğru olmayabilir ..? –

+1

Takip eden sorunuzu anladığımdan emin değilim, bu yüzden ilk kareyi bir örnek olarak ele alalım ve next_game_tick'in 0'da başladığını varsayalım. Şimdi, güncelleme ve gösterimin 6 ms içinde yapıldığını varsayalım. next_game_tick daha sonra 16'ya yükseltilir. Şimdi sleep_time 16 - GetTickCount() = 16 - 6 = 10. Yani bir sonraki kareye geçmeden önce uyuyabilmek için 10 milisaniye var. –

+1

GetTickCount() öğesinin dönüş değeri kodunuzdaki bir açıklamada açıklanmıştır ;-) '... sistemin başlatılmasından bu yana geçen milisaniye', yani makinenizin başlatılmasından bu yana geçen süre. –