如何将游戏中的所有图像都放入一个文件?


67

我刚刚完成了一个用C ++ SFML编写的基本RPG游戏,我在游戏中付出了很多努力,我想分发它,但是遇到了一个小问题。

问题是,我有200多个图像和地图文件(其中包含地图代码的.txt文件)都与可执行文件位于同一文件夹中,当我查看该文件夹时,这让我想哭一点如此众多的资源,我从未见过一款可以直接向您显示所有资源的游戏,相反,我相信它们会将资源打包在某个文件中。

好吧,这就是我要达到的目的:我希望将所有图像打包到1个文件(可能也包括.txt文件)中,然后能够从该文件中读取或轻松添加到其中。



我已经看到了代码,其中所有图像都打包在代码中的字符串中。但这是由于要求而完成的。(这是一个64KB的Java竞赛)
Omar Kooheji 2012年

抱歉,这是4Kb Java竞赛。不是64Kb的。
Omar Kooheji 2012年

Answers:


62

游戏程序员依靠两种主要的数据存储方法之一:

  • 将每个数据文件存储为单独的文件
  • 以自定义存档格式存储每个数据文件

第一种解决方案的缺点是浪费磁盘空间问题,以及安装速度较慢的问题。

第二种解决方案提供了它自己的陷阱,首先是您必须编写所有自己的图像/声音/等。使用自定义API来访问已归档数据的加载例程。另一个缺点是,您必须首先编写自己的存档实用程序来构建存档。

除非总是从归档文件中加载所有文件,否则TAR / GZ可能不是一个好主意,因为您无法根据需要提取特定文件。这就是许多游戏使用ZIP存档的原因,ZIP存档确实允许您根据需要提取单个文件(一个很好的例子是Quake 3,其PK3​​文件不过是具有不同扩展名的ZIP文件)。

编辑: “隐藏”游戏文件夹结构,仅“保留”可执行文件

另一个解决方案通常用于“隐藏”文件夹结构中的游戏文件。在主目录中仅保留可执行文件和自述文件,然后将游戏文件移动到名为“ data”或其他相关文件的子文件夹中。

编辑: Gamedev Tuts Plus有一个不错的资源

编辑: libarchive

一种可能的解决方案libarchive,它是一个归档库,它将处理从存档中提取文件的问题,例如ZIP文件。它甚至允许您将提取的文件分配给标准FILE指针,这将使与任何其他库的接口可能更直接。

编辑:具有其他扩展名的ZIP格式文件

在这里,我喜欢@Joachim Sauer的评论

在游戏之外,使用具有替代扩展名的ZIP格式文件也具有悠久的传统:Java可以做到Java是OpenDocument格式(又名OpenOffice / LibreOffice格式),甚至Office Open XML(又名“新” Microsoft Office格式)都可以使用。做到了


2
是的,Thief / SystemShock2也使用.zip文件重命名了其他名称。在Java中,您可以使用TrueZip之类的东西来访问zip中的文件,就好像它们是文件夹中的文件一样,我想对于C ++也有类似的库。
尼克


5
@Svish。根据平台的不同,即使根本不压缩大文件,许多小文件占用的磁盘空间也可能比一个大文件占用的磁盘空间大得多.tar。这与数据物理存储在磁盘上的方式有关。
TRiG 2012年

1
啊,是的。虽然不应该太多,除非有很多,但是在那种情况下它确实可以建立。我可以想象安装和卸载也会带来很多小文件。
Svish 2012年

2
与Kylotan的评论略相关,这是Jonathan Blow在The Witness的dev-blog上的帖子,内容涉及使用档案以及它们如何与Steam的补丁机制交互。“见证人将其大多数数据打包到一个以.zip格式存储的2 GB的文件中。在将初始版本上传到Steam之前,我采取了保护措施以最小化补丁大小,或者我想[...](Imagine文件是以随机顺序存储的:可能每个补丁都涉及到每个玩家重新下载整个游戏!)”
Eric

39

通常用于“隐藏”游戏文件的另一种解决方案是文件夹结构。在主目录中仅保留您的可执行文件,可能还保留一个自述文件,然后将游戏文件移动到子文件夹“ data”中。我认为这样做并非罕见。我知道许多游戏都以这种方式存储其内容。


8
+1如果磁盘空间或保护不是问题,那是最简单的解决方法。
Laurent Couvidou 2012年

1
+1,因为另一个人说+1。不会错,是吗?(开个
玩笑

我认为这是理想的选择。如果文件系统不能有效地处理该文件系统,则该文件系统已损坏,您应该依靠操作系统制造商进行改进。
2012年

3
@Omnifarious并非总是如此,例如,当从光盘读取数据时,即使具有完美的文件系统,也通常会在加载文件时打包文件,以防止过度搜索(速度提高实际上是非常令人惊讶的)。但这对于硬盘来说是完全不同的故事,我倾向于认为OP在这种情况下就是如此。
Laurent Couvidou 2012年

3
@野兽先生你错过了我的观点。我说的是光盘。我曾在一家工作室工作过,这是一个程序员的全职工作,以确保将文件尽可能高效地打包在DVD上,从而获得最佳的加载时间。我相信他会很高兴得知他可以仅仅依赖DVD文件系统;)
Laurent Couvidou 2012年

22

我真的很喜欢PhysFS。它允许您使用相同的代码访问文件夹或zip存档。它在游戏生命周期的所有阶段都运作良好。

  1. 开发期间:直接从文件夹层次结构访问资源。这样,压缩归档文件就不会出现问题,您可以快速进行迭代。
  2. 初始部署:压缩您的资源,以方便部署/快速安装。无需更改任何代码。只需将PhysFS指向拉链而不是文件夹。
  3. 更新/更改:PhysFS可以加载多个zip档案,其中一个档案的资源会覆盖另一个档案。更新可以像仅包含更改文件的新zip一样简单。改装也是如此。

更新:

我使用了源附带的教程doxygen文档来学习PhysFS。该API确实非常简单,您将花费更多的时间来学习如何通过内存缓冲区而不是文件路径将图像加载到SFML中。


4
我正在为当前项目使用PhysFS,我喜欢它。我并不总是需要重新生成内容存档文件。我可以在搜索路径和BAM中添加更新的版本!有用。
Zack The Human

经过一番回答后,我决定我将使用physFS。您是否愿意推荐一个不错的教程?:)
Bugster 2012年

12

我建议使用一个ZIP文件。这是一种无处不在的格式,您会发现现成的库,可让您从ZIP文件中加载文件。快速的Google搜索甚至显示了sfmlzip加载器


3

好吧,您可以像他们提到的那样作弊:)您可以从图像中制作一张精灵表,如今无需压缩它,除非它节省了大量空间。从图像创建一个精灵表或几个精灵表后,您可以简单地重命名其扩展名。大多数游戏玩家都不会打扰检查,为什么不把这个选项留给将来可能要修改游戏的艺术家呢?这样,他们也可以创建一个sprite-sheet,重命名它的扩展名并开始滚动。

对于文本文件,我谨建议您将数据转换为二进制形式。我敢肯定,您会找到一种简单的方法。例如,如果您仅使用AZ,az和0-9,则可以使用6位来表示每个字符,这将在某种程度上保护您受版权保护的材料,也会阻止其他人编辑地图。.如果愿意,您随时可以添加地图转换器。压缩对于文本来说是完全合理的。


转换为二进制是一个很好的建议,但不是为了提供保护-它将更易于解析和加载。建议将其作为预处理步骤,但这将使该问题脱离主题。
Maximus Minimus 2012年

好吧,我猜,如果他想更有效地保护它,他可以尝试使用RSA或类似算法对它进行加密(没有必要)。我怀疑有人将二进制游戏中的独立游戏中的地图文件用于未经授权的使用。似乎不值得花费时间来确定我们的解析。文本文件是完全容易受到攻击的,并且正如您所建议的那样,存储数据无效。
wolfdawn 2012年

3
在HDD上,加载单个zip文件比许多小文件要快,因为对物理磁盘的随机寻道成本较低。小型游戏的二进制文件可以映射到内存中,并且可以“神奇地”工作,几乎不需要解析。
丽山2012年

@Liosan您可能会误解了我的意思,或者我误解了您。.我说过二进制更适合存储数据,并且其他游戏设计者不太可能想要学习如何解析您的二进制地图代码,除非记录并鼓励进行二进制编码目的。因此,它对文本文件提供了一些基本的保护。
wolfdawn 2012年

2

这不仅与资源或磁盘空间的数量有关。
在使用OpenGL渲染的SFML的情况下,有很多不同的纹理文件,每次要渲染纹理时,OpenGL都需要将下一个纹理绑定到视频卡(请检查glBindTexture()),并且一项非常昂贵的任务。
考虑到这一点,您可以了解为什么游戏通常会根据您的菜单/级别/地图,将多个精灵放置在相同的纹理(即所谓的精灵表)中。
结果是,通过使用相同的绑定纹理调用渲染许多精灵,可以极大地提高性能。


在获得了制作Spritesheet的一些参考之后,我考虑了一些重构以减少图像数量。谢谢
Bugster 2012年

2

我将亲自为此定制二进制文件路由。这是我现在一直在做的事情,它听起来并不像听起来那么困难,而且还为您的游戏资源文件提供了一定程度的混淆。如果您有兴趣,我不久前写了一篇有关Gamedev的介绍性文章:

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

Sprite-sheets完全是一个不同的主题,但是对于大多数游戏来说,它们都是常态:)


1

您可以使用的另一种方法:

XnView的免费版本提供了一个名为“ Strip of Images”(SHIFT + A)的功能,可让您创建sprite-collections

这样可以最大程度地减少文件访问量,对于减少Web应用程序/游戏的数量尤其重要HTTP-roundtrips

然后通过坐标图(例如css-definitions)授予对单个图像的访问权限。


0

首先,您必须编写所有自己的图像/声音/等。使用自定义API来访问已归档数据的加载例程。另一个缺点是,您必须首先编写自己的存档实用程序来构建存档。除非总是从存档中加载所有文件,否则TAR / GZ可能不是一个好主意,因为您无法根据需要提取特定文件。这就是许多游戏使用ZIP存档的原因,ZIP存档确实允许您根据需要提取单个文件(一个很好的例子是Quake 3,其PK3​​文件不过是具有不同扩展名的ZIP文件)。 http://zpp-library.sourceforge.net/

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.