Sinkronisasi gerakan berbasis multi-pemain

8

Saya harus menyinkronkan pergerakan beberapa pemain melalui Internet, dan saya mencoba mencari cara teraman untuk melakukannya.

Permainan ini berbasis ubin, Anda hanya dapat bergerak dalam 4 arah, dan setiap gerakan memindahkan sprite 32px (seiring waktu tentunya). Sekarang, jika saya hanya mengirim aksi perpindahan ini ke server, yang akan menyiarkannya ke semua pemain, sementara tombol jalan terus ditekan, untuk terus berjalan, saya harus mengambil perintah berikutnya, mengirimkannya ke server, dan untuk semua klien, pada waktunya, atau perpindahan tidak akan mulus lagi. Saya melihat ini di game lain, dan itu bisa menjadi sangat cepat, bahkan tanpa lag. Jadi saya bertanya-tanya apakah ini bahkan pilihan yang layak. Ini sepertinya metode yang sangat bagus untuk pemain tunggal, karena mudah, lurus ke depan (, cukup ambil tindakan gerakan selanjutnya dan tambahkan ke daftar), dan Anda dapat dengan mudah menambahkan gerakan mouse (mengklik ubin), untuk menambahkan jalur ke antrian, itu berjalan bersama.

Hal lain yang muncul di benak saya adalah mengirimkan informasi bahwa seseorang mulai bergerak ke suatu arah, dan sekali lagi dia berhenti atau mengubah arah, bersama dengan posisi, sehingga sprite akan muncul di posisi yang benar, atau lebih tepatnya sehingga posisi bisa diperbaiki jika salah. Seharusnya ini (semoga) hanya membuat masalah jika seseorang benar-benar tertinggal, dalam hal ini yang diharapkan. Agar hal ini berhasil, saya perlu semacam antrian, di mana perubahan arah yang masuk dan hal-hal disimpan, sehingga sprite tahu ke mana harus pergi, setelah gerakan saat ini ke ubin berikutnya selesai. Ini sebenarnya bisa bekerja, tetapi terdengar rumit. Meskipun itu mungkin satu-satunya cara untuk melakukan ini, tanpa risiko gagap. Jika perubahan berhenti atau arah diterima di sisi klien, itu s disimpan dalam antrian dan char terus bergerak ke koordinat yang ditentukan, sebelum berhenti atau mengubah arah. Jika perintah baru datang terlambat pasti akan gagap juga ...

Saya kesulitan menentukan metode, dan saya belum bisa menemukan contoh untuk ini. Masalah utama saya adalah menjaga pergerakan ubin menjadi lancar, itulah sebabnya topik lain tentang sinkronisasi gerakan berbasis piksel tidak banyak membantu.

Apa cara "standar" untuk melakukan ini?

Mars
sumber

Jawaban:

4

Saya berasumsi Anda berbicara tentang bergerak secara real time. Mencoba menginterpolasi posisi mungkin adalah penyebab yang hilang; melalui koneksi yang lambat, kondisi gim Anda bisa jatuh semakin jauh di belakang keadaan gim yang sebenarnya. Tidak seperti komentar lainnya, saya akan menyarankan agar tidak menempatkan banyak logika permainan di sisi server. Ketika saya menerapkan solusi semacam ini, klien memiliki soket TCP ke server terus-menerus. Saat kondisi permainan berubah, ia mengirim pesan ke server, seperti 'klien ada di x = 10, y = 20'. Server mendorong pesan ke klien lain, yang mencoba menanganinya berdasarkan logika internal mereka sendiri. Menggunakan TCP memastikan pesan Anda tiba secara berurutan.

Sayangnya, bahkan game AAA tidak dapat menangani lag ekstrim; pemain sesekali akan bergerak sangat cepat, karena keadaan lokal dan jaringan mereka jauh dari mendera. Memantau pengguna pulang-pergi ping dan menendang yang terlalu jauh / lambat akan membantu dengan ini.

Alan Gardner
sumber
1
Memberi +1 untuk 'bahkan game AAA tidak dapat menangani lag ekstrim;' Sebenarnya Tidak ada yang dapat menangani bahkan kelambatan kecil dengan sempurna. Kita bisa membuatnya tampak seperti kita bisa.
Valmond
3

Pada dasarnya ini adalah bagaimana Anda dapat melakukannya dengan cara yang sederhana dan aman (peringatan, kodesemu ekstrem):

A) Klien (pemainid = 5) meminta server untuk memindahkan 'kanan' (atau lebih baik, ke ubin 73,18)

B) Server memeriksa peta 2D besarnya yang berisi pemain (atau ID pemain misalnya):

 if(map[73][18] == occupied)
     Send back ('Not OK') to client (the case is blocked by another player)
else
    Set the new position as blocked: map[73][18]=5
    Release the old position: map[72][18]=0;
    Send a 'new position: 5, 73,18' message to all players who are nearby (moving client included)

C) Klien mendapatkan pesan 'posisi baru' (baik, atau pemain 5 mendapat pesan 'Tidak Oke')

D) klien perlahan memindahkan item yang memiliki playerid = 5 menuju posisi barunya (atau membuatnya jika tidak memiliki satu item dengan playerid = 5)

Valmond
sumber
Baiklah, terima kasih, tapi masalah saya membuatnya tetap mulus di klien lain selama beberapa gerakan ubin terus, bukan gerakan ubin secara umum ^^
Mars
Tetapkan kecepatan dengan benar dan ganti rugi untuk lag dengan misalnya perhitungan mati atau hanya gerakan 'bodoh' menuju target dengan kecepatan konstan '(atau kecepatan proporsional di atas treashold tertentu jika Anda mengirim cap waktu di sepanjang posisi) dan Anda harus baik-baik saja.
Valmond
1

Saya pikir metode yang Anda gambarkan cukup bagus, terutama dalam permainan sederhana yang hanya memungkinkan 4 gerakan. Inilah cara saya mengimplementasikannya.

Saya tidak tahu standar apa pun, tetapi hal pertama yang muncul di benak saya adalah hanya menyiarkan "perubahan input", perubahan input pemain, dari pemain ke yang lain. Misalnya, Anda dapat menyiarkan hanya pesan di sepanjang garis [penekanan tombol, ID kunci, waktu], atau [kunci dilepaskan, ID kunci, waktu], dan biarkan permainan para pemain bertindak atas perubahan input ini. Termasuk waktu akan membantu dengan koreksi jalur (jika pemain telah mengubah arah pada waktu t, maka "maju" pada waktu t +1 akan perlu diperbaiki).

Namun, dengan solusi ini Anda mungkin menghadapi masalah pesan yang hilang; misalkan pesan "kunci dirilis" tidak pernah dikirim? Sesuatu yang dapat membantu ini adalah secara berkala melakukan polling keadaan permainan pemain dan mengembalikan posisi pemain saat ini, serta tombol apa saja yang ditekan, atau bahkan mengembalikan seluruh keadaan permainan. Bergantung pada jumlah pemain dan perintah, Anda dapat men-tweak ini untuk menyeimbangkan pengiriman pesan antara klien / server untuk keseimbangan yang baik.

Hal lain yang dapat Anda perhatikan adalah perencanaan jalur. Misalnya, jika pemain telah bergerak maju selama 5 detik, maka dalam milidetik berikutnya kemungkinan pemain masih akan bergerak maju. Dalam hal ini, Anda dapat membuat kemiripan prediksi jalur untuk menghindari kelambatan. Ini pada dasarnya adalah apa yang dilakukan metode di atas, meskipun ini dapat memperhitungkan jalur sirkular.

Saya harap ini membantu!

Jonathan Pitre
sumber
1
Masalah dengan hanya mengirim input adalah bahwa jika Anda melewatkan satu atau kadang-kadang hanya menafsirkannya dalam urutan yang salah maka gamestate Anda tidak akan apa-apa lagi, yaitu. dua klien akan menunjukkan 'layar' yang berbeda.
Valmond
@Valmond poin yang sangat bagus ... sebenarnya, saya merasa ingin menghapus jawaban saya, karena dalam hal itu rasanya tidak benar.
Jonathan Pitre
1
Anda dapat mengirim input ke server (hingga tidak apa-apa) tetapi server harus (IMO) mengirim data yang tepat atau setidaknya memverifikasi data atau mungkin mengirim seluruh gamestate (ini telah dilakukan dalam permainan nyata misalnya Blood Bowl ), mungkin Anda dapat mengubah jawaban Anda alih-alih menghapusnya :-)
Valmond