哈喽,大家好,我是源小北。
当已有的机器无法给你更多启发的时候,那就换一台虚构的吧。
许多的电脑爱好者在它们的发烧之路上尝试过各种各样的硬件设备和软件平台。而很多时候它们会有意的搜集这些平台和设备,来尝试上面的游戏或是完成它们的艺术作品。这一探索过程也帮助这些发烧友们了解各个平台的特性,并帮助他们发掘自己喜爱或是感兴趣的电脑平台。而虚构的游戏机平台Pico-8就是其中别具趣味的一个。
对Pico-8最好的解释,就是它是一款并不真实存在的游戏机的模拟器。它的具有非常鲜明的8-bit风格,因此你可以把它像想为类似GameBoyColor这样的小掌机。它的提供一块x像素,16色的显示屏,以及四通道的音乐芯片。
不过,Pico-8却不仅仅是某种架空历史的实践,它设计的出发点与市面上已有的类似设备有着很大的不同。它并没有试图去最大化的利用有限的逻辑功能,而是提供了一批积木式的代码部件,尽可能的挖掘使用的乐趣。开发商希望随着时间的推移,Pico-8的技术框架将形成一种独特的审美观:极简主义并有着丰富的表现力。
第一印象
Pico-8乍看上去有一点“精神分裂”。启动之后它给人的感觉并不是一台游戏机,而更像是一台带有键盘鼠标的家用电脑。它使用命令解释器来加载软件和输出提示,举例来说,按下ESC按钮,你会打开一个文本编辑器,它具有自己独立的区域来存储代码、图像和声音内容。不过,只有系统内置的应用程序可以访问键盘、鼠标和完整的文件系统——对于外部加载的应用程序来说,Pico是一台使用ROM卡带和双按钮手柄的游戏机。
Pico使用Lua作为它的开发语言,这款为游戏脚本而生的语言虽然功能有限,但却具有强大的表达能力。实际上,Pico虚拟机本身并不模拟任何处理器芯片——它甚至不会执行字节码。所有的东西全都使用Lua写成,这也是程序员们能访问到的最底层的东西。
分发Pico-8平台的游戏和软件主要有两种方式,一种方式被称作“卡带”(cartridges)或者“卡”(carts),它实际上是一张PNG图片,看起来像是一张带有封面贴纸的游戏卡,“卡带”图片使用了文件的低位(lowerbits)来存储程序代码、图像和声音数据,类似某种文件指纹。而另一种方式则是将软件导出为HTML5格式并使用现代浏览器来运行,以这种方式运行的软件可以不需要Pico-8环境。
边界和限制
Pico最明显的技术特征就是x像素的屏幕分辨率以及固定的16色调色盘了,这一调色板具有相当独特而易于辨识的色彩组合,显示了其设计者对色彩的嗅觉相比一般的工程师更胜一筹。
虽然典型的Pico游戏通常使用8x8像素的方格来构成游戏地图,并使用8x8像素的动画精灵,但这却不是平台的限制之一。Pico的图形模式是纯粹的像素缓冲模式,它实际上可以绘制任何的图形——而机器的性能也足够流畅的运行90年代演示程序中的各种特效。不过,平台通过提供速度更快的绘制地图和精灵的功能函数,鼓励开发者使用8x8像素快而不是使用自己的代码逐个像素的绘制图形。
一张“游戏卡”可以存储字节(15KB)压缩后的代码,编辑器所能支持的最大长度是个字符或是个“标记”(tokens)。这一限制实际上并不容易达到,即使是许多Pico平台上最好的游戏其代码量也要明显低于这个数额。从另一个方面讲,这种限制鼓励开发者开发简单而线性的游戏逻辑,Pico上面没有空间容纳庞大的游戏引擎或多层的抽象逻辑。
“游戏卡”上还有字节(12.25KB)的空间预留给图像资源,另外字节(4.5KB)则留给声音。当然这些数据区域也可以被用作其他用途——内存操作指令可以在字节层面去操作它们。当程序开始运行之后,“游戏卡”中的数据将会被复制到RAM,然后程序就可以在需要的时候修改它们。用户可使用的RAM还包括了略低于7KB的用户保留空间,以及8KB的显存。
图形数据由8x8像素的精灵组成,它们可以包含调色板中的任意颜色。系统可以支持最多个精灵,而地图则由x2个精灵组成。如果只使用个精灵的话,地图的尺寸还可以再翻倍。
在声音方面,与“精灵”对应的是“声效”(soundeffect-sfx),每个声效由2个音符位置(notelocations)组成,每个音符位置都包含了音符和它的波形、音量和特效,每一个选项都有8种不同的设置可选,播放的速度也可以修改,较慢的播放速度更适合演奏音乐而不是音效。
与Tracker(序列器)音乐类似,一首歌曲由四个通道上定义了不同效果的“图案”(patterns)构成,Pico-8支持最多64个图案,通过使用循环和图案结束标记可以在一个文件中容纳多首歌曲。
虽然Pico-8的图形功能可以让开发者操作单个像素,但用户却无法直接访问声音系统的“寄存器”。理论上讲你可以通过实时修改声音数据来实现播放器功能,但虚拟机的时序限制很可能让这种功能无法被实现出来。不过,通过向音效内存里写入随机数据的方式,还是可以轻松的创造出若干试验性的声效的。
除了程序代码,数据RAM和卡带ROM之外,Pico还为Lua解释器提供了KB内存空间。相比Pico的其他内存空间来说这一空间要大上不少,但它却比较容易被用完,比如说在操作大型表(Table-Lua中的一种数据结构)的时候。数字表的每个元素最多可以存储8字节,但实际的数据只能使用其中的一半。每个数字包含16bit整数和16bit小数部分,这些意味着通过位算数运算可以对它们进行比较。
当内存空间不足时,Pico也可以从其他ROM卡带中读取数据,甚至可以向卡带中写入数据。但程序代码有着严格的限制,只可以从它们原始的卡带中运行。Lua本身支持将数据作为代码运行,但Pico-8删除了这一功能,这意味着需要使用更多代码空间的程序需要构建它们自己的虚拟机。
Pico-8并不能以电脑处理器的全速执行Lua代码。执行不同函数所需的时间已经被预先设定好。而这种速度限制也可以减少典型的Pico软件开发时所可能出现的问题,同时也将其对硬件的需求标准化,并避免了硬件需求的螺旋上升。按照作者的描述,第一代的树莓派就足以让最复杂的Pico软件全速运行了。
如何编写代码?
Lua是一种全部使用大写字母的语言,因此它往往会让人联想起BASIC。举例来说许多人都会记得如何使用BASIC语言无限循环打印文本:
::START::PRINT"HELLO"GOTOSTART
不同于标准的Lua库,Pico提供了一组有限的BASIC风格的函数:其中包括了绘图函数,一组声音函数,控制器输入函数和一些内存管理、数学运算、位运算和字符串处理函数。
基本的绘图命令可以绘制像素、四边形、线段、圆形、文本、精灵和背景地图。绘图命令可以切换其使用的调色盘颜色,你也可以将精灵和背景的颜色变为透明色。
Pico绘制活动图形的功能更接近于PC而不是8-bit家用电脑。Pico没有“硬件精灵”或者“硬件卷轴”相反,通常每一次刷新都需要重新绘制:清除屏幕、绘制背景并绘制需要的精灵。
绘制精灵可以使用两个不同的函数:spr()可以在指定的坐标上绘制一个8x8像素的精灵,而sspr()则可以在任意区域以任意缩放比例绘制精灵。缩放功能可以帮助开发者实现在大多数经典硬件上开销较大的技巧,比如说Doom风格的纹理映射。
开发者可以将绘图命令放到一个无限循环当中,但更优雅的方式则是将其定义为名为_draw()的函数,这样每一次屏幕刷新都会触发到它,也就是说每秒会调用0次。因此上面的例子可以被这样改写:
FUNCTION_DRAW()PRINT"TERVEHDYS"END
btn()函数可以读取游戏手柄状态,它支持使用数字作为检查特定按钮是否被按下的参数。一段将0号精灵向左或向右移动的代码大概是这样:
X=64FUNCTION_DRAW()CLS()SPR(0,X,)IFBTN(0)THENX=X-1ENDIFBTN(1)THENX=X+1ENDEND
为了能够在屏幕上有所显示,在执行这段代码之前,您需要先在精灵编辑器里绘制0号精灵。
有时候_draw()函数可能包含了太多的功能,因此无法在每次屏幕刷新时执行。在这种情况下,开发者需要改用_update()函数来刷新游戏状态——理论上讲——它每秒也会被调用0次。同样的从理论上讲,由于没有使用定时器中断,如果_draw()花费的时间更长,它可能会被调用若干次。
一般来讲双缓冲(Double-buffering)的绘图技巧在Pico上面并不适用,因为只有当_draw()函数执行完成后更改显存的操作才其作用。另一方面来讲,即使在删除掉一些声音效果之后,用户内存也仅仅能够装下一个全屏双缓冲器。
声音方面Pico提供了sfx()和music()两个函数。前者会在第一个空闲的通道上播放指定参数的音效,而后者则会从指定的“图案”编号处开始播放音乐。
小型2D游戏的开发者们并不需要太在意命令执行的速度,只有当将要达到平台极限的时候才会出现问题。pset()函数刷新屏幕上所有像素所需的时间大概是正常情况下屏幕刷新的1.5倍。直接使用poke()函数写入显存则比一般情况下快将近三倍。然而,使用memcpy()和memset()函数的话,速度将会快上10倍,并且绘制背景图像的命令map()的速度也是一样快。
像素方块的乐趣
Pico的许多功能都会让人联想起年代的家用电脑,但它却没有止步于对传统或技术的复原,而更加强调创作的乐趣和像素方块风格的美术效果。那些对这一点感到疑惑的人们应当考虑到它毕竟是一款虚构的游戏平台:虚拟世界并不总是完美无缺的,但它设定了许多有趣的事件,并能够激发参与者的想象力。
如果我们用一个词来总结Pico-8的精神的话,我想应该是“直截了当”。其中的一部分来自于8-bit电脑和运行在上面的BASIC语言:你可以在“开机”之后立刻编写程序,而不需要考虑如何配置操作系统、API和运行环境。所有的事情都简洁明了:内存里的某个比特总是会反馈到屏幕上某个位置的某个色块上。
然而这一概念并不止于此,它没有时钟周期和栅格线,没有颜色单元边界,没有折腾开发工具和文件的困扰。平台自身的限制避免了磨洋工式的细节调整。这得益于没有可以调节的调色盘、采样系统和机器语言指令,你不再需要对它们进行微调。而较少的像素数让完美主义者们也不会花太多时间在处理抗锯齿上。
对于那些对它感兴趣了人们来说,Pico-8确实有一些技术挑战和智力问题在等着它们。但我们也同样不会认为Pico-8的世界里需要极度