Güncelleme (mantık kene) ayırmak ve (kene kene) oranları çizmek istersiniz.
Güncellemeleriniz, çizilecek dünyadaki tüm nesnelerin konumunu üretecektir.
Burada, talep ettiğiniz, ekstrapolasyon ve başka bir yöntem olan interpolasyon olmak üzere iki farklı olasılık ele alınacaktır.
1.
Ekstrapolasyon , nesnenin (öngörülen) konumunu bir sonraki karede hesaplayacağımız ve mevcut nesnelerin konumu ile nesnenin bir sonraki karede olacağı konum arasında enterpolasyon yapacağımız yerdir.
Bunu yapmak için, çizilecek her nesnenin ilişkilendirilmiş olması velocity
veposition
. Nesnenin bir velocity * draw_timestep
sonraki karede olacağı konumu bulmak için, bir sonraki karenin öngörülen konumunu bulmak için sadece nesnenin o anki konumuna ekleriz . draw_timestep
önceki render kene (yani önceki beraberlik çağrısı) beri geçen zaman miktarıdır.
Bunu burada bırakırsanız, öngörülen konumlarının bir sonraki karedeki gerçek konum ile uyuşmadığı durumlarda nesnelerin "titremeye" başladığını göreceksiniz. Titremeyi gidermek için, önceki güncellemeyi onaylamadan itibaren geçen süreyi lerp faktörü olarak geçen süreyi kullanarak, öngörülen pozisyonu saklayabilir ve önceden tahmin edilen pozisyon ile her çekme adımında öngörülen yeni pozisyon arasında lerp kullanabilirsiniz. Bu, hızlı hareket eden nesnelerin aniden yerini değiştirmesi durumunda kötü davranışa neden olur ve bu özel durumu ele almak isteyebilirsiniz. Bu paragrafta belirtilen her şey, sizin yok kullanımı ekstrapolasyon istiyorum.
2.
İnterpolasyon , son iki güncellemenin durumunu kaydettiğimiz ve güncellemeden bu yana geçen güncel süreyi temel alarak aralarındaki enterpolasyondur. Bu kurulumda, her nesnenin bir ilişkili position
ve olması gerekir previous_position
. Bu durumda, çizimimiz mevcut oyun ekranının arkasındaki en kötü güncelleme işaretini ve en iyi ihtimalle güncel güncelleme işaretiyle aynı durumda olacak.
Benim düşünceme göre, muhtemelen tanımladığım gibi enterpolasyon yapmak istiyorsunuz, çünkü ikisinin uygulaması daha kolay ve mevcut güncellenmiş durumunuzun ardında bir saniyenin (örneğin 1/60 saniye) küçük bir kısmını çizmek gayet iyi.
Düzenle:
Yukarıdakilerin bir uygulamayı gerçekleştirmenize izin vermemesi durumunda, burada tarif ettiğim interpolasyon yönteminin nasıl yapılacağına bir örnek. Ekstrapolasyonu ele almayacağım, çünkü tercih etmen gereken gerçek dünya senaryosunu düşünemiyorum.
Çizilebilir bir nesne oluşturduğunuzda, çizilmesi gereken özellikleri (yani çizmesi için gereken durum bilgisi) depolar .
Bu örnekte, pozisyon ve rotasyonu kaydedeceğiz. Ayrıca renk veya doku koordinat konumu gibi diğer özellikleri de depolamak isteyebilirsiniz (yani bir doku kayarsa).
Oluşturma iş parçacığı çizilirken verilerin değiştirilmesini önlemek için (yani, oluşturma iş parçacığı çizilirken bir nesnenin konumu değiştirildi, ancak diğerleri henüz güncellenmedi), bir tür çift tamponlama uygulamamız gerekiyor.
Bir nesne iki kopyasını saklar previous_state
. Ben onları bir diziye koymak ve onlara bakın edecektir previous_state[0]
ve previous_state[1]
. Aynı şekilde iki kopyasına ihtiyacı varcurrent_state
.
Çift tamponun hangi kopyasının state_index
kullanıldığını takip etmek için, hem güncelleme hem de iş parçacığı için mevcut olan bir değişken saklıyoruz.
Güncelleme iş parçacığı, öncelikle kendi verilerini (istediğiniz veri yapıları) kullanarak bir nesnenin tüm özelliklerini hesaplar. Sonra, bu kopyalar current_state[state_index]
için previous_state[state_index]
, çizim için yeni veri alakalı ve kopyalar position
ve rotation
içine current_state[state_index]
. Daha sonra state_index = 1 - state_index
, çift tamponun o anda kullanılan kopyasını çevirmek için yapar .
Yukarıdaki paragraftaki her şey kilitlenerek yapılmalıdır. current_state
. Güncelleme ve çizme iplikleri bu kilidi çıkartır. Kilit, yalnızca hızlı olan durum bilgilerinin kopyalanması süresince alınmaktadır.
Render ipinde, daha sonra pozisyon ve rotasyonda doğrusal bir enterpolasyon yaparsınız:
current_position = Lerp(previous_state[state_index].position, current_state[state_index].position, elapsed/update_tick_length)
Nerede elapsed
son güncelleme kene beri kılmak dizisindeki geçen zamanın miktarı ve update_tick_length
Sabit güncelleme oranı (örn 20fps güncellemelere, kene başına aldığı süredir update_tick_length = 0.05
).
Lerp
Yukarıdaki işlevin ne olduğunu bilmiyorsanız , konuyla ilgili wikipedia yazısını inceleyin: Linear Interpolation . Bununla birlikte, hangi gecikmenin ne olduğunu bilmiyorsanız, o zaman muhtemelen enterpolasyonlu çizim ile dekuplajlı güncelleme / çizim yapmaya hazır değilsiniz.