游戏中包含大量的图像数据,如何表示它们是一个很重要的问题。 我对这个问题没有太多研究,只发表一点个人意见。因为游戏种类的不同,图像的表示方法也会有很大的差异。通用的方法是存在的,但并不是最有效的。有个性的程序员通常都会根据自己程序的特殊需要而在通用的方法上加以改进。所以我所说的只是几点基本的东西。真想做游戏的朋友自己还是要根据情况研究研究适当的表示方法。
1、通用图像格式
美工制作的原始图像通常以BMP或PCX的格式。因为别的格式如GIF或JPG,虽然压缩比很高,但使用并不简便。程序员通常要对这些原始的图像进行一定的处理,所以图像格式越简单越好。早期的游戏(DOS时代)通常都用PCX格式,因为有很多好的工具 软件可用。Windows时代由于Microsoft力推BMP为标准格式,所以BMP渐渐用得多起来。游戏中包含很多画面,比如一个人的行走包含几帧、几十帧甚至几百帧画面(取决与游戏的风格和细腻程度,当然,还有美工的辛苦程度)。早期的做法是把相关的很多画面(通常是等宽等高的)按顺序存放在一个BMP图像中。例如,每个画面大小是16x16,10个画面按顺序横向(纵向也可以)存放,则BMP图像的大小为160x16。每个画面只是BMP图像的一个矩形部分。运行的时候很容易计算。例如要显示第2幅画面,只需显示BMP图像(16,0)-(31,15)的矩形部分就可以了。
2、简单的IMG格式
原来的游戏大多是256色的,(16色的原理类似,只不过对美工要求更高一些)。由于游戏通常只使用固定的几个调色板,所以每个BMP图像文件都包含调色板信息就有点浪费空间了。用过Borland BGI图形处理的人都知道,BGI中有一种IMG格式,只保存图像的宽度、高度和图像像素内容(一个二维数组)。这种格式象BMP一样简单,又去掉了大量重复的调色板信息。调色板可以单独保存为PAL格式,一个简单的结构数组(array[0..255] of record R, G, B: Byte; end;)。《剑侠情缘》就用得这种结构。所以我没有玩游戏,却把很多图像浏览了一遍。
3、支持RLE压缩和透明特性的自定义格式
上面提到得格式太简单,效率太低了。游戏中常用的图像通常充满了大量的空白或连续相同的像素,采用RLE,Run-Length Encoding(行程长度编码),可以节省大量的空间而又不牺牲效率,应为RLE的解码非常简单快速。我们在游戏中看到的人物各式各样,但其实都是以矩形图像的形式保存。有的朋友老问我透明是怎么回事儿,其实大家应该都明白。我们在白纸上画个小人,显示的时候,先画背景,例如绿色的草地,再画小人。画小人的时候,只要发现图像的点是白色的就跳过不画。最后的结 果就是一个小人站在草地上。显然,游戏中的图像充满大量的白色的点。由于背景不见得都是白色的,所以我习惯称之为透明的点。举个简单的例子吧:(RGB分别表示红色、绿色、蓝色,_表示透明色)图像中有一行数据:___RRR_RBGB我们可以表示为:3个透明色,3个红色,1个透明色,4个不同色。 我们规定表示像素数据的两种格式: 1、相同色彩长度,色彩值; 2、不同色彩长度,色彩序列。 那么刚才的数据就表示为: 3 _ 3 R 1 _ 4 RBGB 可是我们无法区分开头的长度是表示相同色彩还是不同色彩,于是我们 进一步规定,小于100表示相同色彩,否则表示不同色彩。重新表示刚才的 图像数据就是: 3 _ 3 R 1 _ 104 RBGB 由于透明色彩非常特殊而且出现率非常高,我们可以进一步对它特别 处理,假定:1..99表示透明,101..199表示相同色彩,201..299表示不同 色彩,重新表示刚才的数据就是: 3 103 R 1 204 RBGB 透明色“_”不再需要了,我们不再关心它到底是什么色彩,反正它是 透明的,看不见的。 总结一下,我们有三种格式表示图像数据: 1、透明色彩长度 2、相同色彩长度,色彩值 3、不同色彩长度,色彩序列
特别声明:我只是举个简单的例子,实际编码原理类似,但不同相同。
4、Diablo的图像表示方法
应云风的要求,我把Diablo的压缩方法告诉大家。大家了解后应该能 自己编写出编码和解码程序,我就不罗嗦了。 格式 范围 实际数值 1、透明色彩长度:n(01-7F) n 2、相同色彩长度:n(81-BE) BF-n 3、不同色彩长度:n(C0-FF) 100-n
知道我是怎么知道的吗? 运行Diablo,用FPE看它的内存。我睁大了眼睛,看啊看啊,突然就看明白了。 你也试试?
结束语: 我在自己的演示程序中因为是使用16位色彩方式,所以对上述方法做了些修改,使用起来还是很不错的。大家可以随便设计自己的图像表示方法。程序设计没有框框限制。不要拘泥于上述想法。不要跟我讨论上述方法的好坏,本来就是个提示而已,实用适用的方法自个儿搞就是了。
| |