游戏资源打包方法总结

版权声明:允许转载到个人博客和技术网站,但必须注明是转载,且给出原文链接。引用到书面,包括杂志文章和书籍,请标明出处。 https://blog.csdn.net/n5/article/details/1512712

虽然资源打包是个基本问题,但我几乎没见过有人谈过。所以自己总结一下。
本文贴在csdn n5 blog上( blog.csdn.net/n5 ),转载请保持完整性。另外本文是持续补充和更新的。

首先,定义两个名词。
block :打包数据的单位,可以是一个文件也可以是一个数据块。总之是资源包中的一块数据。
包,资源包:即包含多份数据的一个文件。

1 block size + block data 
  按数据块大小+数据块内容的方式将一批数据块逐个打包。这是比较简单实用的方法。往往还需要生成一个文本文件指明每个数据块是什么内容。如果按照默认顺序打包和读取就不需要了。
这种方法主要用于包中的数据需要全部同时读出的情况。因为这种格式的包,从中间单独抽取某个数据块读出比较麻烦。只能跳过若干数据块。

2 offset table + block datas
 这种方式下,首先在包头部写入一个offset table,即每个数据块在包中的起始位置。然后将所有数据块的内容逐个写入包中。这个offset table条目数一般比block数大1,这样
table[0]=0
table[1]=block 0 size
table[2]=block 1 size + table[1]
table[3]=block 2 size + table[2]
......
table[n]=block n-1 size + table[n-1]
(block从0开始计数,共n个[0,n-1])
 读取的时候,根据block id,先在table中查到table[id]和table[id+1], 两者之差就是block size.table[id]是block地址。
当然也需要一个配套的文本文件记录每个block id对应的内容。
这种方式的好处是可以只读出需要的内容。且table所占的容量只比第一种方式稍大。是非常实用的方式。

3 trunk 方式
首先定义trunk:block id + block size + block data
只比第一种方式多了一个block id。但灵活性提高了。因为可以根据id判断当前的block是否是需要载入的。如果是就载入否则跳过这个block接着看下一个block,直到找到或没找到需要载入的block。block id不但可以指明数据块在同类数据中的id,而且可以指明是哪一种资源,这样就可以把不同种类的资源打包到一起。当然在前面的方式中可以在数据块中包含资源类型,但灵活性就差了,特别是必须在所有类型的数据块中统一写一些数据在相同位置来表示资源类型。而在trunk方式中,只要在block id中取一些位来定义资源类型,然后根据资源类型调用不同类型的载入函数去读取数据是相当灵活的。trunk方式的缺点是读取速度稍慢,因为必须一个个找过去。

4 file name 索引方式
不知道除了我有没有人用过这种方式,这是一种偷懒的方式。打包对象是文件。先在包头部写入一个文件名和offset 映射表。文件名按字符串写入包中,所以这之前要写入文件名的字节数。
映射表的结构为: 文件名字节数+文件名字符串+文件offset
当然文件名必须用ascii编码。这儿还有个变通的方式。你可以用utf-8格式的编码,就不需要写文件名自己数了。
映射表之后就按顺序写入文件。
这种方式其实是offset table 方式的一种变体。不同的是直接将文件名写入包中。读取时可以指定文件名从包中读出,根从持久性设备上读单个文件的感觉一样。不必再定义额外的文件文件表明每个数据块的含义了。所以是一种比较懒的方式。缺点是浪费容量。

小结:
以上4种方式各有用处,用的最多的是offset table和trunk方式。此文需要持续补充更正完善

阅读更多

扫码向博主提问

勤奋happyfire

博客专家

非学,无以致疑;非问,无以广识
  • 擅长领域:
  • unity
  • cocos
  • TCP/IP
  • 3D
去开通我的Chat快问

没有更多推荐了,返回首页