Bir fayans haritasını web üzerinde verimli bir şekilde nasıl saklayabilir ve görüntüleyebilirim?


9

hakkında

Bunlar aslında bir soruda iki soru. Her şeyden önce büyük miktarda fayans verilerini verimli bir şekilde saklamanın bir yolunu arıyorum. Diğer özellik, veri kümesini sorgulama ve kutucukları görüntüleme ile ilgilidir. Önce size biraz bilgi vereyim.

Tuval'e dönüştürmek için CraftyJS kütüphanesini kullanarak tarayıcı tabanlı çok oyunculu bir tycoon oyunu yapıyoruz. GUI'nin arka planında PHP üzerinde Yii Framework kullanıyoruz ve hepsi bir Python rastgele harita üreteci ve oyun motoruna bağlanıyor.

İlk kaba harita görüntüsü şöyle görünür: http://i.imgur.com/khAXtl.png

Harita verilerinin saklanması

Oyun dünyası, oyun her başladığında rastgele oluşturulur. Boyut her oyuncu için 100x100 altıgen fayans. Bu, üç oyunculu bir oyun için 90.000 karo oluşturulduğu anlamına gelir. Şu anda haritayı oluşturduğum bir JavaScript dizisi oluşturuyorum.

Bu, renderleme için iyi çalışır, ancak harita ile her türlü etkileşim için, hangi oyuncunun karoya sahip olduğunu, üzerine ne tür bir yapı inşa edildiğini, mevcut fiyat ve benzeri şeyleri depolamamız gerekir. İlk başta, en azından prototip için, MySQL kullanmak istedik, ancak bazı testlerden sonra, istediğim kadar hızlı değil. Belki MongoDB gibi bir nesne deposu, bir SQL tablosu yerine döşeme verilerinin depolanması için daha uygundur. Ya da belki başka bir şey?

Haritayı görüntüleme

Gördüğüm başka bir sorun da harita üzerinde dolaşmak. Şu anda görünümde olmasa bile her bir karo için kurnaz varlıklar oluşturuyorum. Bu yavaştır, çünkü Crafty yalnızca görünüm alanında olanları oluştursa da, her render etkinliğindeki tüm karoları depolar ve yineler. Şu anda sahip olduğum şey, yüklendiğinde çok yavaş olan ve hareket ettiğinizde kekeler olan çizilmiş bir harita, şimdi oynanabilir hale getirmek istiyorum.

İlk fikrim, görüntü alanında bulunan döşemelerin görüntülenen alt kümesini yüklemekti. Ancak bir oyuncu görünüm alanını boş bir alana taşıdığında, sunucuyu sorgulamam ve yanıtı geri beklemem gerekir, ancak o zaman harita oluşturulabilir. Bu, yerel bir uygulamada iyi olurdu, ancak bir web oyununda laggy.

Haritadan sorunsuz performans elde etmenin yolu, daha büyük bir kutucuk alt kümesini javascript dizisine önceden yüklemek ve önbellek olarak kullanmak olabilir. Oyuncu birkaç ekran "önbellek" olurdu ve o görünüm penceresini hareket ettirdiğimde, JS "önbellek" için daha fazla kiremit yüklemek istiyorum.

Doğru yöne mi gidiyorum? Benzer bir şey yapan birinden daha fazla bilgi almak isterim. Oyun geliştirmede yeniyim, ancak son birkaç haftadır birçok kaynaktan geçiyorum.


1
MySQL'i bir darboğaz olarak tanımladığınıza şaşırdım. İşleri yavaşlattığı sonucuna varmak için neyi test ettiniz?
bummzack

@bummzack Her karoda bir satır varsa, işlerin nasıl yavaş olamayacağını pek göremiyorum.
aaaaaaaaaaaa

1
@eBusiness Bir DB'den binlerce satır sorgulamak gerçekten sorun olmamalı. Bu hala birkaç milisaniye aralığında olmalıdır. Ayrıca 90.000 sıra değil, 3 oyuncu için 30.000 sıra (oyuncu başına 100x100) olurdu.
bummzack

Kafa karıştırıcı matematik için özür dilerim, oyuncu bölgesi arasında iki kat boşluk da var, böylece birbirlerinden eşit uzaklıkta olacaklar, bu da onu 90k yapıyor. Sorgulamak sorun değil. 90 bin fayans seçmek ve bir harita oluşturmak. Ama bunu yapmanın iyi bir yolu değil. Harita verileri serileştirmek ve ayrıntılı bilgi istendiğinde db fayans sorgu kullanacaktır.
eleman

Yanıtlar:


2

Oynanış
Öncelikle size sormak istiyorum, oyuncu başına 10000 karoya ihtiyacınız var mı? Ne tür bir oyun yaptığınızı bilmiyorum, ancak büyük haritaların uzun oyunlar yaptığı genellikle doğrudur. Civilization 5'teki en büyük harita 10240 fayans ve sadece sorta çalışıyor çünkü bir kısmından daha fazla oynamanıza gerek yok.

Veritabanı
Böyle bir oyunu veritabanından çalıştırmaya çalışmamalısınız, verileri uygulama belleğinde tutmanız gerekir. Oyunu yedeklemek için bir veritabanı kullanabilirsiniz. Tam bir yedekleme için oyun verilerinin serileştirilmesini kaydedin ve daha sonra verilen siparişleri kaydederek arttırabilir ve daha sonra yedeklemenin kullanılması gerekiyorsa bunları yeniden çalıştırabilirsiniz.

JavaScript depolaması
İstemciye gelince, tüm haritayı yüklü tutmanız daha iyi olduğunu söyleyebilirim, en azından hepsinin güzel bir nesne ağacında olması gazillion fayanslarına yapışırsanız biraz fazla olabilir, bu yüzden muhtemelen verileri saklamanız gerekir "yarı ikili" kodlanmış biçimde. Dizeler bu tür şeyler için mükemmel çalışır, alternatif olarak, 64 bit şamandırada 53 bite kadar imzasız tamsayıları güvenli bir şekilde saklayabilir, bir dizideki şeylerin çoğunu doldurabilirsiniz ve bence oldukça mütevazı bir bellek ayak izi göreceksiniz.

JavaScript görselleştirme
Kanvas kullanmamanız gerektiğini söylemese de, aslında böyle şeyler için buna ihtiyacınız yoktur. Hepsini bir dizi img öğesi olarak ayarlayın ve haritanın farklı bölümlerini görüntülemek için src özelliğini değiştirin.

Pro ipucu
Bu arada, bazen onu oluşturmak için kullanılan tohumu paylaşmak tüm haritayı paylaşmaktan daha kolaydır.


+1, ancak ne yazık ki PHP ile yazılmış bir web uygulamasının genellikle oyun durumunu hafızada tutmanın bir yolu yoktur.
bummzack

@bummzack, Ahh, doğru, sanırım bir şekilde PHP kelimesini atladım ve sadece Python'u okudum. O zaman arka uç çerçevesinin değiştirilmesi gerekebilir. Node.js bir seçenek olabilir.
aaaaaaaaaaaa

Rekabetçi bir ulaşım kralı inşa ediyorum, OpenTTD'yi düşünüyorum, 512x512 (262k) büyüklüğündeki bir harita birkaç oyuncu için o kadar büyük değil. Bunun iddialı olduğunu anlıyorum, ancak harita o kadar büyük değilse, oyun çok yakında sona erecekti. Çok oyunculu bir oyun olduğu için haritadaki değişiklikleri oyuncular arasında senkronize etmem gerekiyor. İlk içgüdüm sadece web geliştirmeden bildiğim kavramları kullanmak ve datbase kullanmaktı. Süper gerçek zamanlı olması gerekmez. JS görselleştirme ile gidiyorum, çünkü haritada dinamik şeyler istiyorum.
eleman

Cevabımı bazı işaretçiler olarak düşünün, sonunda performansı kendiniz çözmek zorunda kalacaksınız, ciddi bir sorun ve bazı tavizler vermeniz gerekebilir.
aaaaaaaaaaaa

Katılıyorum, cevabınız bana düşünce için çok yiyecek verdi. Serileştirilmiş harita verilerini bellekte tutmanın ve veritabanını yedek olarak tutmanın bir yolunu bulmaya çalışacağım. Ama sonra değişiklikleri oyuncular arasında nasıl paylaşacağımı bulmalıyım. Daha fazla test yaptıktan sonra bulduğum şeyle geri döneceğim.
eleman

1

MySQL yavaş değil. Büyük olasılıkla saf sorgular gerçekleştiriyorsunuz veya alt optimal dizinleriniz var. MongoDB gibi NoSQL yaklaşımları daha hızlı olabilir, belki olmayabilir. Erişim düzeniniz ve sorgu seçiminiz burada gerçekten önemlidir. Performansı nasıl geliştireceğiniz konusunda tavsiyelerde bulunmak mümkündür, ancak zaten ne yaptığınızı görmeden.

Haritadan sorunsuz performans elde etmenin yolu, daha büyük bir kutucuk alt kümesini javascript dizisine önceden yüklemek ve önbellek olarak kullanmak olabilir.

Evet tabi ki. Buraya eklenecek çok şey yok - istemci sunucudan fayans ister, bu yüzden istediklerinizin ekrandan daha büyük bir alanı kapsadığından emin olmanız gerekir.

Zeyilname:

PHP'de Yii Framework kullanıyoruz ve hepsi bir Python rastgele harita üreteci ve oyun motoruna bağlanıyor.

Python ile yetkinseniz, PHP aracısını terk etmenizi tavsiye ederim. Oyununuzu bir Python işlemi olarak çalıştırırsanız, döşeme verilerinizi daha kolay bellekte tutabilir ve MySQL erişimini önemli ölçüde azaltabilirsiniz. Python'un PHP'den çok daha akıcı bir dil olmasına yardımcı olur.

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.