Saya sedang mengembangkan game multipemain berbasis Javascript. Sejauh ini saya sudah menyiapkan server dasar, klien, dan jaringan.

Saya memang memiliki masalah di mana pemutar saya bergerak lebih cepat pada layar 120Hz dibandingkan dengan layar 60Hz. Saya telah memperbaikinya dengan mengalikan kecepatan gerakan pemain dengan deltatime dari 'requestAnimationFrame'.

Namun; apakah itu solusi yang lebih baik untuk memisahkan animasi dari logika?

Seperti dalam:

//Game loop; Do each 1/60th of a second
setInterval(gameTick, 1000/60);
function gameTick(){
  player.handleKeys();
  enemies.foreach( (enemy) => {
    enemy.update();
  });
}

//Draw loop; match to player screen refresh rate
window.requestAnimationFrame(gameLoop);
function gameLoop() {
    player.draw();
    enemies.foreach( (enemy) => {
    enemy.draw();
  });
  window.requestAnimationFrame(gameLoop);
}

Meskipun perbedaannya mungkin "dapat diabaikan", saya ingin menghindari pemain dengan 'spam' server 240Hz dan memiliki keunggulan dibandingkan pemain lain.

Padahal di sisi lain untuk monitor 240Hz; hanya 1 dari 4 frame input keyboard Anda yang akan ditangani, jadi mungkin tidak terasa semulus ini?

Alasan saya bertanya adalah bahwa ini akan menjadi permainan yang kompetitif dan karenanya harus seimbang. Tetapi saya telah memeriksa berbagai sumber di mana konsensus tampaknya menggunakan requestAnimationFrame (bahkan untuk logika; tidak hanya gambar), meskipun saya meragukan ini dan ingin tahu mana yang benar (dan/atau digunakan dalam profesional permainan kompetitif).

6
Paul 20 September 2019, 12:41

1 menjawab

Jawaban Terbaik

requestAnimationFrame (rAF) hanya akan menyala pada kecepatan maksimum 60fps. (pengecualian Beberapa versi yang jauh lebih lama dari beberapa browser memiliki tanda untuk mematikan VSync yang memengaruhi rAF)

Catatan

  • rAf, setTimeout atau setInterval tidak dapat diandalkan dan dapat menjatuhkan bingkai karena berbagai alasan.

  • rAF akan berhenti menembak jika Tab atau Jendela disembunyikan atau (tab) tidak fokus.

  • setInterval dan setTimeout akan dibatasi jika Tab atau Jendela disembunyikan atau (tab) tidak fokus.

  • Argumen waktu rAF tidak mewakili waktu frame (ditampilkan berikutnya), melainkan waktu panggilan balik rAF dipanggil.

    Itu artinya...

    • waktu antar frame jika dihitung dari argumen waktu rAF akan mengambang dan tidak dapat digunakan secara andal sebagai waktu delta.
    • argumen waktu menyatakan waktu panggilan, bukan waktu bingkai ditampilkan ke layar, dan bisa sampai <1/60 detik lebih awal dari konten yang dirender disajikan ke perangkat keras layar.

Jaringan lokal

Untuk permainan multi pemain, server harus melayani waktu sehingga semua pemain berjalan pada stempel waktu yang umum dan dapat diandalkan. Klien dapat memproyeksikan waktu maju dari cap waktu terakhir untuk menghindari pembekuan jika jaringan menunda paket, tetapi harus kembali ke waktu yang disinkronkan (waktu server) saat diterima.

Jaringan besar

Komunikasi bergantung pada jarak, bahkan pada jaringan titik ke titik yang sempurna jika klien berada di belahan dunia lain, ping terbaik yang mungkin dilakukan adalah 130ms (mendekati 8 frame @60Hz) karena waktu tempuh yang ringan. Ini tidak termasuk packet switching dan panjang rute yang sebenarnya. Umumnya waktu ping ke titik terjauh di dunia adalah sekitar 300ms.

Penundaan ini harus dipertimbangkan untuk game profesional, dan itulah sebabnya banyak game multi-pemain menyediakan server lokal, dan membatasi pemain dari beberapa server jika jauh. 300ms memberi pemain yang lebih dekat keuntungan yang signifikan.

Game multipemain waktu nyata yang menggunakan API browser untuk menghosting klien akan sangat bermasalah karena browser adalah host klien yang tidak dapat diandalkan dan tidak konsisten, kebanyakan karena banyaknya perangkat yang dijalankan klien.

BTW

window adalah default this (globalThis) dan karena itu tidak diperlukan. misalnya window.requestAnimationFrame identik dengan requestAnimationFrame

3
Community 20 Juni 2020, 09:12