Posisi interpolasi dalam game multi pemain

14

Untuk menghemat bandwidth dalam permainan multi - pemain saya , saya tidak memperbarui setiap objek setiap server centang, sebaliknya setiap objek memiliki updateRate yang memberi tahu permainan bahwa objek ini diharapkan akan diperbarui setiap kutu server X.

Ketika saya menerima pesan pembaruan untuk objek saya menghitung waktu saya mengharapkan pembaruan berikutnya datang:

origin = serverCurrentPosition
diff = serverNextPosition - origin
arriveTime = now + timeBetweenTicks * updateRate

Ketika saya menggambar objek saya menghitung waktu yang tersisa sampai pembaruan berikutnya dan menginterpolasi posisi sesuai:

step = 100 / timeBetweenTicks * updateRate
delta = 1 - step * ((arriveTime - now) / 100)
position = origin + diff * delta

Ini bekerja ... tetapi masih ada sedikit kegugupan dalam gambar, meskipun dalam teori saya, semua hal akan berjalan dengan baik, karena penskalaan harus menangani beberapa kelambatan, bukan?

Jadi pertanyaannya di sini adalah, apakah ini pendekatan terbaik? Haruskah saya memasukkan kelambatan aktual ke dalam perhitungan? Jika demikian, bagaimana saya melakukannya? Saya melakukan beberapa pengalaman, tetapi kegugupan hanya bertambah buruk.

Ivo Wetzel
sumber
Hai Ivo. Saya pikir ini adalah topik yang baik, tetapi tidak jelas apa yang kode Anda lakukan - misalnya dari mana serverCurrentPosition, serverNextPosition, timeBetweenTicks berasal?
CiscoIPPhone
Itu mengirim data pembaruan yang berasal dari server.
Ivo Wetzel

Jawaban:

11

Anda memiliki jitter, karena Anda lag berubah terus-menerus. Ini berarti, bahwa sementara server mengirimkan pembaruan tepat setiap timeBetweenTickskutu, klien menerimanya setelah beberapa waktu variabel. Waktu itu mungkin dekat dengan timeBetweenTickskoneksi yang baik, tetapi tidak persis sama (Dan selain itu, Anda mungkin memiliki kelambatan server dan kecepatan clock yang berbeda pada server dan klien).

Jadi, ketika Anda mengandalkan menerima pembaruan tepat pada waktu yang ditentukan, Anda terus-menerus sampai di tujuan sedikit sebelum / setelah pembaruan yang sebenarnya. Karena itu, jitter.

Pendekatan sederhana untuk mengurangi jitter adalah menggunakan "karet gelang", yang merupakan jawaban Martin dalam jawaban lain. Pada dasarnya, ketika Anda menerima pembaruan, Anda tidak segera mengubah posisi objek. Sebaliknya, jika posisi klien dan posisi server hanya berbeda sedikit, Anda mulai menginterpolasi posisi klien, sehingga setelah beberapa waktu yang ditentukan (katakanlah, separuh untuk pembaruan berikutnya) posisi klien dan server bertemu.

Gagasan lain untuk mengurangi jitter dalam pengaturan Anda: karena Anda mentransmisikan koordinat "saat ini" dan "berikutnya", Anda dapat menghitung kecepatan objek. Kemudian, ketika pembaruan tertinggal, Anda tidak menghentikan objek di tujuannya (yaitu posisi "berikutnya"), tetapi terus bergerak dengan kecepatan yang sama. Jika objek Anda tidak mengubah kecepatannya secara tiba-tiba, ini akan benar-benar meningkatkan kelancaran gerak pada klien.

Lupakan
sumber
Sudah begitu, bahwa objek tidak berhenti, mereka terus bergerak sampai menerima pembaruan berikutnya. Juga, menggunakan Akselerasi Perangkat Keras pada kanvas HTML tampaknya sedikit mengurangi efek jitter. Mungkin saya menjadi gila setelah mengerjakan hal itu begitu lama.
Ivo Wetzel
Itu sangat mungkin. Jika menyalakan akselerasi membuat laju bingkai lebih tinggi, maka kemungkinan menangani informasi pembaruan tepat pada saat yang tepat meningkat.
Nevermind
9

Saya telah memecahkan masalah ini sebelumnya dengan beberapa keberhasilan dengan pendekatan yang saya sebut "bayangan jaringan". Saya tidak tahu apakah ini sesuatu yang dilakukan orang lain, tetapi selalu berhasil bagi saya.

Setiap entitas yang sedang disinkronkan di jaringan memiliki entitas bayangan jaringan yang tidak terlihat. Ketika pembaruan datang dari jaringan, Anda memindahkan bayang-bayang secara langsung ke posisi yang seharusnya berada di jaringan, lalu perlahan-lahan Anda menginterpolasi entitas lokal yang terlihat ke arah bayangan dari waktu ke waktu.

Saya memasukkan banyak detail tentang pendekatan ini dalam jawaban saya sebelumnya di sini

Martin
sumber
Hm, saya melakukan sesuatu seperti itu di versi sebelumnya, ketidaktepatan floating point membuatnya sangat buruk di kali, saya memiliki rentang waktu yang cukup besar antara pembaruan, hingga 300 ms untuk beberapa objek, tapi mungkin saya hanya melakukan itu salah, saya akan memberikannya tembakan ketika saya menemukan waktu luang :)
Ivo Wetzel
presisi floating point benar-benar tidak boleh masuk ke ini sama sekali! Apakah Anda membaca jawaban tertaut saya di stackoverflow? Ini mencakup semua detail penerapan hal semacam ini.
Martin