Delta zamanı nasıl alınır ve kullanılır?


14

Oyunumda görünen ve yürüyen farelerim var, ama çok yavaş ve kullanımı zor. Sanırım bunun nedeni sabit hız kullanıyorum. Büyük projelerde geliştiricilerin delta zamanı kullandıklarını duydum. Glutta delta süresini nasıl hesaplayabilirim? Delta zamanını kullanarak hızı nasıl hesaplayabilirim?


Yanıtlar:


18

"Delta zamanı" eskiden iki kare güncellemesi arasında geçen süreydi (ancak diğer bağlamlarda da kullanılabilir; bu genellikle bir zaman çıkarma işleminin sonucudur).

GlutGet yöntemini ve GLUT_ELAPSED_TIME parametresini ve bazı işlemleri kullanarak delta süresini delta olarak alabilirsiniz .

Aşağıdaki satır glutInit çağrıldığından (veya ilk glutGet çağrısında (GLUT_ELAPSED_TIME)) milisaniye sayısını döndürür:

int timeSinceStart = glutGet(GLUT_ELAPSED_TIME);

Dolayısıyla, geçerli timeSinceStart'ı her oluşturma döngüsünde kaydederseniz, eskisini yenisine çıkararak deltaTime'ı öğrenebilirsiniz.

int oldTimeSinceStart = 0;

while( ... )
{
     int timeSinceStart = glutGet(GLUT_ELAPSED_TIME);
     int deltaTime = timeSinceStart - oldTimeSinceStart;
     oldTimeSinceStart = timeSinceStart;

     //... stuff to update using deltaTime
}

Bunu, clock () ile C / C ++ ctime kütüphanesini ve bir saat işareti ile bir saniye arasındaki ilişkiyi belirten CLOCKS_PER_SEC makro sabit ifadesini kullanarak hemen hemen aynı şekilde yapabilirsiniz .


Temel olarak, sabit bir zaman değeri kullanmak yerine hareketlerinizi bu geçen süreye oranla güncellemek için deltaTime kullanabilirsiniz. Bu şekilde, programınız 60 fps'de veya 10 fps'de çalışıyorsa, karakterinizin hareket hızı neredeyse aynı olmalıdır.


Küçük bir örnek: bir şeyi x ekseninde saniyede 10 birim taşımak istediğinizi varsayalım. Böyle bir şey yapabilirsiniz (deltaTime gerçekten milisaniye kullanırsa).

Position.x += 10/1000 * deltaTime;

Bu şekilde, programınız ister 2 kez ister 100 kez güncellensin, 1 saniye sonra konumun hemen hemen aynı olması gerekir ve oyun oynama, küçük bir bilgisayarın düşük fps'sinden sabit değerler kullanmasından daha az etkilenir.

  • Sabit değerlerle ==> düşük fps = daha az güncelleme = yavaş hareketler, yüksek fps = daha fazla güncelleme = çok hızlı hareketler.

  • DeltaTime ==> "neredeyse" aynı hareketleri ile.


Son olarak, gamedev.stackexchange'te Sabit zaman adımı ve Değişken zaman adımı'nı okumalısınız.


Milisaniye tamsayı olarak döner? Brüt ve muhtemelen yeterli değil. Her zaman platforma özgü zamanlayıcıları kullanmak zorunda kaldım ve daha sonra veba gibi GLUT'dan kaçındım çünkü oyunlar için süper değil.
Sean Middleditch

@Sean GLUT'u da kullanmıyorum, ama bu sorunun parametresindeydi, bu yüzden bunu aklımda cevapladım;) Ancak, oyunlarda milisaniyeyi işlemek için int'in "yetersizliği" konusundaki pozisyonunuzla ilgileniyorum . A positive intgenellikle imzalanırsa 2.147.483.647'ye ve imzalanmamışsa 4.294.967.295'e kadar gider ... bu yüzden daha küçük olanı düşünsek bile 2.147.483.647 milisaniye neredeyse 25 gündür ... Çoğu oyunu ele almak için yeterli olmalı zamanlayıcılar ve yeterli olmasa bile hala makul unsigned int(~ 50 gün) veya hatta long long(genellikle yaptığım gibi) kullanabiliriz.
Valkea

1
@Valkea Puan azami değil, en düşük çözünürlük. 60 FPS'deki tek bir kare sadece 16 2/3 ms olduğundan, 1 ms'lik bir doğruluk (milisaniyeyi tamsayı olarak göstermekten),% 5'ten fazla bir hata payını temsil eder - simülasyonları patlamanın dışına atmak için fazlasıyla yeterli. Tamsayı bir mikrosaniye sayısı katlanılabilir, ancak milisaniye çok kaba.
Steven Stadnicki

Evet, birçok şey için milisaniyeden daha az zamanlamaya ve GLUT'un sağlamadığı (bildiğim) yüksek çözünürlüklü bir zamanlayıcıya ihtiyacınız var. QueryPerformanceCounterWindows ve gettimeofdaydiğerlerinin çoğunda kullanmak için küçük bir platform kodu yazmak kötü değil . Ellerinizi kirletmeniz ve özellikle C ve C ++ 'da platform API'lerinin en az ortak paydasından biraz daha fazlasını hedeflemeniz gerekecek.
Sean Middleditch

Böyle bir hassasiyet tüm oyunlar için yararlı değildir. Ancak bu, int ve saatler hakkındaki bakış açınız hakkındaki soruşturmamı tam olarak cevaplayan çok ilginç bir açıklamadır. Henüz yüksek hassasiyetli saate ihtiyacım olmadı, ama sanırım konu hakkındaki bilgimi derinleştirmenin zamanı geldi. Teşekkür ederim;)
Valkea 18:13
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.