[上篇:视角的选择和坐标变换][下篇:动态地表的实现]
将要设计的斜视角图形引擎中, 如果细分的话, 大约要处理 5 种不同的对象.
让我们从简单的开始,先处理地表.
这是最容易的,因为不需要考虑遮挡关系,永远最先画就可以了 ;-) 如果是传统的 Tile 引擎,我们不必将其分开单独列作一项, 地表也是由 Tile 组成的, 可以和物体/精灵同时绘制. 但现在这个非 Tile 引擎中 却可以采取整幅画面的方法使游戏的图象更吸引人.
想想如果用整幅画面做背景地表有多大的数据量, 在这里, 因为实现特效需要 使用 Alpha 混合(今后的战斗引擎也需要), 256 色是不够的, 至少是 64K 色, 而且 64K 高彩已经是当今游戏的标准了 ;-) 那么使用能让玩家接受的最低 分辨率 640x480. 一屏图象的内存消耗就是 768K (幸亏现在 16M RAM 已经是 最低的标准, 否则我的活就干不下去了 ;-). 记住这是个不小的数值, 游戏程序是很容易吞噬掉大量的内存, 我们在头脑里要有警惕性, 内存和速度 是相关的 (如果内存不够,就会用硬盘模拟,而且内存的消耗意味着数据量的增加, 直接和需要从外存读取的数据量相关) 大家都不希望游戏慢慢吞吞的.
游戏的整张地图自然不只一个屏幕大小, 一个 RPG 可能会用到上千个屏幕区域. 我们用几百兆的空间就只去存储些简单的地表吗? 显然不合算. (对于真彩图片, 一般的压缩算法效率并不高) 这使人马上联想起有损压缩的 JPEG 图象格式, 对于单调的图象, 一张 640x480 的 JPEG 图往往只有几K 到 十几K 左右. 正和我意 ;-) 唯一的缺陷是 JPEG 的解码太慢, (在我的机器 CyrixMediaGx/120 上解码 640x480 的 JPEG 需要 0.6 秒) 也许在现在普遍流行的 P II 机型上, 根本谈不上慢, 但目前我仍旧希望采取更快的方法, 当然具体使用什么文件格式, 在引擎设计中是可以随意更替的, 也许在将来,我会采取时间换空间的策略.
使用无损失压缩的解码速度将很快,取决定因素的是图片的大小, 图片将从 CD-ROM 上读取,所以也影响着游戏的速度. 无损压缩的压缩比, 对于一般图片来说是 50%, 当然对于单调图片可能还要小一点. 那么, 640x480 的 64k 色图片的大小大约就是 300K 了, 这显然还是大了点, 不适合实时处理, 所以我们应该将其转化为 256 色图象保存, 这样又可以将空间消耗减小一半 ;-) 而针对 64k 色 256 色图象的质量下降 几乎是肉眼体会不到的, 且 256 到 64k 的转换非常容易. 8 速 CD-ROM 的理论速度有 1200K/s 大则就算实际没有这么高吧,达到 800K/s 应该是可以的. 这样一秒之内就可以轻易的读取 5 屏图象. 这个速度是可以接受的.
RPG 中, 随着精灵的运动, 屏幕自然会滚动,反映玩家在游戏世界中运动. 滚屏是地表处理中最重要的工作. 当然不能等玩家离开一个屏幕时马上取盘 读出下一屏的地表, 疯狂的读取 CD-ROM 会把玩家逼疯的. 我们需要更好的方法.设计引擎的这个部分时,云风有两条思路: 其一,是将游戏场景切分成许多局部块.每个局部块大小在 9 到 16 屏幕左右. 每次进入一个局部场景时,一起将所有图象载入解码. 如果不是频繁的切换场景的话, 这段时间所需的 2 到 4 秒的等待是可以接受的. 而内存的消耗呢? 载入图象后,处理速度的需要,一般不压缩存放, 按一屏 384K 计 (256 色格式), 16 屏就是 6M, 留下了足够多的空间去处理其它. 当所有的地表数据都在内存时, 带给我们最到的好处就是处理方便, 可以将所有的位图合成一张大位图, 屏幕显示部分就是大位图的一个子图而已. 当然在显示时别忘了做 256 到 64K 的转换. 由于操作的简便,这个方法为以前大多数游戏所采用. 但我认为, 这不是最好的方法, 平时在玩游戏时,最讨厌的就是切换场景的等待 :-( 下面就谈谈另一种实时交换内存和外存数据的方法.
事实上, 我们将利用的是一个 CACHE, 它保存了最近正在使用的场景地表,
而当预测到需要用的地表不在内存中时, 从外存取出, 更新 CACHE.
为了减少每次更新 CACHE 的数据量, 在对场景分块时以 1/4 屏幕大小为一块
玩家在游戏中运动,实际上玩家始终在屏幕的中央,地表在动,
而内存中总是保存玩家所在地表块及于其相连的块的数据
(见左图). 开始时,玩家在 14,15,20,21 块的交接处 O ,
那么内存中就保存了与这四块相连的块的地表数据
(即紫色和绿色的部分).而当玩家从 O 向 A 点运动后,
玩家处在了第 14 号块中, 这时的屏幕区域如灰色框所示.
内存中应当有围绕块 14 的 8 个块和 14 本身的数据.
当然, 这些数据原本就在内存 CACHE 中,不必更新;
玩家继续向 B 点移动. 进入块 13 时, 则需要将和块 13 向连的
6,12,18 载入内存, 同时可以将远离块 13 的 22,27,28 块的数据释放掉.
这样每次进入新块时,最少不用更新内存,最多时需要更新 7 个地表块
(在玩家斜向,即沿游戏世界坐标轴,经过四个块的交点时) 每个地表块大概有 35K
的数据量, 就是说,最多时,更新 CACHE 会有 250K 左右的数据载入内存
(暂时不记新的物体的载入) 按当前比较低的配置, 8x CD-ROM,
将造成 0.3 秒左右的延迟, 对玩家,是可以接受的. 如果减小 CACHE 的大小到 9
个图块 (9/4 屏幕大小) 每次夺取的数据量还可以减少一半
(当数据量小到一定程度时, 时间消耗的主要矛盾将转移到,图象解码上)
只是 CACHE 失效带来的延迟的频率增加了. CACHE 具体应该设为多大,
在不同的环境下可能有不同的感受,要靠在各种环境下反复比较效果决定,
9 到 16 块都是可以的,我个人偏好于将 CACHE 设小点,
用此法, 玩家将不会遇到切换场景的长时间等待
(许多游戏中做成淡入淡出效果, 我敢打赌,大多数人对此造成的中断很有意见)
现在我的引擎采取第二种方式,使用 PCX 格式. 如果日后机器升级,会调整为 Jpeg 格式. 或者当后面的部分设计完后,发现速度跟不上,可能会调整为第一种实现方式. 总之,玩家在玩的时候,不会因为速度的因素而抱怨不已,是我们应该做到的.