双向链表:Tile Based Engine的设计 - 精灵链表

  通常说来, 第 3人称 2D 游戏中通常把景物和精灵分开处理 (至少我是这样) 尤其是游戏机上, 硬件对精灵有支持. 现在我们显卡多也支持显存间 keycolor 检查 Blt 操作, 实际就是用来加快精灵处理 (也包括景物)

   精灵在运动时, 往往是基于像素 (虽然有人喜欢简化设计, 精灵在停止时候仍旧是站在格子里) 而景物却是静止在格子中. 如果能使用更有针对性思路方法分别绘制, 将可以提高游戏速度. 本文观点源于云风早前所写斜视角图形引擎设计系列. 并在近期实战(制作商业A.RPG游戏)中得到完善.

   实际上, 游戏中每帧图象, 没有必要每次用各个图素合成, 尤其在使用了大量如Alpha轮廓, 透明等大运算操作情况下, 屏幕上并未更改区域重复被运算非常浪费时间. 所以我们可以借鉴游戏机做法, 场景图面创建稍稍比屏幕大圈, 只在屏幕移出窗口时再补绘场景, 把精灵提出, 每帧重绘于场景上.

   合成精灵和场景有 3大问题, 是如何处理精灵遮挡问题, Isometric Tile Engine 遮挡处理文阐述了云风观点; 其 2是如何清除上精灵: (当然这步也可以省略, 改为将场景层和精灵层合成到第 3缓冲区) 如果不想多建立屏幕后台缓冲区, 减少合成图层时数据移动量, 我们可以采取在绘制精灵前保存精灵原处场景图象. 具体实施方案在后面将有详细解说

   最后大要点是以正确次序绘制精灵了. 这里我想使用个链表, 串起场景中所有精灵, 姑且将它称为精灵链表吧. 同时我们还需要另个链表保存屏幕上可见精灵, 减少我们处理精灵数量.

   场景精灵链表是创建场景时创建, 在某精灵消失(死亡)后从链表中删除, 精灵也可以在游戏时被创建加入链表. 而屏幕精灵链表却是绘制屏幕时动态生成, 保证其中精灵满足从后到前顺序. 这样我们只需要在产生链表后, 依链表次序将精灵绘制到屏幕就可以了 :-)

那么整个处理过程如下:

   根据当前屏幕精灵链表清除上帧图象中所有精灵
   清除当前屏幕精灵链表
   遍历整个场景精灵链表, 处理每个精灵动作和状态, 如果精灵正在屏幕上, 就将其按前后次序插入屏幕精灵链表.
   将即将绘制精灵位置场景保存
   按屏幕精灵链表次序绘制精灵到屏幕
   显示帧图象
   循环这些步骤

   第步清除上帧精灵具体操作中, 我们可以为每个精灵分配个缓存Cache图, 保存绘制前场景. 但这样比较浪费. 不在屏幕上精灵根本用不着这个缓存Cache图. 所以我们可以进步优化为, 精灵进入屏幕时才分配缓存Cache图, 移出屏幕就释放掉. 不过内存分配实际是个很消耗时间过程. 当精灵大小都类似时,进优化方案是限定屏幕上可以同时出现精灵数量, 化时就统分配批等大缓存Cache图(我称其为缓存Cache池), 其每个都足已容纳最大精灵. 当某个屏幕精灵需要缓存Cache图时, 就从缓存Cache池中找个没有使用供其使用, 精灵移出屏幕后, 放弃对缓存Cache图控制即可.

   有关第3步将存在于屏幕精灵插入屏幕精灵链表操作, 涉及如何判定精灵前后关系. 我们可以在作图时, 就将精灵重心定为其参考点保存中图素文件中. 利用这个参考点坐标就可以完成精灵前后判定了 ;-)

   本文整理总结了云风近期制作游戏中些经验, 希望对后来者有所借鉴. 成文仓促, 在所难免. 提及思路方法也是我个人观点, 游戏设计魅力在于其设计时可以不遵循常例,任意发挥, 在此欢迎大家起探讨, 指出和不足.
Tags:  c语言链表 循环链表 链表排序 双向链表

延伸阅读

最新评论

发表评论