FC开发进阶技巧

1.如何让人物的跳跃显得自然?

说到游戏里角色的运动轨迹,一般会立刻想到的就是通过模仿物理现象的算法来实角色的运动轨迹。可惜的是,受限于FC的硬件条件,银河无法用上面的方法。
FC的处理器采用的是6502,其运算能力是非常差的。要知道,用于开发NES游戏的C语言编译环境——CC65也仅仅是达到了FC性能“能接受”的范围而已,为了提高性能和节省内存,游戏里大部分的变量都声明都为unsigned char类型,unsigned char能表示的数字范围是0~255,这个范围基本上能满足FC开发的大部分运算需求,同时也能保证性能。
其次,游戏的分辨率只有256 * 240,角色的动作精度已经达到范围极小的像素级别, 没有小数点,没有足够长的运动轨迹,没有,什么都没有……
在银河采用了各种算法来实现跳跃都不理想后,银河最终尝试了“最笨”的方法——用数组来存储角色每一帧的位移变化,然后经过无数次的测试,对数组内存储的每一帧的位移变化做修改调优。结果出乎意外,这种“体力式”的做法最终居然实现出了最令人满意的效果。银河通过这种方法做出了看起来最舒服,最自然的跳跃。在FC诸多限制之下,有时候这种显得很笨的方法竟是最有效的方法。

2.如何在游戏里放入一个体积庞大且有复杂动作的BOSS?

每当银河脑海中想到一个有足够画面表现力,玩法有趣极了的想法时,银河的老朋友“同行不能超过8个精灵块”先生总会第一时间跳出来狠狠地扇了银河一巴掌:别想了,实现不了!
是的,由于PPU性能的限制,游戏在同意扫描线上最多同时显示8个精灵块,超出的部分将不被显示。很多游戏为了在同一行里尽量塞入足够多的角色,采用了精灵块交替闪烁的方法。如果你玩过FC游戏,我想你对这个场景应该不陌生吧,著名的超级玛丽、魂斗罗等游戏,在怪物或敌人过多的时候,会出现不停闪烁的现象。如果敌人在不停地移动又稍纵即逝,这的确不失为一个可行的方法(甚至是唯一的方法),但 如果是一个长时间占据着屏幕的BOSS,那交替闪烁恐怕不是令一个玩家愉悦的做法。玩家们可不想因为眼睛被闪瞎而败在BOSS手中。
另外一个常见的方法,是用将BOSS做成背景的方法来实现。常见的体型巨大的BOSS都是用这个方法来实现的,不过局限性在于这些BOSS的要么完全不动,要么动作简单,主要是靠发射弹道和召唤小怪的方法对玩家产生威胁。
银河的想法是一个手持链球的“壮汉”,不停地甩动着手中的链球,并在你出其不意的时候将链球扔向你,铁球在飞行中有铁链连着。如果“壮汉”被玩家攻击到,那么他将疯狂地拿起他的铁球砸地面,引发不稳的天花板掉落碎石来砸中主角。让银河来看看“壮汉”的模型贴图:


模型1

模型2

首先,银河的主人公的身体加上武器,横向已经占用了3个精灵块,也就是说同行只剩下最多5个精灵块,可以看到图1中BOSS光站立着甩动链球的模型已经占据了横向5个Tile的宽度了,这也就意味着,如果BOSS是使用精灵块显示的话,光是最简单的情况下同行精灵块就已经满载了,更何况BOSS的攻击动作中包含着铁球、铁链以及可能同时落下的碎石。那么解决方法有两个,一个是在攻击时铁球和BOSS交替闪烁,明显这是个糟糕的方法,上面银河已经谈到过了,而且这种方法无法解决铁链的显示问题,如此长的铁链用精灵块无论如何都无法完美地显示在屏幕上的。那么只能选择其他方法了——用背景。BOSS频繁的动作使用重新渲染背景的方法,铁链也使用渲染背景的方法,链球经过的地方渲染或抹去铁链,这样横向就只剩下铁球需要占用精灵块了,主角占用3个Tile的精灵块,加上链球占用2个,那同一行里也就占用了5个Tile宽度的精灵块了,银河甚至还有3个没用上!问题到这里应该已经结束了不是吗?很遗憾,这里又出现了另外一个问题——FC的PPU性能不足以支持这么频繁的背景刷新,因为刷新背景的关系,整个游戏变得缓慢、丢帧,这又导致了游戏的体验变得糟糕透了!尽管银河通过分段调整游戏里各个参数的方法试图优化游戏来减弱这个现象带来的负面体验,但很遗憾效果只能说是差强人意,银河希望能有更好的游戏体验而不是这种勉强及格的体验。银河不得不抛弃第二种做法,采用第三种方法——尽可能不渲染背景,而是通过切换PPU上的CHR来实现BOSS那种高频率的动作切换。PPU可以存储两个分别占4K的图案表,银河的开发采用了MMC3特殊芯片的MAPPER,通过改变其在内存中位于$8000和$8001的寄存器映射地址的值,银河可以随时切换PPU图案表的内容。PPU的第一个图案表平均分为上下2个BANK,第二个图案表则平均分为上下4个BANK,每个BANK可以根据银河的需求在CHR ROM里自由地加载任意一个BANK,因此银河把BOSS的模型以每四分之一图案表两个动作的方式存入CHR ROM里,BOSS在屏幕上显示的图块大小固定为5 * 5个Tile,这样通过切换BANK的方法来加载BOSS在CHR ROM里不同的动作模型就可以实现BOSS频繁的动作切换了。这种方法的好处在于对于性能的损耗远远小于直接不停地刷背景。最后通过一小部分的数值调优,银河理想地完成了“在游戏里放入一个体积庞大且有复杂动作的BOSS”的任务,实现了银河的想法。如图:


图案表 1


图案表 2

还有一个问题,为什么铁球不用背景实现?是的,既然BOSS的大部分实现都是通过背景的方式了,为什么铁球不也一起用背景实现呢?其实使用背景来显示画面里的物体有个缺陷,如果是在移动的物体,那么使用背景的方式,物体的移动就没办法以最小1像素为单位移动了,因为每次都是靠渲染新图和抹去旧图的逻辑来显示移动的物体,物体在游戏内两帧的移动轨迹至少也是1个Tile为单位,这样使用背景实现的链球的移动轨迹会显得相当生硬。其次链球的移动速度较快,和BOSS动作频繁一样如果用背景实现链球也会造成背景的频繁刷新,损耗性能,造成卡顿。既然同行精灵块够用,那银河当然愉快地选择用精灵块来实现链球的位移啦。

3.怎样实现流畅的动态背景?

动态的背景能产生极大的视觉冲击力,只可惜受限于FC的技能,前期没有使用特殊芯片的FC卡带上的大部分游戏都没做出华丽的动态背景。


背景 1


背景 2

背景的柱子在不停地滚动。和实现“在游戏里放入一个体积庞大且有复杂动作的BOSS”的任务一样,银河采用了不停地切换PPU加载的图案表来实现这个目的。

图案表 1


图案表 2

怎么样?同一招灵活使用的话能够实现令人意想不到的效果不是吗?