Cara mendapatkan dan menggunakan waktu delta

14

Saya memiliki tikus yang melihat dan berjalan dalam permainan saya, tetapi mereka sangat lambat dan sulit digunakan. Saya pikir itu karena saya menggunakan kecepatan tetap. Saya mendengar bahwa dalam proyek besar pengembang menggunakan waktu delta. Bagaimana cara menghitung waktu delta dalam kekenyangan? Bagaimana cara menghitung kecepatan menggunakan waktu delta?

Mark Fedurin
sumber
C11 dan C ++ 11 juga memiliki jam nanodetik sekarang: stackoverflow.com/a/36095407/895245 || stackoverflow.com/a/5524138/895245
Ciro Santilli 新疆 改造 中心 法轮功 六四 事件

Jawaban:

18

"Waktu delta" dulunya adalah waktu yang berlalu antara dua pembaruan bingkai (tetapi juga dapat digunakan dalam konteks lain; ini biasanya merupakan hasil dari pengurangan waktu).

Anda bisa mendapatkan waktu delta dalam kekenyangan menggunakan metode glutGet dan parameter GLUT_ELAPSED_TIME, ditambah beberapa operasi.

Baris berikut mengembalikan jumlah milidetik sejak glutInit dipanggil (atau panggilan pertama ke glutGet (GLUT_ELAPSED_TIME)):

int timeSinceStart = glutGet(GLUT_ELAPSED_TIME);

Jadi, jika Anda mendaftarkan timeSinceStart saat ini di setiap loop rendering, Anda dapat mengetahui deltaTime dengan mengurangi yang lama ke yang baru.

int oldTimeSinceStart = 0;

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

     //... stuff to update using deltaTime
}

Anda juga dapat melakukannya dengan cara yang hampir sama, menggunakan C / C ++ ctime library dengan clock () dan ekspresi konstan makro CLOCKS_PER_SEC yang menentukan hubungan antara centang jam dan detik.


Pada dasarnya, Anda dapat menggunakan deltaTime untuk memperbarui gerakan Anda sesuai dengan waktu yang telah berlalu ini daripada menggunakan nilai waktu tetap. Dengan cara ini, kecepatan gerakan karakter Anda harus hampir sama jika program Anda berjalan pada 60 fps atau jika berjalan pada 10 fps.


Ini adalah contoh kecil: misalkan Anda ingin memindahkan sesuatu sebanyak 10 unit setiap detik pada sumbu x. Anda dapat melakukan sesuatu seperti ini (jika deltaTime memang menggunakan milidetik).

Position.x += 10/1000 * deltaTime;

Dengan cara ini, apakah program Anda diperbarui 2 kali atau 100 kali, 1 detik kemudian posisinya harus hampir sama, dan permainan-nya kurang terpengaruh oleh fps rendah komputer kecil daripada jika menggunakan nilai tetap.

  • Dengan nilai tetap ==> fps rendah = kurang pembaruan = gerakan lambat sedangkan fps tinggi = lebih banyak pembaruan = gerakan sangat cepat.

  • Dengan deltaTime == "" hampir "gerakan yang sama.


Terakhir, Anda harus membaca Langkah waktu tetap vs Langkah waktu variabel di gamedev.stackexchange.

Valkea
sumber
Ia mengembalikan milidetik sebagai bilangan bulat? Kotor, dan mungkin tidak cukup. Saya selalu harus menggunakan penghitung waktu khusus platform dan kemudian hanya menghindari GLUT seperti wabah karena itu super tidak bagus untuk game.
Sean Middleditch
@Sean Saya juga tidak menggunakan GLUT, tapi itu ada di parameter pertanyaan jadi saya jawab dengan ini;) Namun, saya tertarik dengan posisi Anda dalam hal "kekurangan" int untuk menangani milidetik dalam game . A positive intbiasanya naik menjadi 2.147.483.647 jika ditandatangani dan hingga 4.294.967.295 jika tidak ditandatangani ... jadi meskipun kita anggap lebih kecil, 2.147.483.647 milidetik hampir 25 hari ... Itu seharusnya cukup untuk menangani sebagian besar permainan timer dan bahkan jika itu tidak cukup kita masih dapat menggunakan unsigned int(~ 50 hari) atau bahkan long long(seperti yang biasanya saya lakukan).
Valkea
1
@ Valkea Intinya bukan maks, itu resolusi di ujung bawah. Karena satu frame pada 60 FPS hanya 16 2 / 3rds ms, akurasi 1ms (dari mewakili milidetik sebagai bilangan bulat) mewakili margin kesalahan lebih dari 5% - lebih dari cukup untuk melempar simulasi jauh dari pukulan. Hitungan bilangan bulat dari mikrodetik akan tertahankan, tetapi milidetik terlalu kasar.
Steven Stadnicki
Ya, Anda perlu pengaturan waktu sub-milidetik untuk banyak hal dan timer resolusi tinggi untuk menemukan itu, yang tidak disediakan oleh GLUT (yang saya tahu). Tidak buruk hanya menulis sedikit kode platform untuk digunakan QueryPerformanceCounterdi Windows dan gettimeofdaypada sebagian besar lainnya. Anda harus membuat tangan Anda kotor dan bertujuan untuk sedikit lebih banyak daripada penyebut API platform yang paling tidak umum, terutama di C dan C ++.
Sean Middleditch
Ketepatan seperti itu tidak berguna untuk semua game. Namun ini adalah penjelasan yang sangat menarik yang sepenuhnya menjawab interogasi saya tentang sudut pandang Anda tentang int dan jam. Saya belum pernah membutuhkan jam presisi tinggi, tapi saya kira sudah waktunya untuk memperdalam pengetahuan saya tentang masalah ini. Terima kasih;)
Valkea