数学建模社区-数学中国

标题: [转帖]游戏中的资源打包技术 [打印本页]

作者: xShandow    时间: 2004-12-7 14:01
标题: [转帖]游戏中的资源打包技术
<TABLE>
8 k& W: R: p$ Q3 S! h9 ^8 A* {
* F' r( p0 B2 Q# S8 W<TR>
* b  d" v5 k$ ~8 n& ^+ T9 b3 F. j<TD width="100%">
+ V7 ?7 o% ]/ s5 g  N9 ^; \% r< align=center><FONT color=#ffffee><B>游戏中的资源打包技术</B></FONT></P></TD></TR>
: w4 `: g1 R+ i6 ^- W$ A" M4 ~<TR>( L9 l$ @; W* t* R2 e' M
<TD width="100%"> </TD></TR>+ H+ L3 Q7 f- z+ |0 _0 S+ I
<TR>: l! ^, C6 P: O- V7 M
<TD width="100%"><FONT size=2>  打包,很形象的,就是把零散的东西转换为单一的东西。常用的压缩软件就可以说是给文件打包。那么,在游戏中为什么要打包?有什么意义么?个人认为,有以下几个意义:
9 U+ A5 n) D% b. h0 O* D </FONT> 9 ~0 @& F: m* @2 s( w" W8 E
< ><B><FONT size=2>1.安全性。</FONT></B></P>
1 O# W! `6 R6 v/ t0 n  ?+ |< ><FONT size=2>如果你的游戏重要数据以文本文件的形式保存在某些文件中,然而你又不希望玩家随意修改这些数据。(比如某些ini文件之类的)把他们和其他2进制文件全部打包在一起的话,这个问题就可以避免了。  t6 z! |7 N. Y- f
 </FONT></P>8 `# @! T4 q9 [, q2 v3 w# ^0 I
< ><B><FONT size=2>2.节约磁盘空间。</FONT></B></P>
3 _- x  M, a$ Z0 g3 E& g3 C1 [2 m< ><FONT size=2>文件太多的话,很容易产生“碎片”。比如一个1个字节的文件,占用空间就高达8Kb。(这个是由windows文件管理系统决定的),如果是很多这样的文件,就可能会发生这种情况:xxxxx个文件,实际大小1xxMb,占用空间3xxMB,(这里只是打一个比方,实际相差不会那么多)。这也许会让人感觉不舒服。
- J& @2 y) V% E. O7 v: w </FONT></P>
* {% K6 @6 E! l: `# Q8 A8 |; P3 L< ><B><FONT size=2>3.美观</FONT></B></P>
3 E  n" X5 c1 w/ L, J+ n< ><FONT size=2>简单的少量文件总比一大堆乱七八糟的东西更让人觉得舒服。
9 E; e5 }3 G3 n2 _' [3 z </FONT></P>
  U! h( N6 }) |7 _% V- L< ><FONT size=2>4.还没想到......</FONT></P>
" H, a( [2 e: [2 B) g% u1 c< ><FONT size=2> </FONT></P>$ r0 k% P( s* @# ?0 c* l: h
< ><FONT color=#3399ff size=2>下面说说我的设计思路。</FONT></P>
% k/ e, Y1 w9 D8 M8 z< ><FONT size=2>打包后的文件该是怎样一种结构呢?</FONT></P>
! f2 O! O  ?9 v< ><FONT size=2>我想到的有以下几种结构:8 k- ?' d2 H& j6 @* S7 A
 </FONT></P>
# c- p" I0 M, O7 H# v1 W! ?9 l< ><FONT size=2>1.</FONT></P>7 e" d! l2 ^- a* Z( t. V9 r  E
< ><FONT size=2>{</FONT></P>
- N2 P5 ~; q$ b< ><FONT size=2>    文件标示信息   //判断是否是正确的打包文件</FONT></P>
5 _0 Q% }, B2 i+ \8 q+ H9 f# d< ><FONT size=2>    文件的个数,文件索引表大小</FONT></P>- }& i5 O1 ~7 X3 S" `6 P
< ><FONT size=2>    各个文件的一个索引表.里面包含每个文件的偏移,大小.类似这种结构:文件名 偏移 大小.</FONT></P>
7 i4 l7 _1 C% Q, d" t# f+ K' y! d< ><FONT size=2>    各个文件内容</FONT></P>7 E7 _, S4 S! T2 q% c' [+ U) z
< ><FONT size=2>}
9 G, k3 \. B7 l5 v1 P) l) Y </FONT></P>- v. A5 c3 j/ Q- p% @" v; |
< ><FONT size=2>2.</FONT></P>, ^' b7 S( Q: [0 i' I
< ><FONT size=2>{</FONT></P>
1 K5 q8 P/ ?0 |& F3 i< ><FONT size=2>    文件标示信息</FONT></P>2 {8 `+ ?4 K- j2 d
< ><FONT size=2>    第一个文件信息: 文件名长度,文件名,文件长度</FONT></P>& x0 O: W( |0 p$ v
< ><FONT size=2>    第二个文件信息: 文件名长度,文件名,文件长度</FONT></P>; s: u. u8 C3 ^* f5 A
< ><FONT size=2>    ......</FONT></P>
' g2 k/ _, L9 {  W# X3 u< ><FONT size=2>    第n个文件信息: 文件名长度,文件名,文件长度</FONT></P>
5 V& l6 O" b; X+ e( Z. l- b< ><FONT size=2>    (文件计数)</FONT></P>& T( \, B% |5 g
< ><FONT size=2>}
$ E  ^0 _, |0 ?% |# m2 p: |3 i* M' | </FONT></P>8 {) |5 |" s! K0 D" J( X
< ><FONT size=2>3.</FONT></P>3 y1 v( I) P3 q1 K
< ><FONT size=2>{</FONT></P># |; i# ]: m8 `4 R# \, @* _
<P ><FONT size=2>    打包成两个文件,一个负责方式1的索引表.另外一个只负责文件内容</FONT></P>
, o+ l" c1 Y' k3 Z+ H+ z$ a<P ><FONT size=2>}</FONT></P>
; C! ]; Q  `1 D. @) v8 l3 ~<P ><FONT size=2>这里第1种和第三种方式必须要得到索引表信息后才能填充文件,不如方式2直截了当.所以我在程序设计的时候采用的是方式2.当然方式1,3也有他们的好处,比如查找文件比2要方便一点.</FONT></P>% A' A8 |! h. u
<P ><FONT size=2> </FONT></P>0 f6 Z7 r* b& F6 x! @5 C
<P ><B><FONT color=#3399ff size=2>需要压缩么?</FONT></B></P>
9 i# o. [' u4 ^6 u, X9 J; V<P ><FONT size=2>  解压缩是要花费时间的.你可以从速度和容量方面做一个折中.我在设计的时候,没有考虑压缩.</FONT></P>
6 W: K0 ?- W! d9 G. p3 W' ~<P ><FONT size=2> </FONT></P>
5 A. F! M8 ~# O3 D9 \<P ><B><FONT color=#3399ff size=2>怎样在游戏中从已经打包了的文件读取需要的文件?</FONT></B></P>
* `0 |+ x4 ^" ~6 D<P ><FONT size=2>  最简单的方法,得到需要的文件信息,从打包文件中读取出来,放到一个临时文件中.读取这个临时文件即可,</FONT></P>% {: k6 g4 w1 }5 B( e$ p
<P ><FONT size=2>游戏结束之前,从程序中删除这个临时文件即可.这里就带来了一个问题:性能.每次都要进行I/O操作.如果每个文件都不是非常大的文件的话,这个办法还是可以的.或则你需要高性能的东西,那就只有一个办法:把你的程序中所有对文件操作都改到对内存进行操作.这样只要把需要的文件从打包文件中读取到内存中即可.或者还有另外的方法,直接在打包文件中读取(这个我还不知道怎么实现,盼望高手赐教之)$ z/ L# H( q9 N4 B2 T
 </FONT></P>
1 P7 T8 q9 L$ M2 L* j9 v% }<P ><FONT size=2>  在制作游戏过程中,当然不用打包,只是在正式版发布后,把所有已经做好了的资源(比如图片,一些数据文件,脚本文件等)打包再一起就可以了.类似如下结构  k* }, c# T4 M" l
 </FONT></P>* ^9 {. J- Y' I! I7 K0 m& F
<P ><FONT size=2>  //假设这个是一个打包类的一个成员函数,</FONT></P></FONT><FONT face=宋体>* x) p) L* V& w( \
<P ><FONT size=2>    BOOL CPackFile::GetPackFileFromPacker(char*szFindFile,char*szTempFile)</FONT></P>
& f0 X0 H8 u* Z7 K<P ><FONT size=2>    {</FONT></P>/ A4 z+ N: S( m/ x3 u3 V, P0 z) }! }
<P ><FONT size=2>    #ifndef PACKER</FONT></P>( {1 B5 ~9 b* ~1 V" w
<P ><FONT size=2>        strcpy(y,x);</FONT></P>
; H: w1 A3 s8 V& _  M' d<P ><FONT size=2>        return true;</FONT></P>
2 @3 q8 Q% y; N% a4 s, s8 _" X# d& G<P ><FONT size=2>    #else</FONT></P>
% V: C/ @0 d8 P* X4 J# D7 p4 z; S) Y& w<P ><FONT size=2>        在打包文件中查找szFindFile,如果找到,创建文件名为szTempFile的文件,返回true</FONT></P>
& T) n9 w6 c5 ?* v<P ><FONT size=2>        否则,返回false</FONT></P>. M+ F$ u4 h. [2 z3 H
<P ><FONT size=2>    #endif</FONT></P>, u1 C  d* m" D# n. t+ |7 R2 R
<P ><FONT size=2>    }( K3 U- }) ], D6 u1 w# Q6 y
 </FONT></P></FONT>
9 I/ f: ^0 {* q; s/ f' o) X" B1 Q  e/ b<P ><FONT face=Arial size=2>  程序中应该有如下片断1 {; V. X1 T' d; H) ]
 </FONT></P><FONT face=宋体>
5 |. I2 r2 ~- t6 T: q1 W7 B<P ><FONT size=2>    char szFile[256];</FONT></P>
7 s8 E: f: Y0 A6 p0 R<P ><FONT size=2>    CPackFile packer;</FONT></P># q; u- ^( ]+ D0 D' g  E* U' u& f
<P ><FONT size=2>    packer.OpenPackFile("somefile.pak");</FONT></P>
" j2 s8 A( N$ I! S+ @<P ><FONT size=2>    ................</FONT></P>
# l8 Q* b  O3 A% s% E$ `5 {<P ><FONT size=2>    if(packer.GetPackFileFromPacker("resource.bmp",szFile))</FONT></P>
& w, M# z, E! W, ^<P ><FONT size=2>       do something....</FONT></P></FONT><FONT face=Arial>
6 }/ y& z. N) p3 s9 S<P ><FONT size=2>    </FONT></P>
9 k$ k! i* B" h, W" o<P ><FONT size=2>  下面看看我的具体程序吧!</FONT></P>5 G+ j- N" ^! {
<P ><FONT size=2>  <a href="http://www.gameres.com/Articles/Program/Control/packer.rar" target="_blank" >程序下载</A></FONT></P>
+ K$ |, r& M' G2 w. b0 y<P ><FONT size=2>  欢迎和我交流</FONT></P>& d8 R( e+ _. U( a4 z& O8 i( S
<P ><FONT size=2>  <a href="mailtE-mail:game-diy@163.com" target="_blank" >E-mail:game-diy@163.com</A></FONT></P>
6 U) R; ?1 r' g. ]4 k/ _; I<P ><FONT size=2>  OICQ:30784290(难得糊涂)</FONT></P>
1 T* I5 }/ @- m3 h- ~: s0 @<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>
作者: ppooiiuu    时间: 2005-2-13 12:46
kl




欢迎光临 数学建模社区-数学中国 (http://www.madio.net/) Powered by Discuz! X2.5