登录社区:用户名: 密码: 忘记密码 网页功能:加入收藏 设为首页 网站搜索  

文档

下载

图书

论坛

安全

源码

硬件

游戏
首页 信息 空间 VB VC Delphi Java Flash 补丁 控件 安全 黑客 电子书 笔记本 手机 MP3 杀毒 QQ群 产品库 分类信息 编程网站
  立华软件园 - 安全技术中心 - 技术文档 - 入门基础 技术文章 | 相关下载 | 电子图书 | 攻防录像 | 安全网站 | 在线论坛 | QQ群组 | 搜索   
 安全技术技术文档
  · 安全配制
  · 工具介绍
  · 黑客教学
  · 防火墙
  · 漏洞分析
  · 破解专题
  · 黑客编程
  · 入侵检测
 安全技术工具下载
  · 扫描工具
  · 攻击程序
  · 后门木马
  · 拒绝服务
  · 口令破解
  · 代理程序
  · 防火墙
  · 加密解密
  · 入侵检测
  · 攻防演示
 安全技术论坛
  · 安全配制
  · 工具介绍
  · 防火墙
  · 黑客入侵
  · 漏洞检测
  · 破解方法
 其他安全技术资源
  · 攻防演示动画
  · 电子图书
  · QQ群组讨论区
  · 其他网站资源
最新招聘信息

Tile文件的组织
发表日期:2007-01-16作者:[转贴] 出处:  

  斜视角Tile游戏中,Tile是组成地图的最基本的东西,整个地表(不包括上面的建筑)都是由Tile拼出来的。每个Tile就是个小图片,描述了这个地表(象地板、街道、草地、溪流等等)的样子。依照(我的)习惯,同类文件就组织在一起打成一个包,下面就给出一个Tile文件的结构。

  我们先来讨论一下Tile图片的颜色数,在以前我曾经说过,对256色模式我有一种怪异的癖好,而且我也讲过一些256色的好处,很多Tile肯定都可以用相同的调色板(象不同形状的草地等等),而且这些调色板也可以给那些物体用(节省空间是我们的目的),另外说实话,每个Tile根本不见得有256个有意义的像素,因此在这里,每个Tile仍然用256色就足够了。但是256色就有个调色板的问题,这个在后面具体讨论数据结构的时候再解决。

  每个Tile图片都有很大的压缩余地,毕竟同一种地表肯定有很多相邻颜色是相同的,而且菱形的四周都是透明色,肯定是要压缩的。压缩方法就采用《DIABLO中的图像压缩方法》中提及的Diablo所采用的RLE压缩方法(简单、效果也不差)。由于采用了压缩方法之后,这些Tile的大小就变得大小不等了。为了快速在文件中定位每个Tile,我们需要建立一个索引文件(可以叫xxx.inx),整个文件就是个数组,记录着每个Tile在Tile文件中的位置及一些必要信息,具体数据结构稍候讨论。这样,就可以根据Tile的ID号(实际就是Tile在整个它所处的Tile文件中的索引号)快速在Tile文件中查找到所需要的Tile。当然,也可以把这个索引放到Tile文件的里面(头上或尾部),这样看起来显得更紧凑一些。

好了,现在该说到具体的数据结构了。

typedef struct {
  int  Version;
  int  nTileWidth, nTileHeight;
  int  nTileNumber;
  int  Compress;
  char TileFileDesc[44];
} TILEFILEHEADER;


这是个64字节的Tile文件头的结构。Version是描述一下这个Tile文件的版本,以备后来的Tile引擎以及地图编辑器识别的,如果日后再定义了一些新的Tile格式,只要把这个版本号改一下,通知Tile引擎或地图编辑器就行了;nWidth,nHeight两个成员是说明每个Tile的长和宽的,因为每个Tile都是等大的(不然怎么拼起来?),所以在前面定义一次就够了;nTileNumber是记录在这个文件中总共有多少个Tile,如果索引在这个Tile文件中的话,那么这个成员就很有用了;Compress是说明Tile数据是用什么方法压缩的(模仿BITMAPINFO里的结构搞了这么个东西),以备扩展;TileFileDesc是这个Tile文件的描述,给地图编辑器用的,提供给编辑者一个对这个Tile文件的初步印象。

文件头后面就是一个Tile索引表(还是按我的习惯,把东西都放到一起,看起来整洁一点)。索引表实际就是个如下的结构数组:

typedef struct {
  int  nTilePos;
  int  nFrameNumber;
  char TileDesc[24];
} TILEINDEX;

nTilePos是最重要的成员,它记录着这个Tile在文件中的位置(相对于文件头的偏移,用SetFilePointer函数可以很容易的定位Tile);nFrameNumber是用来记录这个Tile的帧数,当这个值为1时,代表这个Tile只有一幅图片,也就是个静止的Tile,当值大于1时,这个成员就指定了这个Tile的帧数,也就是说这是个动态的Tile(比如说,随风摆动的草地、起伏的水面等等);TileDesc这个东西又是给编辑器看的,描述了这个Tile的名字,说明这是个什么样的地表形状,有了这么个成员,我们就可以在编辑Tile的时候直接读取每个Tile相关的信息,以选择所需要的Tile,而不用扫描整个文件了。

索引表的后面就是具体的Tile数据了,每个静态的Tile数据都有一个自己的8个字节的数据头。

typedef struct {
  int  nPaletteNumber;
  int  nTileSize;
} STATICTILEHEADER;


nPaletteNumber是用来记录当前这个Tile图片是使用哪个调色板,Tile图片数据的每个像素的值实际就是在这个调色板里的索引,实际的颜色值是记录在这个调色板里的;nTileSize是给出这个Tile的被压缩后的图片数据大小,也就是在文件中真正占据空间的大小,这个是为了读Tile到内存时和解压缩时的方便。每个Tile Header后面就是具体的压缩过的图片数据了。

对于动态的Tile来说,这个数据头稍稍有点变化。

typedef struct {
  int  nPaletteNumber;
  int  nTileSize;
  int  nFramePos[1];
} DYNAMICTILEHEADER;


这里的nTileSize是指所有帧的压缩图片大小的总和;nFramePos是个数组,记录着每一帧的数据相对于第一帧开头数据的偏移,对于每一帧的图片都是分别压缩的,举个例子:一个动态的Tile总共有5帧图像,每帧图像压缩后的大小分别是10、20、25、16、15,那么nFramePos[0] = 0,nFramePos[1] = 10,nFramePos[2] = 30,nFramePos[3] = 55,nFramePos[0] = 71,就是这样。这样把Tile读入内存时可以完全不用做任何改动,很方便的就可以迅速定位到任何一帧数据的开头上。

  当把这些Tile载入内存的时候(可能不是全部载入),就需要在内存中再建一个类似的索引,nTilePos这个成员就成了指向Tile数据的指针了。在内存里可是寸土寸金,TILEINDEX的TileDesc成员就没必要要了。对于建立这个索引,还有一点要说明的。因为在一幅地图中,所用到的Tile数是有限的,没必要也不应该把所有的Tile一古脑全都读到内存里去。所以有很多Tile都是用不到的,那么在这个索引中,这些没用到的Tile的指针就置成NULL,以免误操作。只把需要的Tile读入内存,把相应索引里的指针置成正确的值。
我来说两句】 【发送给朋友】 【加入收藏】 【返加顶部】 【打印本页】 【关闭窗口
中搜索 Tile文件的组织

 ■ [欢迎对本文发表评论]
用  户:  匿名发出:
您要为您所发的言论的后果负责,故请各位遵纪守法并注意语言文明。

最新招聘信息

关于我们 / 合作推广 / 给我留言 / 版权举报 / 意见建议 / 广告投放 / 友情链接  
Copyright ©2001-2006 Lihuasoft.net webmaster(at)lihuasoft.net
网站编程QQ群   京ICP备05001064号 页面生成时间:0.00256