QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 3921|回复: 1
打印 上一主题 下一主题

[转帖]游戏中的资源打包技术

[复制链接]
字体大小: 正常 放大
xShandow        

43

主题

1

听众

385

积分

升级  28.33%

该用户从未签到

国际赛参赛者

新人进步奖

跳转到指定楼层
1#
发表于 2004-12-7 14:01 |只看该作者 |倒序浏览
|招呼Ta 关注Ta
<TABLE>
$ z0 H4 ]# V; b( _
+ V3 L# D) n7 G/ O+ I<TR>" ~1 ]. a$ X% [  V- p1 T
<TD width="100%">
: [9 j  t' K& K- c6 t- b8 J+ K< align=center><FONT color=#ffffee><B>游戏中的资源打包技术</B></FONT></P></TD></TR>8 U' L. L5 s0 d
<TR>2 c6 p0 ?1 v: E7 u
<TD width="100%"> </TD></TR>2 x) m& y! X* T; \. |9 A: R4 A% {
<TR>0 O0 H  i6 K/ T2 C
<TD width="100%"><FONT size=2>  打包,很形象的,就是把零散的东西转换为单一的东西。常用的压缩软件就可以说是给文件打包。那么,在游戏中为什么要打包?有什么意义么?个人认为,有以下几个意义:, D6 \( L' _  L2 f# i. A* W; g
 </FONT> + P! p+ V, S( v* w7 X3 e: R7 A
< ><B><FONT size=2>1.安全性。</FONT></B></P>% r. F9 J4 E% Z$ M
< ><FONT size=2>如果你的游戏重要数据以文本文件的形式保存在某些文件中,然而你又不希望玩家随意修改这些数据。(比如某些ini文件之类的)把他们和其他2进制文件全部打包在一起的话,这个问题就可以避免了。
5 H0 z+ d; Q- V: N$ O  | </FONT></P># l3 S$ V& a' Y% G2 t. v0 T  a, T
< ><B><FONT size=2>2.节约磁盘空间。</FONT></B></P>
+ {6 B0 k1 U( ^9 A; P< ><FONT size=2>文件太多的话,很容易产生“碎片”。比如一个1个字节的文件,占用空间就高达8Kb。(这个是由windows文件管理系统决定的),如果是很多这样的文件,就可能会发生这种情况:xxxxx个文件,实际大小1xxMb,占用空间3xxMB,(这里只是打一个比方,实际相差不会那么多)。这也许会让人感觉不舒服。# G5 ^) [3 h. W" W2 |) U
 </FONT></P>
* F1 Z6 b; C1 A! v; E0 d< ><B><FONT size=2>3.美观</FONT></B></P>- f& H( V( P0 k6 X& R9 L* {
< ><FONT size=2>简单的少量文件总比一大堆乱七八糟的东西更让人觉得舒服。4 l& y' U' C+ C# f( ]
 </FONT></P>
# G6 U, e$ z3 s/ k8 |* W+ Y# ^< ><FONT size=2>4.还没想到......</FONT></P>) E2 r0 y& R$ ~6 j7 V0 s6 |' C
< ><FONT size=2> </FONT></P>: |5 U- a+ x) v( A2 Q
< ><FONT color=#3399ff size=2>下面说说我的设计思路。</FONT></P>3 y8 L2 c- T0 n1 B
< ><FONT size=2>打包后的文件该是怎样一种结构呢?</FONT></P>- D* k+ A0 a- E$ D8 b5 r$ `; k
< ><FONT size=2>我想到的有以下几种结构:
0 D' y- l4 l) P, H1 `9 n0 D& F- u4 S </FONT></P>$ ?1 m2 R1 X8 {( G9 I0 A0 N
< ><FONT size=2>1.</FONT></P>, F8 W: [! S) s3 a6 f! N
< ><FONT size=2>{</FONT></P>
; M. q: a( k, y1 U; r: A# O% T< ><FONT size=2>    文件标示信息   //判断是否是正确的打包文件</FONT></P>' c' C: N8 N3 X6 H2 ?
< ><FONT size=2>    文件的个数,文件索引表大小</FONT></P>! |- |% ?1 s. R
< ><FONT size=2>    各个文件的一个索引表.里面包含每个文件的偏移,大小.类似这种结构:文件名 偏移 大小.</FONT></P>
2 K, J( J1 @9 L/ i8 Y< ><FONT size=2>    各个文件内容</FONT></P>
" |8 Q. e" u7 P1 m3 g< ><FONT size=2>}
4 p$ a; U8 U/ j8 n </FONT></P>" a/ k; K3 e* {2 R! |# G) g
< ><FONT size=2>2.</FONT></P>
4 p% Q/ \4 {: r# b< ><FONT size=2>{</FONT></P>: |3 P  K, ]2 I- c  _3 ]3 R  Q
< ><FONT size=2>    文件标示信息</FONT></P>$ {! J) ^0 `8 ?& `. Z& {' }
< ><FONT size=2>    第一个文件信息: 文件名长度,文件名,文件长度</FONT></P>
6 F# b0 k. h2 J' |+ `+ n; K$ Q. c5 B< ><FONT size=2>    第二个文件信息: 文件名长度,文件名,文件长度</FONT></P>
5 h4 G; H( {7 o- U& y< ><FONT size=2>    ......</FONT></P>
' |) M% O/ F; C  @- l& I0 z: R< ><FONT size=2>    第n个文件信息: 文件名长度,文件名,文件长度</FONT></P>' m" W7 k9 C! X) b5 ^4 K. s
< ><FONT size=2>    (文件计数)</FONT></P>6 f. u: s7 S! y( a0 Q% V
< ><FONT size=2>}' K, g' E' h: B0 X- k5 ]
 </FONT></P>
' C" C2 r3 v* S, `% b+ ^7 o< ><FONT size=2>3.</FONT></P>
6 {9 A3 s6 P% J< ><FONT size=2>{</FONT></P>
2 w. b0 [4 ?% f  W2 y<P ><FONT size=2>    打包成两个文件,一个负责方式1的索引表.另外一个只负责文件内容</FONT></P>
& q$ ^0 Q3 _( R  y0 m, p<P ><FONT size=2>}</FONT></P>
! k% [+ m. x/ F! i) O; [<P ><FONT size=2>这里第1种和第三种方式必须要得到索引表信息后才能填充文件,不如方式2直截了当.所以我在程序设计的时候采用的是方式2.当然方式1,3也有他们的好处,比如查找文件比2要方便一点.</FONT></P>0 t# C3 A9 ^% e) i# w" u: k1 z
<P ><FONT size=2> </FONT></P>
2 U# g0 i: U, `* H$ z<P ><B><FONT color=#3399ff size=2>需要压缩么?</FONT></B></P>
# U$ K/ }/ B! J0 {<P ><FONT size=2>  解压缩是要花费时间的.你可以从速度和容量方面做一个折中.我在设计的时候,没有考虑压缩.</FONT></P>
  d8 f% h& x, d6 E( ]4 a<P ><FONT size=2> </FONT></P># N/ D* ^. L5 o* S4 d  `( c
<P ><B><FONT color=#3399ff size=2>怎样在游戏中从已经打包了的文件读取需要的文件?</FONT></B></P>: \! e) T/ W. ~
<P ><FONT size=2>  最简单的方法,得到需要的文件信息,从打包文件中读取出来,放到一个临时文件中.读取这个临时文件即可,</FONT></P>
% h0 X5 u  T4 C7 u6 `: v$ j# C$ n<P ><FONT size=2>游戏结束之前,从程序中删除这个临时文件即可.这里就带来了一个问题:性能.每次都要进行I/O操作.如果每个文件都不是非常大的文件的话,这个办法还是可以的.或则你需要高性能的东西,那就只有一个办法:把你的程序中所有对文件操作都改到对内存进行操作.这样只要把需要的文件从打包文件中读取到内存中即可.或者还有另外的方法,直接在打包文件中读取(这个我还不知道怎么实现,盼望高手赐教之)
5 Q7 H/ `% ]" h) A) b& i$ N </FONT></P>
, Z/ i) Y6 Z8 ~# Q! Y/ d- `1 I<P ><FONT size=2>  在制作游戏过程中,当然不用打包,只是在正式版发布后,把所有已经做好了的资源(比如图片,一些数据文件,脚本文件等)打包再一起就可以了.类似如下结构1 l! I$ F2 [$ w( [
 </FONT></P>
) m+ W3 l+ j! [+ P<P ><FONT size=2>  //假设这个是一个打包类的一个成员函数,</FONT></P></FONT><FONT face=宋体>/ S! v8 k. b! A# n! r  Q
<P ><FONT size=2>    BOOL CPackFile::GetPackFileFromPacker(char*szFindFile,char*szTempFile)</FONT></P>) N, y9 m& k% T3 ]
<P ><FONT size=2>    {</FONT></P>: d$ ~; }6 ?. Q5 R
<P ><FONT size=2>    #ifndef PACKER</FONT></P>: q' p* \0 s5 T, O1 g* x
<P ><FONT size=2>        strcpy(y,x);</FONT></P>
! V$ t/ E8 W& d1 }$ U" T<P ><FONT size=2>        return true;</FONT></P>. A& j* O/ ~8 }( j  Y) p
<P ><FONT size=2>    #else</FONT></P>! q2 y, s8 D  r! s) G1 d1 S" o
<P ><FONT size=2>        在打包文件中查找szFindFile,如果找到,创建文件名为szTempFile的文件,返回true</FONT></P>2 O5 c) y6 X& z2 ~0 D; J5 k
<P ><FONT size=2>        否则,返回false</FONT></P>- c8 ~# a! m4 d, p+ T- R
<P ><FONT size=2>    #endif</FONT></P>
7 \; U) y4 S" {<P ><FONT size=2>    }
" K0 R/ j2 }0 x' u+ N5 a </FONT></P></FONT>
* Q/ ?# ]! |- s. u<P ><FONT face=Arial size=2>  程序中应该有如下片断
9 w; P$ q% B* a: I2 R  M </FONT></P><FONT face=宋体>
. _5 b6 i/ M, h) p2 i# z<P ><FONT size=2>    char szFile[256];</FONT></P>
; I  ~# o6 g; o  D<P ><FONT size=2>    CPackFile packer;</FONT></P>  W8 ?1 u5 R5 }1 f- A& ?8 {( g
<P ><FONT size=2>    packer.OpenPackFile("somefile.pak");</FONT></P>
& Y# q# D2 A# L/ o  X( x" h<P ><FONT size=2>    ................</FONT></P>- j" Q/ F6 l3 i0 E. O6 f
<P ><FONT size=2>    if(packer.GetPackFileFromPacker("resource.bmp",szFile))</FONT></P>
; Y# M9 Q- _( M<P ><FONT size=2>       do something....</FONT></P></FONT><FONT face=Arial>5 D3 |  y7 |9 U3 U9 f6 \
<P ><FONT size=2>    </FONT></P>. O; E( l6 R& y( T7 B
<P ><FONT size=2>  下面看看我的具体程序吧!</FONT></P>; g+ E/ K8 ^# L, e
<P ><FONT size=2>  <a href="http://www.gameres.com/Articles/Program/Control/packer.rar" target="_blank" >程序下载</A></FONT></P>
3 N) P# h9 Z- h/ D  I- q1 c<P ><FONT size=2>  欢迎和我交流</FONT></P>
; d7 A% I3 w) q5 G<P ><FONT size=2>  <a href="mailtE-mail:game-diy@163.com" target="_blank" >E-mail:game-diy@163.com</A></FONT></P>
0 ?$ `% e* L1 ?: _<P ><FONT size=2>  OICQ:30784290(难得糊涂)</FONT></P>% U' j  i: t6 n. o0 Y+ O7 k
<P ><FONT size=2>  </FONT><a href="http://gameplusplus.yeah.net/" target="_blank" ><FONT size=2>http://GamePlusPlus.yeah.net</FONT></A></P></FONT></TD></TR></TABLE>
zan
转播转播0 分享淘帖0 分享分享0 收藏收藏0 支持支持0 反对反对0 微信微信
ppooiiuu        

0

主题

2

听众

166

积分

升级  33%

该用户从未签到

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册地址

qq
收缩
  • 电话咨询

  • 04714969085
fastpost

关于我们| 联系我们| 诚征英才| 对外合作| 产品服务| QQ

手机版|Archiver| |繁體中文 手机客户端  

蒙公网安备 15010502000194号

Powered by Discuz! X2.5   © 2001-2013 数学建模网-数学中国 ( 蒙ICP备14002410号-3 蒙BBS备-0002号 )     论坛法律顾问:王兆丰

GMT+8, 2026-6-13 07:08 , Processed in 0.452788 second(s), 57 queries .

回顶部