Çok oyunculu bir oyunda enterpolasyon pozisyonları


14

Çok oyunculu oyunumdaki bant genişliğini kaydetmek için her sunucuyu işaretleyen her nesneyi güncellemiyorum, bunun yerine her nesnenin oyuna bu nesnenin her X sunucusu kenarı güncellenmesi beklendiğini söyleyen bir updateRate var.

Bir nesne için güncelleme mesajı aldığımda, bir sonraki güncellemenin gelmesini beklediğim zamanı hesaplıyorum:

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

Nesneyi çizdiğimde, bir sonraki güncellemeye kadar kalan süreyi hesaplar ve konumu buna göre enterpolasyona tabi tutarım:

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

Çalışıyor ... ama çizimde hala biraz titreme var, ancak teorimde her şey iyi çalışmalı, çünkü ölçeklendirme bir miktar gecikmeye dikkat etmeli, değil mi?

Buradaki soru şu: Bu en iyi yaklaşım mı? Hesaplamaya gerçek bir gecikme koymalı mıyım? Öyleyse, bunu nasıl yaparım? Bazı deneyimler yaptım, ama gerginlik daha da kötüleşti.


Merhaba Ivo. Bunun iyi bir konu olduğunu düşünüyorum, ancak kodunuzun ne yaptığı net değil - örneğin serverCurrentPosition, serverNextPosition, timeBetweenTicks nereden geliyor?
CiscoIPPhone

Bu, sunucudan gelen güncelleme verilerinde gönderilir.
Ivo Wetzel

Yanıtlar:


11

Titremeniz var, çünkü gecikmeniz sürekli değişiyor. Bu, sunucu tam olarak her timeBetweenTickskeneyi güncellerken , istemcinin değişken bir süre sonra bunları aldığı anlamına gelir . Bu zaman muhtemelen timeBetweenTicksiyi bir bağlantıya yakındır , ancak tam olarak eşit değildir (Ayrıca, sunucu gecikmesi ve sunucu ve istemcide farklı saat hızları olabilir).

Bu nedenle, güncellemeyi tam olarak belirtilen sürede almaya güvendiğinizde, hedefe sürekli olarak gerçek güncellemeden biraz önce / sonra ulaşırsınız. Bundan dolayı, titreme.

Titremeyi azaltmak için basit yaklaşım, Martin'in başka bir cevapta önerdiği gibi "lastik bantlama" kullanmaktır. Temel olarak, güncelleme aldığınızda, nesnenin konumunu hemen değiştirmezsiniz. Bunun yerine, istemci konumu ve sunucu konumu biraz farklıysa, istemci konumunu enterpolasyona başlarsınız, böylece belirli bir süre sonra (örneğin, bir sonraki güncellemenin yarısında) istemci ve sunucu konumları birleşir.

Kurulumunuzdaki titreşimi azaltmak için başka bir fikir: hem "mevcut" hem de "sonraki" koordinatları ilettiğiniz için, nesnenin hızını hesaplayabilirsiniz. Ardından, güncelleme geciktiğinde, nesneyi hedef noktasında durdurmazsınız (yani "sonraki" konumu), ancak aynı hızda hareket ettirmeye devam edersiniz. Nesneleriniz hızlarını aniden değiştirmezlerse, bu durum istemcideki hareket düzgünlüğünü gerçekten artırır.


Öyle ki, nesneler durmuyor, bir sonraki güncellemeyi alana kadar devam ediyorlar. Ayrıca, HTML tuvalinde Donanım İvmesi'nin kullanılması, jitter etkisini biraz azaltıyor gibi görünüyor. Belki de bu şey üzerinde uzun süre çalıştıktan sonra delirdim.
Ivo Wetzel

Bu oldukça mümkün. Hızlandırmayı açmak kare hızını yükseltirse, güncelleme bilgisini tam olarak doğru anda işleme olasılığı artar.
Nevermind

9

Bu sorunu daha önce "ağ gölgeleri" dediğim bir yaklaşımla çözdüm. Bunun diğer insanların yaptığı bir şey olup olmadığını bilmiyorum, ama her zaman benim için çalıştı.

Ağ üzerinden senkronize edilen her bir varlığın görünmez bir ağ gölge varlığı vardır. Ağdan bir güncelleme geldiğinde, gölgeyi doğrudan ağın olması gerektiğini söylediği konuma ışınlarsınız, ardından zaman içinde yerel görünür varlığı gölgeye doğru yavaşça enterpolasyon yaparsınız.

Buradaki önceki yanıtımda bu yaklaşımla ilgili çok fazla ayrıntı ekledim


Hm, daha önceki bir versiyonda böyle bir şey yaptım, kayan nokta belirsizliği zaman zaman gerçekten kötü yaptı, bazı nesneler için 300 ms'ye kadar güncellemeler arasında oldukça büyük zaman aralıklarına sahibim, ama belki sadece yanlış yaptım, vereceğim Biraz boş zaman bulduğumda bir çekim :)
Ivo Wetzel

kayan nokta hassasiyeti gerçekten buna girmemelidir! Stackoverflow'daki bağlantılı cevabımı okudun mu? Bu tür şeyleri uygulamanın tüm detaylarını kapsar.
Martin

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.