欢迎光临散文网 会员登陆 & 注册

梦开始的地方——FC游戏开发指南(8)背景与卷轴

2021-11-01 15:36 作者:皮皮关做游戏  | 我要投稿

(本系列是一个回归电子游戏原点的特别系列,作者 @goodorc_gamedev

上期链接:https://www.bilibili.com/read/cv13763901

从最早的FC作品之一:超级玛丽兄弟开始,FC就以它强大的背景卷轴机能给玩家留下了深刻印象。

背景卷轴技术最大的难点在于——当背景向左移动一个像素时,背景需要被完整刷新一次,每个像素都要重新绘制一遍。如果用CPU来做这件事简直是不可想象的,所以80年代的电脑系统大都不支持流畅的全屏卷轴,相比FC的流畅效果,其它电脑系统都有所妥协。

所以,学到这里的同学也都能猜到——一定又是PPU的功能对不对?

没错。本节将从绘制大背景开始,介绍“背景卷轴”这个重点功能的实现方法。

1、绘制背景

我做的打飞机游戏,背景是在海面上飞行,比较简单,所以我对背景研究也不是很深。

制作背景的原理两句话就能说清楚——还是用之前做好的chr文件,从已有的Tile中任意选择,将它们拼在一张大图上,就是背景了。

如上图,我添加了4个tile小格,将它们重复平铺就可以形成一整张海面背景。

制作背景图,只需要在FC游戏大师中新建一个“背景工程(nmr)”即可。

  1. 新建时提示没有调色板、没有chr,都没关系。

  2. 新建的背景图一开始是空的,首先导入字模(字模就是CHR)。

  3. 配色不需要导入,点击主菜单的配色 > #00,手动选择与之前的调色板同样的颜色就可以了。 (由于文件格式不兼容,导入原来的配色更费劲,不如手动选择了。)

  4. 在右侧选中tile,在左侧用鼠标刷出来即可。注意:此工具窗口有点小,菜单中有x2放大功能。

  5. FC地图编辑器,支持一次选中4个tile。只要选中“连续方块”选项即可。

基本方法就是这么简单。

保存以后得到一个nmr文件,一个nam文件,直接用nam即可。

2、显示背景

和之前一样,导入二进制文件到rom中,需要修改crt0.s文件。详细步骤:

1、我保存的背景文件是test.nam文件,在文件夹中确认它存在。

2、修改crt0.s文件,在文件前面导出 _test_nam的符号给C语言使用。




3、在irq那几行指令后面,加入test.nam的二进制内容。




说明:上面第2步导出了一个符号给C语言,第3步是将整个nam文件的内容复制到了最终游戏rom中去。

4、修改C语言代码。首先在文件前面加一句外部符号test_nam声明,这里不能写开头的下划线:




在游戏初始化画面时略加修改:




解释:load_BG_palette意思时加载背景调色板,这里复用了精灵的颜色。

load_full_name_0就是加载0号名字表,包含符号表和属性表。

FC提供了两个名字表0号和1号,这样方便我们做出背景连续滚动的效果。如图:

实际上还有另外两个,一共4个名字表,不过单向卷轴2个表就够了。

简单编写之后,我们的“移动”游戏也有背景了:

3、在汇编中添加卷轴变量,并在C语言中赋值

经过尝试,卷轴功能写在C语言代码中总有一些时序问题,很难完美。

所以这里直接介绍在汇编中操作卷轴的方法,还是和上次讲过的NMI中断有关。

首先加入两个汇编变量,修改nes.inc文件,在tickcount变量之后加两个变量:




其中,vpos指的是纵向卷轴的位置,取值范围0~239(因为FC一屏正好240行),而escroll是卷轴功能开关,只要escroll==0,就停止卷轴。

这样定义的变量,在汇编中是可以用的。但是怎样在C语言中用它呢?注意到,其实汇编中定义的变量,是已经指定了地址的,vpos内存地址是0x6d,escroll内存地址是0x6e。所以C语言中用指针引用它们:




使用时,只要写 *pescroll = 1;   就给该变量赋值为1了。怕之后忘,现在就在初始化阶段加上:




4、加入卷轴代码

端口0x2005控制卷轴功能。

修改crt0.s的NMI中断代码,在原有代码中插入了16行,同时删除tickcount+1的那行,完整摘录如下:




其实功能很简单,就是对vpos变量进行加1操作,到了240就回到1。每帧将vpos值写入0x2005端口,0x2005就是控制卷轴的端口。

虽然功能简单,但汇编写起来就是这么长。

注:原来的汇编代码我没有完全看懂,但后面的代码一定要删除或注释,才能启用卷轴功能。

在初始化阶段别忘了加入 *pescroll = 1;

再次运行,应该可以看到背景动起来了:

背景运动后,露出了第二个背景。第二个背景我们没有设置,所以是黑色。

1、修改mylib.c文件。之前只有load_full_name0和load_full_name1,没有写2号、3号名字表。给它补上:




2、在初始化阶段,需要加载0号和2号名字表:




如果顺利的话,到这里背景就可以动起来了。

背景卷动涉及的问题确实很多,通过这篇文章应该也能学到一些C语言指针技巧。下一期将是本系列的最终章。希望对FC有兴趣的同学继续捧场。

(本文作者 @goodorc_gamedev。欢迎加入游戏开发群欢乐搅基:1082025059

对游戏开发感兴趣的童鞋可戳这里进一步了解:levelpp.com/

梦开始的地方——FC游戏开发指南(8)背景与卷轴的评论 (共 条)

分享到微博请遵守国家法律