Güncelleme için sıra tabanlı (RPG) oyunlarda boşta kalma süresini kullanma


9

Herhangi bir sıra tabanlı RPG oyunu alırsanız, oyun 'wait_for_player_input' üzerinde döngü yaptığı için hiçbir şeyin olmadığı büyük zaman dilimleri olacaktır. Doğal olarak bu zamanı bir şeyleri güncellemek için kullanmak mantıklı görünüyor.

Ancak, bu derhal diş açılması gerektiğini düşündürmektedir. Bu tür bir tasarım tek bir iş parçacığında mümkün mü?

loop:  
if not check_something_pressed:  
    update_a_very_small_amount  
else  
  keep going

Ancak 'a_very_small_amount' ifadesinin her bir döngüyü yalnızca tek bir nesneyi güncellediğini söylesek, güncelleme konusunda çok yavaş olacaktır.

Bu konuda, tercihen tek bir iş parçacığında nasıl devam edersiniz?

EDIT: Bu dil-agnostik gibi mantıklı bir şey olarak etiketledim, Python daha spesifik bir şey harika olurdu. ;-)

İkinci düzenleme: Bu oyun animasyonlu bileşenlere sahip olmayı planlamıyor; yani, şu anda bunu oyuncu için bekle-girişi olarak çalıştırıyorum ve sonra her şeyi güncelleyip çiziyorum. Bu yüzden X FPS yerine kullanıcının hızına bağlıdır.

Yanıtlar:


7

Evet, tek bir iş parçacığında yapmak mümkündür. Genel olarak konuşursak, nesneleri sadece yedek döngüler olduğunda değil, her karede güncellemek istersiniz. Animasyonlarınız ve hareketiniz kare hızından ayrılacak ve eğer yapmazsanız oldukça dalgalı görünecektir. AI güncellemeleri veya gerçek zamanlı olması gerekmeyen başka bir şey hakkında daha fazla konuşuyorsanız, üzerine bir zamanlayıcı koyacağım. Hedef kare hızınızın ne olduğunu bilmelisiniz ve boşta kalma süresi, her şey tamamlandıktan sonra kalan süre olacaktır.

Diyelim ki oyununuz için 60 FPS hedefliyorsunuz. Bu, her kareyi yapmanız gereken tüm işleri gerçekleştirmek için 16.667 ms bırakıyor. Oyunun başında, mevcut en yüksek çözünürlük zamanlayıcısını kullanarak geçerli saati alın, 16.667 ms ekleyin ve bir yerde saklayın. Ben dilde çalıştığımdan bu yana bir süre olmuş olsa da python işlevi zaman () olduğunu düşünüyorum. İşleminiz tamamlandıktan sonra, geçerli saati kaydettiğiniz zamana göre kontrol eden bir döngü girin. Geçerli saat kare bitiş saatinden azsa update_a_very_small_amount. Küçük güncellemenizin hızlı bir şekilde işlenmesi gerektiğinden, işlemin çerçevenin sonundan geçmesinden endişe etmem. Bir sonraki karenin başlangıcı için sadece küçük bir gecikme olurdu ve bunu idare etmek için yeterli boş zamanınız var gibi görünüyor.

Çerçevenin işlenmesi bittikten sonra, bir sonraki çerçevenin sonunun nerede olması gerektiğini bulmak için son çerçevenin sonu için saklanan süreye 16.667 ms ekleyin. Geçerli saati + 16.667 ms kullanırsanız ve işlem biterse, bir sonraki çerçevenin sonu son çerçevenin geçtiği zamana kadar dışarı itilir.

Ynt: İkinci Düzenleme

Açıklığa kavuşturmak için, ana döngü boyunca bir yinelemeyi belirtmek için burada kare hızı terimini kullanıyorum. Kullanıcının giriş hızına dayanıyorsa, amacınızın sadece oyunu duyarlı hissetmek olduğunu düşünüyorum. Aksi takdirde, giriş olup olmadığını kontrol edebilir ve 10 saniye sürse bile döngüdeki her şeyi güncelleyebilirsiniz. Gerçi duyarlı hissetmek için, muhtemelen bu kareleri çizmiyor olsanız bile, saniyede yaklaşık 20 kez girişi kontrol etmek isteyeceksiniz. Bu, girişi tekrar kontrol etmeniz gerekmeden önce şeyleri güncellemeniz için 50 ms verir.


2

İçin Python özel olarak denemek ve kullanabilirsiniz Eşyordamlar birden güncelleme görüşmeleri üzerinden hesaplamaları yapmak için.

... yardımcı programlar, belirli konumlarda yürütmeyi askıya almak ve devam ettirmek için birden fazla giriş noktasına izin vermek üzere alt yordamları genelleştiren program bileşenleridir ...

PEP-0342 , Python'da birlikte program uygulamalarını detaylandırır.

Tek bir iş parçacığında çoklu iş parçacığını simüle edebilen kendi zamanlayıcı ve görevlerinizi oluşturabilirsiniz. Bu, Javascript tek bir işlemde çalıştırılsa bile Javascript çerçevelerinin çok iş parçacıklı işlemeye izin verdiği şekilde aynıdır.


1

Evet bu mümkün. Oyununuz bir tür ana oyun döngüsüne sahip olacak. Bunun gibi bir şey:

while(gameRunning)
{
  checkUserInput()
  updateGame()
  renderGame()
}

UpdateGame oyununda oyun nesnelerinizi tekrarlayabilir ve "biraz" güncelleyebilirsiniz. Bu yöntemde herhangi bir ağır hesaplama yapıyorsanız oyun basitçe asılacaktır. Bu yüzden, oyun döngüsünün birkaç tekrarını çalıştırmak için bu hesaplamaları bölmenin bir yoluna ihtiyacınız var.

Onları nasıl böleceğiniz, inşa ettiğiniz oyunun türüne bağlıdır. Labirentten geçen yolu hesaplamak için A * kullanan bir yol bulma rutininiz olduğunu varsayalım. Belirli bir süre sonra veya sabit miktarda yinelemeden sonra algoritmayı durdurmanız, hesaplanan yolu şu ana kadar tutmanız ve kontrolü oyun döngüsüne geri döndürmeniz gerekir. Yol bulma, updateGame bir sonraki çağrıldığında devam eder. Hala hesaplanırken karakteri kısmi yol boyunca hareket ettirebilirsiniz.

Çoğu zaman updateGame aramasının çok uzun sürmesi konusunda endişelenmenize gerek yoktur.

"Erken optimizasyon tüm kötülüklerin köküdür!"
Güncelleme rutininizde bir performans darboğazına çarparsanız, araştırma ve optimize etme zamanı. Oyununuzun hangi bölümlerinin hesaplanması için en fazla zaman alacağını ve yanlış şeyleri optimize etmek için zaman harcayacağınızı önceden bilemeyeceğinizden.


1

Sorunuzu anlamanın yolu, temelde işbirliğine dayalı çoklu görevler sormaktır.

Temel altyapı, hepsi yuvarlak-robin tarzında (daha sofistike bir önceliklendirme gerekmedikçe) çağrılan işlev işaretlerinin bir listesi olacaktır ve tüm bu işlevler, oyunun yapılmasına neden olmayacak kadar küçük olan "biraz çalışma" yapacaktır. halsiz olmak. Ben iş parçacıkları sıcak önce DOS ve ayrıca diş desteklemiyor mobil cihazlarda yaptım.

Bana göre daha iyi bir soru, oyuncunun hareket etmesini beklerken ne yapması gerektiğidir. Ne tür şeyler o kadar fazla işlemci yoğun olurdu ki, yine de anında gerçekleştirilemezler, aynı zamanda oyuncu o kadar hızlı hareket ederse, oyunun yeterince hızlı hareket etmesini sağlarsa, oyunun sahip olmadığı bunları işlemek için zaman. Böylece, birkaç bin AI için A * hesaplamak gibi şeyler çıktı.

Bence daha iyi bir çözüm, sadece verim / uyku sağlamak ve bilgisayarın güç yönetiminin işini yapmasına izin vermektir. Dizüstü bilgisayar kullanıcıları bunun için sizi daha çok sevecekler.

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.