ゲームのすべての画像を1つのファイルに配置するにはどうすればよいですか?


67

C ++ SFMLで書かれた基本的なRPGゲームを完成させたばかりで、ゲームに多大な労力を注ぎ、配布したいと考えていますが、小さな問題に遭遇しました。

問題は、実行可能ファイルと同じフォルダー内にすべての200個を超える画像とマップファイル(マップコードを保持する.txtファイル)があり、フォルダーを見ると少し泣きたい非常に多くのリソースがあるので、すべてのリソースを直接表示するゲームを見たことはありません。代わりに、特定のファイルにリソースを詰め込んでいると思います。

まあ、それは私が達成しようとしていることです:すべての画像を1つのファイル(おそらく.txtファイルかもしれません)に詰めて、そのファイルから読み取るか簡単に追加できるようにしたいと思っています。



すべての画像がコード内の文字列にパックされているコードを見てきました。しかし、それは要件のために行われました。(
64 KBの

申し訳ありませんが、4KbのJavaコンテストでした。64Kbではありません。
オマーKooheji

回答:


62

ゲームプログラマは、データストレージの2つの主な方法のいずれかに依存しています。

  • 各データファイルを個別のファイルとして保存する
  • 各データファイルをカスタムアーカイブ形式で保存する

最初の解決策の欠点は、無駄なディスク領域の問題と、インストールの速度が遅いという問題です。

2番目の解決策は、独自の落とし穴を提供します。1つ目は、すべての独自のイメージ/サウンドなどを記述する必要があるということです。アーカイブされたデータにアクセスするためにカスタムAPIを使用するロードルーチン。さらなる欠点は、最初にアーカイブを作成するために独自のアーカイブユーティリティを作成する必要があることです。

アーカイブからすべてのファイルを常にロードしない限り、特定のファイルを必要に応じて抽出できないため、TAR / GZはあまり良いアイデアではないかもしれません。これが、多くのゲームが必要に応じて個々のファイルを抽出できるZIPアーカイブを使用する理由です(良い例は、PK3ファイルが異なる拡張子のZIPファイルにすぎないQuake 3です)。

編集:ゲームフォルダー構造を「非表示」にし、実行可能ファイルのみを「保持」する

別のソリューションは、フォルダ構造内のゲームファイルを「隠す」ためによく使用されます。メインディレクトリに実行可能ファイルとreadmeファイルのみを保存し、ゲームファイルを「data」または他の関連するサブフォルダーに移動します。

編集: Gamedev Tuts Plusには素晴らしいリソースがあります

編集: libarchive

1つの潜在的なソリューションlibarchive。これは、ZIPファイルなどのアーカイブからのファイルの抽出を処理するアーカイブライブラリです。さらに、抽出したファイルを標準のFILEポインターに割り当てることもできます。これにより、他のライブラリとのインターフェースがより簡単になる可能性があります。

編集:代替拡張子を持つZIP形式のファイル

ここでは、@ Joachim Sauerのコメントが好きです

代替の拡張子を持つZIP形式のファイルを使用することだけでなく、ゲームの外の偉大な伝統を持っている:Javaはそれをしない(OpenOfficeの/ LibreOfficeの形式別名)のOpenDocumentフォーマットは、それをしない、でも(「新」のMicrosoft Office形式別名)OfficeオープンXMLそれを行います。


2
確かに、Thief / SystemShock2は.zipファイルを使用して他の名前に変更しました。Javaでは、TrueZipのようなものを使用して、zip内のファイルにアクセスできます。まるでフォルダー内のファイルであるかのように、C ++用の同様のライブラリーがあると思います。
ニック

18
代替の拡張子を持つZIP形式のファイルを使用することだけでなく、ゲームの外の偉大な伝統を持っている:Javaはそれをしない(OpenOfficeの/ LibreOfficeの形式別名)のOpenDocumentフォーマットは、それをしない、でも(「新」のMicrosoft Office形式別名)OfficeオープンXMLそれはありません、...
ヨアヒム・ザウアー

5
@Svish。プラットフォームによっては、多数の小さなファイルが占めるディスク容量は、その大きなファイルがまったく圧縮されていない場合でも(.tarたとえば)、1つの大きなファイルが占める容量よりもかなり大きくなる可能性があります。データをディスクに物理的に保存する方法に関係しています。
TRiG

1
ああ、それは本当です。ただし、が多くない限り、多くはないはずですが、その場合は実際に蓄積されます。インストールとアンインストールも、多くの小さなファイルでヒットすることを想像できます。
Svish

2
少しKylotanさんのコメントに関連し、ここにあるポストのアーカイブを使用し、それらがどのようにスチームのパッチ適用メカニズムとの相互作用についての証人DEV-ブログのジョナサン・ブロウによって。「Witnessは、ほとんどのデータを.zip形式で保存された単一の2ギガバイトファイルにパックします。初期バージョンをSteamにアップロードする前に、パッチサイズを最小限に抑えるための安全対策を講じました。そのファイルはランダムな順序で保存されます。おそらく、すべてのパッチにはすべてのプレーヤーがゲーム全体を再ダウンロードする必要があります!)」
Eric

39

ゲームファイルを「隠す」ためによく使用される別のソリューションは、フォルダー構造です。メインディレクトリに実行可能ファイルとreadmeのみを保存し、ゲームファイルをサブフォルダー「data」に移動します。そうすることはめったにないとは思いません。私が知っている多くのゲームは、そのような方法でコンテンツを保存します。


8
+1ディスク容量または保護が問題にならない場合、それが最も簡単な修正方法です。
ローランクービドゥー

1
+1他の男が+1を言ったから。間違ってはいけませんよね?(冗談はさておき、素晴らしい答え。)
jcora

私の意見では、これが理想的な選択です。ファイルシステムがそれを効率的に処理できない場合、ファイルシステムは壊れているので、OSメーカーに頼って改善する必要があります。
オムニファリアス

3
@Omnifarious必ずしもそうとは限りません。たとえば、完璧なファイルシステムであっても、光ディスクから読み取るときは、過度のシークを防ぐためにファイルをロード順にパックするのが一般的です(実際、スピードアップは驚くべきことです)。しかし、これはハードディスクにとってはまったく異なる話であり、OPはこの場合にあると思う傾向があります。
ローランクーヴィドゥ

3
@ Mr.Beastあなたは私のポイントを逃しました。私は光ディスクについて話している。単一のプログラマーのフルタイムの仕事であるスタジオで働いて、DVDにファイルをできる限り効率的にパックして、可能な限り最高の読み込み時間を確保しました。私は彼がDVDファイルシステムに頼ることができたことを知って喜んでいると確信しています;)
ローランCouvidou

22

私はこのためにPhysFSが本当に好きです。同じコードでフォルダーまたはzipアーカイブにアクセスできます。それは、ゲームのライフタイムのすべての段階でうまく機能します。

  1. 開発中:フォルダー階層から直接リソースにアクセスします。このように、圧縮アーカイブは邪魔にならず、迅速に反復できます。
  2. 初期展開:リソースを圧縮して、簡単に展開/迅速にインストールできるようにします。コードを変更する必要はありません。フォルダーではなく、zipでPhysFSをポイントするだけです。
  3. アップデート/改造:PhysFSは、一方のリソースが他方をオーバーライドする複数のzipアーカイブをロードできます。更新は、変更されたファイルのみを含む新しいzipと同じくらい簡単です。改造についても同様です。

更新:

ソースとdoxygenのドキュメントに含まれているチュートリアルを使用して、PhysFSを学習しました。APIは本当に簡単です。ファイルパスではなくメモリバッファを介してSFMLに画像をロードする方法を学習するのにより多くの時間を費やします。


4
現在のプロジェクトにPhysFSを使用していますが、とても気に入っています。コンテンツアーカイブファイルを常に再生成する必要はありません。更新されたバージョンを検索パスとBAMにドロップするだけです!できます。
ザック人間

いくつかの答えの後、私はphysFSを使用することにしました。素敵なチュートリアルをお勧めしますか?:)
バグスター


3

さて、あなたは彼らが言及したようにチートすることができます:)あなたは画像からスプライトシートを作ることができます、それはトンのスペースを節約しない限り、今日それを圧縮する必要はありません。画像からスプライトシートまたは複数のスプライトシートを作成した後、単に拡張子の名前を変更できます。ほとんどのゲーマーはチェックすることを気にしませんし、将来あなたのゲームを改造したいかもしれないアーティストにそのオプションを残してみませんか?そうすれば、彼らはスプライトシートを作成し、その拡張子の名前を変更してローリングを開始することもできます。

テキストファイルでは、そのデータをバイナリ形式に変換することをお勧めします。簡単な方法を見つけることができると確信しています。たとえば、AZ、az、および0-9のみを使用する場合、各文字を表すために6ビットを使用できます。また、他のユーザーがマップを編集できないようにします。必要に応じて、マップコンバーターをいつでも追加できます。ただし、テキストの圧縮は完全に合理的です。


バイナリへの変換は良いアドバイスですが、保護のためではありません-解析がより簡単になり、ロードがより速くなるでしょう。前処理ステップとしてそれを提案しますが、それは質問のトピック外になります。
マキシマスミニマス

まあ、私は、彼がより効果的にそれを保護したいなら、彼はRSAまたは同様のアルゴリズムで暗号化を試みることができると思います(必要はありません)。バイナリファイル内にある場合、インディーゲームのマップファイルを不正に使用する人はいないでしょう。解析を理解するのに時間をかける価値はないようです。テキストファイルは完全に脆弱であり、データを保存するには効果のないものを提案しました。
wolfdawn

3
HDDでは、物理ディスクへのランダムシークが安価であるため、単一のzipファイルのロードは、多くの小さなファイルよりも高速です。小さなゲームのバイナリをメモリにマップして、「魔法のように」動作させることができます。解析はほとんど必要ありません。
リオサン

@Liosan意味を誤解したり、誤解したりする可能性があります。データ保存にはバイナリの方が適していると述べました。目的。したがって、テキストファイルに対して基本的な保護を提供します。
wolfdawn

2

リソースの数やディスク領域だけではありません。
OpenGLでレンダリングするSFMLを使用しているため、テクスチャをレンダリングするたびに、OpenGLは次のテクスチャをビデオカードにバインドする必要があります(glBindTexture()を確認)。本当に高価な仕事です。
それを念頭に置いて、ゲームのメニュー/レベル/マップに従って、ゲームが通常同じテクスチャにスプライトシートと呼ばれる多くのスプライトを配置する理由を理解できます。
同じバインドテクスチャコールで多くのスプライトをレンダリングしているため、結果はパフォーマンスが大幅に向上します。


スプライトシートを作成するためのいくつかの参照を得た後、画像数を減らすためのリファクタリングを検討しました。ありがとう
Bugster

2

私は個人的にこのためのカスタムバイナリファイルルートに向かいます。これは私自身が常に行っていることで、聞こえるほど難しくはなく、ゲームリソースファイルの難読化のレベルも提供します。あなたが興味を持っているなら、私はこのことについて少し前にGamedevの紹介記事を書いた。

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

スプライトシートはまったく別のテーマですが、ほとんどのゲームでは標準です:)


1

使用できる別の方法:

XnViewの無料版には、「Strip of Images」(SHIFT + A)という機能があり、これを使用して作成できますsprite-collections

これにより、ファイルアクセスが最小限に抑えられ、Webアプリケーション/ゲームでの数を最小限に抑えるために特に重要ですHTTP-roundtrips

その後、座標マップ(css-definitionsなど)を介して個々の画像へのアクセスが許可されます。


0

最初に、あなた自身のすべての画像/音/などを書かなければなりません。アーカイブされたデータにアクセスするためにカスタムAPIを使用するロードルーチン。さらなる欠点は、最初にアーカイブを構築するために、独自のアーカイブユーティリティを作成する必要があることです。アーカイブからすべてのファイルを常にロードしない限り、特定のファイルを必要に応じて抽出できないため、TAR / GZはあまり良いアイデアではないかもしれません。これが、多くのゲームが必要に応じて個々のファイルを抽出できるZIPアーカイブを使用する理由です(良い例は、PK3ファイルが異なる拡張子のZIPファイルにすぎないQuake 3です)。 http://zpp-library.sourceforge.net/

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.