我的《
Game Engine Black Book》一整章
都涉及到
DOOM控制台端口及其开发人员所遇到的挑战。 您可以讨论3DO的完全失败,仿射纹理贴图在Saturn遇到的困难以及Randy Linden对于Super Nintendo进行的惊人的“从零开始逆向工程”。
最初朝崩溃的方向发展
[1] ,Playstation 1(PSX)端口的开发人员随后能够改变路线,并创建了在评论家和市场中成功的端口。
Final DOOM是第一个与PC版本相当的真实端口。 具有alpha混合功能的颜色扇区不仅改善了视觉质量,而且还通过指示所需颜色的键来改善了游戏玩法。 另外,由于PSX控制台的音频处理单元的混响效果,声音得到了改善。
开发团队执行了如此高品质的工作,以至于他们仍然有一些免费的CPU周期,他们决定使用这些CPU周期在
简介和
游戏过程中生成动画效果。 这令我敬畏,以至于我决定弄清楚效果是如何实现的。 当最初的搜索没有给出答案时,我正准备从MIPS书籍中吹出来破解可执行文件,但塞缪尔·比利亚雷亚尔(Samuel Villarreal)准时回答了Twitter,说他已经完成了Nintendo 64
[2]版本的反向开发。 对我来说,清理一下,简化和优化就足够了。
重新发现这种经典的场景效果很有趣。 它的基本思想类似于第一个
水波纹 ,它被包含在90年代许多开发人员的强制性计划中。 精心选择的调色板和简单的技巧相结合是实现理想结果的唯一方法,当时的火焰效果成为活生生的见证。
基本思路
射击效果的核心是使用简单的高程图。 屏幕大小的数组填充有37个值,范围从0到36。每个值与从白色到黑色的颜色关联,并沿它们之间的路径捕获黄色,橙色和红色。 这个想法是模拟上升并逐渐冷却的火焰粒子的温度。
帧缓冲区被初始化为全黑(填充有零),底部(36)是一条白色像素的白线,是火焰的“源”。
每次更新屏幕时,“热量”都会增加。 对于帧缓冲器中的每个像素,都会计算一个新值。 考虑到位于其正下方的值,将更新每个像素。 在代码中,左下角是数组的零索引,右上角具有索引FIRE_HEIGHT * FIRE_WIDTH-1。
function doFire() { for(x=0 ; x < FIRE_WIDTH; x++) { for (y = 1; y < FIRE_HEIGHT; y++) { spreadFire(y * FIRE_WIDTH + x); } } } function spreadFire(src) { firePixels[src - FIRE_WIDTH] = firePixels[src] - 1; }
请注意,行0永远不会更新(对y的迭代不是从0开始,而是从1开始)。 这条零填充线是火灾的“发生器”。 具有线性冷却(-= 1)的简单版本为我们提供了无聊的均匀输出。
我们可以稍微修改spreadFire()函数并修改热值的衰减率。 添加随机性是一个很好的选择。
function spreadFire(src) { var rand = Math.round(Math.random() * 3.0) & 3; firePixels[src - FIRE_WIDTH ] = pixel - (rand & 1); }

那已经更好了。 为了完善这种错觉,人们不仅可以随机分配,而且可以左右随机分配。
function spreadFire(src) { var rand = Math.round(Math.random() * 3.0) & 3; var dst = src - rand + 1; firePixels[dst - FIRE_WIDTH ] = firePixels[src] - (rand & 1); }
[注意 泳道:Youtube严重捏住了视频,最好观看原始文章中有关Javascript的演示,或者在扰流器下打开GIF。]瞧! 请注意,通过更改火焰传播过程,也可以模拟风。 我将把它作为已设法阅读本文的读者的练习。
完整的源代码
塞缪尔的
版本 (从逻辑上来说)看起来更像是汇编程序
版本 。 如果要查看它,则
有一个经过清理和简化的版本。
参考文献
[1]来源:
《 Game Engine黑皮书:DOOM》中详细介绍的完整故事[2]资料来源:
2018年3月25日Twitter帖子。