Bir oyundaki tüm görüntüleri 1 dosyaya nasıl koyabilirsin?


67

C ++ SFML ile yazılmış basit bir RPG oyununu yeni bitirdim, oyuna çok çaba sarf ettim ve dağıtmak isterdim, ancak küçük bir sorunla karşılaştım.

Sorun şu ki, 200'den fazla resim ve harita dosyam var (hepsi harita kodlarını tutan .txt dosyaları) yürütülebilir dosyayla aynı klasörde. Klasöre baktığımda, biraz ağlamak istememe neden oluyor o kadar çok kaynak, hiç bir zaman tüm kaynakları size gösteren bir oyun görmedim, bunun yerine kaynakları belli bir dosyaya topladıklarına inanıyorum.

Tamam, elde etmeye çalıştığım şey bu: Tüm görüntüleri 1 dosyaya yerleştirmeyi umuyorum (belki .txt dosyaları da) o zaman bu dosyadan okuyabilir veya kolayca ekleyebilirim.



Koddaki tüm resimlerin bir dizgeye yerleştirildiği bir kod gördüm. Ancak bu gereksinimler nedeniyle yapıldı. (64KB Java yarışmasıydı)
Omar Kooheji

Üzgünüz, 4 KB'lık bir java yarışmasıydı. 64 Kb değil.
Omar Kooheji 28:12

Yanıtlar:


62

Oyun programcıları, iki ana veri depolama yönteminden birine güvenmiştir:

  • her veri dosyasını ayrı bir dosya olarak saklayın
  • her veri dosyasını özel bir arşiv biçiminde saklayın

İlk çözümün dezavantajı boşa harcanan disk alanı problemi ve daha yavaş kurulum problemidir.

İkinci çözüm, kendi tuzaklarını sağlar, ilk önce kendi görüntü / ses / etc'inizi yazmanız gerekir. arşivlenmiş verilere erişmek için özel bir API kullanan rutinleri yükleme. Diğer bir dezavantajı, arşivleri ilk etapta oluşturmak için kendi arşivleme yardımcı programını yazmanız gerektiğidir.

Tüm dosyaları her zaman arşivden yüklemeyecekseniz, TAR / GZ çok iyi bir fikir olmayabilir, çünkü belirli dosyaları istediğiniz gibi çıkaramazsınız. Birçok oyunun bireysel dosyaları gerektiği gibi çıkarmanıza izin veren ZIP arşivlerini kullanmasının nedeni budur (iyi bir örnek, PK3 dosyaları farklı bir uzantıya sahip ZIP dosyalarından başka bir şey olmayan Quake 3'tür).

EDIT: oyun klasörü yapısını "gizle" ve sadece çalıştırılabilirleri "tut"

Başka bir çözüm de genellikle oyun dosyalarını klasör yapısında "gizlemek" için kullanılır. Yalnızca çalıştırılabilir dosyalarınızı ve belki de ana dizindeki bir benioku dosyasını saklayın ve oyun dosyalarını "data" veya benzeri bir dosya adı altında bir alt klasöre taşıyın.

EDIT: Gamedev Tuts Plus'ın güzel bir kaynağı var

EDIT: libarchive

ZIP dosyası gibi bir arşivden dosyaları çıkarmayı işleyen bir arşivleme kütüphanesi olan potansiyel bir çözüm kütüphanesi. Ayıklanan dosyayı standart bir DOSYA işaretleyicisine atamanıza izin verir, bu da diğer tüm kitaplıklarla etkileşimi potansiyel olarak daha kolay hale getirir.

EDIT: ZIP Alternatif uzantılı dosyalar biçimlendirin

Burada, @Joachim Sauer adlı kullanıcının Yorumunu beğendim

Alternatif uzantılı Posta formatlı dosyaları kullanma yanı oyunların dışında büyük bir geleneğe sahiptir: Java yapar , OpenDocument Biçimi (OpenOffice / LibreOffice biçimi aka) yapar , hatta ( "yeni" Microsoft Office biçiminde aka) Office Açık XML yapar .


2
Evet, Thief / SystemShock2 kullanılmış .zip dosyaları da başka bir şey olarak yeniden adlandırıldı. Java'da, fermuarlardaki dosyalara, klasörlerdeki dosyalara erişmek için TrueZip gibi bir şey kullanabilirsiniz, C ++ için benzer kitaplıklar olduğunu hayal ediyorum.
Nick

18
Alternatif uzantılı Posta formatlı dosyaları kullanma yanı oyunların dışında büyük bir geleneğe sahiptir: Java yapar , OpenDocument Biçimi (OpenOffice / LibreOffice biçimi aka) yapar , hatta ( "yeni" Microsoft Office biçiminde aka) Office Açık XML yapar , ...
Joachim Sauer

5
@Svish. Platforma bağlı olarak, çok sayıda küçük dosya tarafından alınan disk alanı miktarı, büyük bir dosya hiç sıkıştırılmasa bile ( .tarörneğin) büyük bir dosya tarafından alınan miktardan çok daha büyük olabilir . Verilerin fiziksel olarak diskte depolanma şekli ile ilgilidir.
TRiG

1
Ah, bu doğru. Olmadığı sürece, gerçi pek olmamalı çok , ama bu durumda gerçekten birikebilir. Yükleme ve kaldırma işlemlerini de birçok küçük dosya ile gerçekleştireceğinizi hayal edebiliyorum.
Svish

2
Birazcık Kylotan'ın yorumuyla ilgili olarak, Jonathan Wit'in The Witness'ın blogunu arşivleri kullanma ve Steam'in yama mekanizmalarıyla nasıl etkileşime girdikleri hakkında yazdığı bir yazı . “Şahit, verilerinin çoğunu .zip biçiminde depolanan 2 gigabaytlık tek bir dosyaya paketliyor. İlk sürümü Steam'e yüklemeden önce, yama boyutlarını en aza indirgemek için bir güvenlik önlemi aldım ya da düşündüm [...] (Imagine) Bu dosyalar rastgele sırayla saklanır: Muhtemelen her yama tüm oyuncuyu tüm oyunu tekrar indirmeyi içerir!) "
Eric

39

Genellikle oyun dosyalarını "gizlemek" için kullanılan başka bir çözüm de klasör yapısıdır. Yalnızca çalıştırılabilir dosyalarınızı ve belki de ana dizindeki bir benioku dosyasını saklayın ve oyun dosyalarını alt bir veri klasörüne taşıyın. Bunu yapmanın çok nadir olduğunu sanmıyorum. Bildiğim birçok oyun içeriklerini bu şekilde saklıyor.


8
+1 Disk alanı veya koruma bir sorun değilse, bu en kolay çözümdür.
Laurent Couvidou

1
+1 çünkü diğer adam +1 dedi. Yanlış olamaz, ha? (Bir kenara şaka
yapıyorum

Bu, benim görüşüme göre, ideal bir seçimdir. Dosya sistemi bunu etkili bir şekilde kaldıramazsa, dosya sistemi bozulur ve onu geliştirmek için işletim sistemi üreticisine yaslanmış olmalısınız.
Omnifarious

3
@Onnararious Her zaman doğru değildir, örneğin bir optik diskten okurken, hatta mükemmel bir dosya sistemiyle bile, aşırı arama yapılmasını önlemek için dosyaları yükleme sırasına koymak yaygındır (hızlanma gerçekten şaşırtıcı olabilir). Ancak bu, sabit diskler için tamamen farklı bir hikaye ve OP'nin bu durumda olduğunu düşünme eğilimindeyim.
Laurent Couvidou

3
@ BayBeast Amacımı kaçırdınız. Optik disklerden bahsediyorum. Mümkün olan en iyi yükleme süresini elde etmek için dosyaların DVD'de mümkün olduğunca verimli bir şekilde paketlendiğinden emin olmak için tek bir programcının tam zamanlı işi olduğu bir stüdyoda çalıştım. Eminim sadece DVD dosya sistemine güvenebileceğini öğrenmekten memnuniyet
duyardı

22

Bunun için PhysFS'yi gerçekten seviyorum . Klasörlere veya zip arşivlerine aynı kodla erişmenizi sağlar. Oyun ömrünün tüm aşamalarında işe yarar.

  1. Geliştirme sırasında : kaynaklara doğrudan bir klasör hiyerarşisinden erişin. Bu şekilde sıkıştırılmış arşivler yolunda değildir ve hızlı bir şekilde yineleyebilirsiniz.
  2. İlk dağıtım : kolay dağıtım / hızlı kurulum için kaynaklarınızı sıkıştırın. Kod değiştirmek gerekmez. PhysFS'i klasör yerine zip yerine koy.
  3. Güncellemeler / Modlama: PhysFS, kaynakların birinden diğerine geçmediği birden fazla zip arşivi yükleyebilir. Güncellemeler sadece değiştirilen dosyalar ile yeni bir zip kadar basit olabilir. Benzer şekilde modding için.

Güncelleme:

PhysFS öğrenmek için kaynak ve doxygen belgelerine dahil edilen öğreticiyi kullandım . API oldukça basittir, görüntülerin SFML'ye dosya yolu yerine bellek arabellekleri ile nasıl yükleneceğini öğrenmek için daha fazla zaman harcarsınız.


4
Mevcut projem için PhysFS kullanıyorum ve onu seviyorum. İçerik arşiv dosyamı her zaman yeniden oluşturmam gerekmiyor; Arama yoluna ve BAM’a güncellenmiş bir sürümü bırakabilirim! İşe yarıyor.
Zack, İnsan

Bazı cevaplardan sonra ben physFS ile gideceğim karar verdim. Güzel bir eğitim önerebilir misiniz? :)
Bugster

12

ZIP dosyası kullanmanızı öneririm. Her yerde bulunan bir formattır ve bir ZIP dosyası içinden dosya yüklemenizi sağlayan hazır kütüphaneler bulacaksınız. Hızlı bir Google araması bile sfml için bir zip yükleyici ortaya çıkardı .


3

Eh, dedikleri gibi hile yapabilirsin :) Görüntüden bir sprite-sayfası yapabilirsin, bugünlerde tonlarca yer kazanmadığı sürece onu sıkıştırmaya gerek yok. Görüntülerden bir hareketli grafik sayfası veya birkaç hareketli grafik sayfası oluşturduktan sonra, uzantılarını yeniden adlandırabilirsiniz. Çoğu oyuncu kontrol etmeye zahmet etmeyecek ve neden bu seçeneği gelecekte oyununuzu değiştirmek isteyebilecek Sanatçılar'a bırakmayacaksınız? Bu şekilde bir sprite sayfası da oluşturabilirler, uzantısını yeniden adlandırabilir ve yayınlanmaya başlayabilirler.

Metin dosyaları ile alçakgönüllülükle bu verileri ikili forma dönüştürmenizi öneririm. Bunu yapmanın basit bir yolunu bulacağınızdan eminim .. Örneğin, yalnızca AZ, az ve 0-9 kullanıyorsanız, her bir karakteri temsil etmek için 6 bit kullanabilirsiniz, bu telif hakkıyla korunan malzemenizi biraz koruyacaktır, ayrıca başkalarının haritaları düzenlemesini de önleyecektir. İsterseniz her zaman bir harita dönüştürücü ekleyebilirsiniz. Sıkıştırma da metin için tamamen mantıklı.


İkili dosyaya dönüştürmek iyi bir öneridir ancak koruma için değildir - sadece ayrıştırması daha kolay ve daha hızlı yüklenir. Bir ön işleme adımı olarak önerebilir, ancak bu soru için konu dışı olacak.
Maximus Minimus

Tahmin ediyorum, daha etkili bir şekilde korumak istiyorsa, onu RSA veya benzeri bir algoritmada şifrelemeye çalışabilir (gerek yok). İkili bir dosyanın içindeyse, bir indie oyundaki harita dosyalarını yetkisiz bir şekilde kullanacak birinin şüphesi var. Ayrıştırma sürecimizi bulmak için zaman harcamaya değmez. Metin dosyaları sadece tamamen savunmasızdır ve sizin veri depolamak için etkisiz bir şey önerdiğiniz gibi.
Wolfdawn

3
HDD'lerde, tek bir zip dosyası yüklemek birçok küçük dosyadan daha hızlıdır, çünkü fiziksel diske daha ucuz rastgele aramalar yapılır. Küçük bir oyun için bir ikili hafızaya eşlenebilir ve “sihirli” olarak çalışabilir, neredeyse ayrıştırmaya gerek kalmaz.
Liosan

@Liosan Ne demek istediğimi yanlış yorumlamış olabilirsiniz veya sizi yanlış anladım .. Ben ikilinin veri depolamak için daha iyi olduğunu ve diğer oyun tasarımcılarının, ikili harita kodunuzu nasıl ayrıştıracağınızı öğrenmek isteme olasılığının düşük olduğunu söyledim. amaçlar. Bu nedenle, metin dosyaları üzerinde bazı temel korumalar sunar.
Wolfdawn

2

Sadece kaynak sayısı veya disk alanı ile ilgili değil.
OpenGL ile çalışan SFML'yi kullandığınız birçok farklı doku dosyasıyla, bir doku oluşturacağınız her seferinde, OpenGL'nin bir sonraki dokuyu ekran kartına bağlaması gerekir (glBindTexture ()) ve gerçekten pahalı bir görev.
Bunu göz önünde bulundurarak, oyunların genellikle oyunun menülerine / seviyelerine / haritalarına göre spritesheets adı verilen aynı dokuya birkaç sprite koyduğunu fark edebilirsiniz.
Sonuç, aynı cilt dokusu çağrısı ile çok sayıda sprit oluşturduğunuz için performansta büyük bir kazançtır.


Bir spritesheet yapmak için birkaç referans aldıktan sonra, görüntü sayısını düşürmek için bazı refactoring sayılır. Teşekkürler
Bugster 25:12

2

Kişisel olarak bunun için özel ikili dosya yolunu izlerdim. Bu şimdi her zaman kendim yaptığım bir şey, göründüğü kadar zor değil ve aynı zamanda oyun kaynak dosyalarınız için gizlilik düzeyi de sağlıyor. İlgileniyorsanız, uzun zaman önce bununla ilgili küçük bir giriş yapan Gamedev makalesi yazdım:

http://gamedev.tutsplus.com/tutorials/implementation/create-custom-binary-file-formats-for-your-games-data/

Sprite-levhalar tamamen farklı bir konudur, ancak çoğu oyunun normlarıdır :)


1

Kullanabileceğiniz başka bir yöntem:

XnView'ün ücretsiz sürümü, " Strip of Images" (ÜSTKRKT + A) adlı, oluşturmanıza olanak sağlayan bir özellik sunar sprite-collections.

Bu, dosya erişimini en aza indirir ve web uygulamalarının / oyunların sayısını azaltmak için özellikle önemlidir HTTP-roundtrips.

Tek tek görüntülere erişim daha sonra koordinat haritaları (örneğin css-tanımları) ile sağlanır.


0

Öncelikle, kendi görsel / ses / etc'inizi yazmalısınız. arşivlenmiş verilere erişmek için özel bir API kullanan rutinleri yükleme. Diğer bir dezavantajı, arşivleri ilk etapta oluşturmak için kendi arşivleme yardımcı programını yazmanız gerektiğidir. Tüm dosyaları her zaman arşivden yüklemeyecekseniz, TAR / GZ çok iyi bir fikir olmayabilir, çünkü belirli dosyaları istediğiniz gibi çıkaramazsınız. Birçok oyunun bireysel dosyaları gerektiği gibi çıkarmanıza izin veren ZIP arşivlerini kullanmasının nedeni budur (iyi bir örnek, PK3 dosyaları farklı bir uzantıya sahip ZIP dosyalarından başka bir şey olmayan Quake 3'tür). http://zpp-library.sourceforge.net/

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.