Minecraft gibi bir Blok Dünyası nasıl ele alınır


9

Minecraft'ta olduğu gibi bir blok dünyasıyla basit bir oyun yazmak istiyorum. Teorik sorum, oyun sırasında bu blok bilgilerini ele almanın en iyi yolu nedir. İlk fikrim büyük bir dizi ama bu bence bellek tükenmesine neden olacaktır. Belki de blokları sadece oyuncunun yanına yüklemeliyim.

Gerekli blok bilgilerinin bir dosyadan yüklenmesini ve sadece gerekli bilgilerin hafızada tutulmasını nasıl ele alabilirim?


2
Minecraft, dünyayı, aynı anda değil, Chunks adı verilen oldukça büyük küplere yükler. Kesin detaylardan emin değilim. Bunun nasıl gittiğine bir göz atmak istiyorsanız Minecraft kaynağını ele geçirmek oldukça kolaydır.
ratbum

Minecraft wiki'ye bir göz atın: minecraftwiki.net/wiki/Chunk
tom van green

Minecraft'ta topakları zaten biliyordum, ama yine de teşekkürler.
danijar

Bu, bu blogun kapsamı için uygun olmayan karmaşık bir sorudur.

Yanıtlar:


9

Minecraft gibi bloklarla bir oyunun verilerini saklamanın birkaç farklı yolu vardır.

Minecraft'ın buna inanma şekli, dünyayı 16x16x256 Topakları'nda kırıyor. Oynatıcı oyuna başladığında oynatıcının etrafındaki parçalar belleğe yüklenir, daha sonra etrafta dolaşırken arka plan iş parçacığı daha fazla yüklenir. İşte gösteren bir video: http://www.youtube.com/watch?v=oR_ZdJH9eho .

Bunu yapmanın başka bir yolu da dünyayı bir Octree'ye bölmektir. Michael Goodfellow, bu veri yapısı ile bir küp dünyasının uygulanması hakkında bir blog yazdı: http://www.sea-of-memes.com/LetsCode1/LetsCode1.html . Octree güzel çünkü bazı yerleşik sıkıştırma sağlar, ancak muhtemelen bir Array ile çalışmak biraz daha zor olacaktır.

"Sadece ihtiyaç duyulanları bellekte tutmak?" Ne gerekli olduğunu sormak zorunda çünkü bu biraz daha zor. Dünyanın başka bir yerinde, çevre ile etkileşime giren yapay zeka ile yaşayan NPC'leriniz varsa, o zaman bellekte olmak için dünyanın çok daha fazlasına “ihtiyacınız” vardır. Voxel dünya verileri çok hızlı çok büyük olabilir, bu yüzden mümkün olan en az miktarda hafızada kalmaya çalışmak en iyisidir. (IE, yalnızca oynatıcının yakınında NPC'lere sahiptir).

Grafik motoru, diğer şeffaf olmayan bloklarla tamamen çevrili olmayan her bloğa "ihtiyaç duyacaktır". Dünyayı oluşturmanın olağan yolu, görünür her blok için köşeleri içeren tek bir kafes oluşturmaktır. 65.536 blok için (Minecraft boyut yığınlarında) yalnızca 1 çizim çağrısı yaptığınız için bu çizmek çok daha hızlıdır. Grafik motorunun bu ağı oluşturması gerektiğinden, genellikle bir yığındaki tüm küpleri bilmesi gerekir. Bu yüzden Minecraft'ta zemini gördüğünüzde, dünyanın bir çok görünmez olduğunu unutmayın. Bunun nedeni, altı tarafın etrafını saran her bloğun atlanmasıdır. Minecraft'ın aynı tür dokunun yatay kenarlarını doku tekrarı ile tek bir kutuda birleştirerek köşe sayısını da azalttığına inanıyorum.

Benim tavsiyem 16x16x256 parçaları ile gitmek olacaktır. Mesh ve oyun mantığı (çarpışma algılama, blok ekleme / çıkarma, vb.) Nedeniyle hızlı yineleme ve düzenlemeye ihtiyacınız olacağından bunları bir Array'da saklayın. Ardından, oynatıcının çevresini olabildiğince çok parçaya yükleyin. Daha iyi veya daha kötü bilgisayarlar için parça sayısını artırın veya azaltın.

Parçaların yüklenmesi performansta büyük bir hit olacak, bu yüzden onu zaman içinde çalıştıran bir iş parçacığına koyun. Bir oyuncunun bir parçanın bir ucundan diğer ucuna yürümesi gereken süre boyunca tamamen 3 yeni Tıklama yükleyebilmenizi sağlayın.


Teşekkür ederim! Yapay zeka hakkında hiçbir şey yok çünkü MMO için bir müşteri yazıyorum. NPC'lerin hesaplanması sunucu tarafından yapılır. Bir ek: Grafik motoru "şeffaf olmayan diğer bloklarla tamamen çevrili olmayan her bloğa" ihtiyaç duymaz. Mağaralar varsa oyuncu önemsiz olduğunu göremez. ;-)
danijar

2
Oyuncunun göremediği mağaralar hakkında ... Sanırım mağaraları çizmek, mağaranın tamamen kapatılıp kapatılmadığını belirlemek yerine daha az performans kullanıyor. Ve eğer mağara çizmezseniz, o zaman bir bloğu kaldırırsanız, potansiyel olarak sadece bir tane yerine birden fazla parça için ağ oluşturmanız gerekir. Mağaraları dışlamak için bir yol bulmak güzel olurdu, verimli bir şekilde yapmanın bir yolunu düşünemiyorum: D.
Thomas Marnell

3

Bunu açıklamanın en iyi yolu olmayabilir ama deneyeceğim.

Daha verimli hale getirmenin en iyi yolunun Vokselleri anlamak olduğunu düşünüyorum. Minecraft voksel tabanlıdır, sadece küreler vb. Yerine küpler kullanır.

Temel olarak bir voksel, dinamik olarak değiştirilmiş bir hacme sahip olabilen bir 3D şeklidir ve hacim değiştiğinde şekil de değişir. Chunk, X x X x X voksel setidir. Örneğin, 16x16x16 voksel içeren bir parçaya sahip olabilirsiniz ve sonra X sayıda parçaya sahip olabilirsiniz. Bir mesafe ayarına sahip olacaksınız, eğer oyuncu herhangi bir parçadan N'den uzakta ise, bunları hesaplamalarınıza dahil etmeyin. Bu, kırpma mesafelerine benzer, ancak her bir parçaya da uygulanması gerekir. Bu şekilde, çalarınızı daima 3x3'lük bir dizi Chunks'in merkezinde toplayabilmeniz için sahip olabilirsiniz.

Yani sahip olacağınız şey bireysel Vokselleri idare edecek bir sınıftır. Biz buna Voxel_cl diyeceğiz. Ve sonra Voksel_cl adında voksel yığınını işlemek için bir sınıfınız olurdu. Ve sonra World_cl olarak adlandırılan vokselleri üretecek tüm parçaları üreten bir dünya sınıfına sahip olacaksınız.

Şimdi her şeyin büyük bir dizi yerine, herhangi bir zamanda 9 parça bir dizi olurdu ve yığın sınıfta, 4096 voksel bir dizi olurdu.

Bunun oldukça basit bir açıklama olduğunu lütfen unutmayın. Şu anda voksel kullanarak bir şey üzerinde çalışıyorum, bu yüzden benim girdi atmak düşündüm = -)

Voksellerle ilgili daha fazla bilgi için http://en.wikipedia.org/wiki/Marching_cubes adresini ziyaret edin.


3
Yürüyen Küpler vokselleri görselleştirmekle ilgilidir. Minecraft bile kullanmıyor; sadece küpleri çiziyor, bu da Yürüyen Küplerin tam olarak yapmamasıyla ilgili .
Nicol Bolas

Açıklaman için teşekkürler! Daha önce hiç Voxels duymadım ve projem için çok önemli görünüyor. Ama şimdi bir sorum var.
danijar

Her öğenin bu yığın voksel bir dizi içerdiği bir dizi yakın yığın oluşturma anlıyorum. Ama sonra oyuncu dünyada hareket ettiğinde yığın dizisini değiştirmem gerekiyor. Kayıt dosyasından gerekli parçaları okumak zorunda mıyım? Yoksa onları hafızada tutmanın iyi bir yolu var mı?
danijar

2
@danijar Sadece bazı önemsiz şeyler, piksel "resim öğesi" için kısadır, voksel "hacim öğesi" ile aynı şekilde oluşturulur. Hiçbir şey için önemli değil, ama sizin için ilgi çekici olabileceğini düşünmeden voksel terimini duymamış olduğunuzdan.
Daniel Carlsson

1

Oluşturucu yalnızca gördüklerinizle çalışırken, görünür yüzeyleri oluşturmaya çalışabilirsiniz, bilgisayar arka planda blok verilerini işler. 8x8 parçalarının işlenmesi daha kolay olurdu.

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.