本章只介绍图像资源管理.
定义文件名:IMGLIB.DAT
在调试版本中我们使用的脚本语言,只有在发行版本中才将其加密和压缩.
文本举例:
PATH ".\IMGLIB\" //放置图片的路径,在调试版本中,图片是不打包的,发行版本中
//才打包和压缩在一个文件中
#def id=0,name="1",file //对象类型,有文件型,图素拼贴型,复合型等,可以扩充自己的类型
#begin
include file "man.bmp" //包含"man.bmp"的图片
include file "manalpha.bmp" //alpha通道图片
makpicpage directXpage //生成的表面类型,缺省是DirectXDraw表面,参见"第四章"
memctroll TRUE //内存自动管理
litImgs 16 //总共有16张小图
litimg place (0,0,30,30)
(30,0,60,30)
... //子图在图片中的位置,可以自动生成
//litimg place auto
defgo 0,0,0,0,0,3,5... //行走性质定义,我们使用的8*8为一单元
touch litimg=0,(10,0,0,1,1,30,30..) //可以定义子图复杂的触发区,这在
//冒险游戏和多媒体中有时需要
middle all in top( or all in bottom or seldef 0,0,..)
//每张子图片的中心定位点,这在人物行走时特别重要
//定位有几种方法:顶点,坐标,....
#end
大家可以看出,这是一个很复杂的定义格式.他不像许多游戏直接使用图片作为资源,而是包含了一些控制描述的复合定义,当然最简单的形式也就是一个文件名,其余可以使用缺省控制.
首先说说素材的类型,我们经常看到地图编辑器的介绍,提来提出无非是什么拼贴视角等等词语,在我们的引擎中,许多界限都被打破,比如地图的构成,象<<仙剑奇侠>>许多游戏使用的是一种我们称为"图素拼贴"的技术构成,它的原理是采用8*8(或其他尺寸的单元)距阵纪录每个单元对用的材质的序列号,而不是使用实际的点阵数据,这样可以节约大量的内存,另外一种方法是直接使用整张绘制的图像,比如直接由3D设计的一个场景,这在象<<命运之手>>等游戏中使用过.而在我们的引擎中,这些游戏类型的定义都打破了,我们统一使用的是大的图片,但这张图片可以是只包含索引的拼贴纪录,甚至可以是其他已定义资源的合成资源.
随着硬件内存的增加,使用整张图片作为连续滚屏(而不是切换)的背景成为可能,但如果不注意压缩,16M色的内存需求仍然让人恐怖,虽然效果是上去了,所以我们一方面提出了一些场景组成方案,图像压缩使用方案,在某些局部兼容原来的"图素拼贴"的技术有时也是必要的.
这个资源使用的方法很简单:
IMGLIB::Blt(int imgid,int sonImgNo,CPICPAGE *decPage,RECT *decPlace,...);
省略的是其他扩展写法,比如亮度控制,alpha控制等等.不管资源是什么类型,接口一致,保证了系统的扩充性,这就是对象继承的优势,在整个系统构架中,我们都注意了这些,比如前面提到的"三:图像页CPICPAGE介绍".
子图:每一张图片可以包含许多小图片,比如一个人的一套动作包含一张图片中,这样容易管理,子图数要定义其在图像中的Rect,我们使用一种色为子图边框色,这样可以自动得到位置,而不是每个手工测量,也没有子图必须使用统一尺寸的要求.当然怎么做不重要,只要你得到了结果,生成尺寸也是配套的开发工具必须解决的事情.
每一张图片可以带对应的一张图片作为alpha通道图片,这是生成一些特技效果的需求,我们会在另外一张专门介绍当前比较常用的一些特技效果技术比如光影烟雾等和实现办法以及他对提高游戏效果的意义.
行走性质的定义:定义每张图片的一些性质,比如地面,悬崖,障碍等,对如人物,还有头,手,心等详细定义,这样可以制作一些格斗游戏.
触发区:普通的图片触发区要么是包含它的方框,要么是实体区,对于一些多媒体,要求在一张图片中包含多个非规则的触发区,比如一个人的图片,击打不同的躯体位置显示不同的动画,
这便用到此定义,使用:
int IMGLIB::GetTouch(int imgId,int sonImgNo,POINT *pt);
得到此点在触发区的序号.
生成表面类型:定义此资源生成的CPICPAGE的类型,这是为了尽量减少内存的需要.见第三章.
中心定位点:一般地图背景使用的做左上角为定位点,而人物通常使用的是图片的下部中间为定位点,我们在脚本语言中规定了几种标准定位方式,但对于一些非规则体,比如中心位置不标准的人物图片,允许使用坐标标定.
图像资源管理使用的是一个CIMGLIB的对象,对象包含了一个资源的列表单.
通过前几章,我们基本上可以显示一个地图和人物动画了,再加上控制,一个简单的游戏就可以演示了.
下面简单的描述一下过程:
hWnd=InitWindow(640,480)
DirectXWin.OnCreat(640,480,TRUE);
ImgLib.Load("IMGLIB.DAT");
while(1)//按dos写法
{
delay(100);
time++;
//刷新游戏显示
{
CPIGPAGE *lpPage=DirectXWin.GetBakPage();//得到背景图像页
Imglib.Blt(0,1,lpPage,0,10);//将序号为0,子图号为1的背景图片显示在0,10上
Imglib.Blt(2,time%10,lpPage,100,100);//将序号为2,子图号不断改变的人物图片显示在背景上
}
DirectXWin.OutToScr();//输出到屏幕
}
一个游戏引擎包含了太多的内容,不知这篇文章什么时候能写完?!
由于这套引擎本身功能比较全,要介绍的特别具体我们时间不允许,里面许多地方由于时间关系语言逻辑没有条理,甚至不通,大家原谅.作为一商业引擎,他不像大家常见的书本上的大道理,他是建立在实际
基础上的,我们希望大家仔细想一下其中的原理,比如对象接口为什么那样设计,有疑问的地方提
出来,大家探讨.