网络上的 Doom

更新: 我们对这个开源 Doom 的移植是否尊重其使用条款存疑。在做出明智和最终决定之前,我们决定从网站上移除它。

这是一篇由 Alon Zakai 撰写的客座文章。Alon 是 Firefox Mobile 开发人员之一,在空闲时间,他喜欢用 JavaScript 和新 web 技术进行实验。其中一项实验是 Emscripten,一个 LLVM 到 JavaScript 的编译器,以下是 Alon 对它如何使用类型化数组运行经典的第一人称射击游戏 网络上的 Doom 的解释。

作为一名长期第一人称射击游戏爱好者,我一直想把它们带到 web 上。从头开始编写一个非常困难,所以,我采用了最初的 Doom,它是开源的,并使用 Emscripten 将其从 C 编译到 JavaScript。结果就是,Doom 的一个版本可以用 在 web 上玩,使用标准的 web 技术。

Doom 通过将像素数据写入内存,然后在转换颜色等之后将这些像素数据复制到屏幕上进行渲染。对于此演示,编译后的代码具有用大型 JavaScript 数组模拟的内存(因此该数组中的元素 N 代表正常原生代码中内存地址 N 的内容)。这意味着渲染、颜色转换和复制到屏幕上的所有操作都在该大型 JavaScript 数组上完成。基本上,该代码包含大型循环,这些循环复制或修改该数组的元素。为了使它尽可能快,演示可以选择使用 JavaScript 类型化数组,它们看起来像普通的 JavaScript 数组,但保证是特定数据类型的扁平数组。

// Create an array which contains only 32-bit Integers
var buffer = new Int32Array(1000);
for ( var i = 0 ; i < 1000 ; i++ ) {
    buffer[i] = i;
}

当使用类型化数组时,与普通 JavaScript 数组的主要区别在于数组的元素都具有您设置的类型。这意味着在该数组上工作可能比在普通数组上快得多,因为它与普通低级 C 或 C++ 数组非常接近。相比之下,普通的 JavaScript 数组也可以是稀疏的,这意味着它不是单个连续的内存区域。在这种情况下,每次访问数组都会产生一个成本,即计算正确的内存地址。使用类型化数组,查找内存地址要快得多,因为它很简单直接。因此,在 Doom 演示中,使用类型化数组的帧速率几乎是未使用类型化数组的两倍。

类型化数组在 WebGL 和 音频数据 API 以及 Canvas 元素(从 getImageData() 收到的像素数据实际上是一个类型化数组)中非常重要。但是,如果您正在处理大量类似数组的数据,也可以独立使用类型化数组,这正是 Doom 演示的情况。只需注意,如果用户的浏览器不支持类型化数组,您的代码也能正常工作。这样做相当容易,因为类型化数组在大多数情况下看起来和行为像普通数组一样——您使用方括号访问它们的元素等等。主要的潜在陷阱是

  • 类型化数组没有 slice()。相反,它们有 subarray(),它不会创建数组的副本——相反,它只是对相同数据的视图。
  • 不要忘记类型化数组的类型是静默强制的。如果您将 5.25 写入整数类型数组的元素,然后读回完全相同的元素,则会得到 5,而不是 5.25。

关于 louisremi

开发者关系团队,长期 jQuery 贡献者和开放 Web 爱好者。 @louis_remi

更多由 louisremi 撰写的文章…


14 条评论

  1. Shmerl

    太棒了!

    还有一个非常有趣的项目值得注意,它也大量使用了类型化数组——Javascript PC 模拟器

    http://bellard.org/jslinux/
    http://bellard.org/jslinux/tech.html

    2011 年 6 月 3 日 下午 09:13

  2. 未找到

    链接显示未找到错误。

    2011 年 6 月 4 日 上午 02:09

  3. nemo

    网络上的 Doom 现在似乎 404 了?

    2011 年 6 月 4 日 下午 12:31

    1. skierpage

      很可惜,它都 404 了,Google 缓存仍然有介绍页,但没有启动页或下载页,而且糟糕的 MDN 搜索有一个指向上传的链接(
      developer.mozilla.org/media/uploads/demos/a/z/azakai/487d42c2ecc16277745a469861bd377e2/doom-on-the-web_1306727266_demo_package/details.html ),它也是 404。

      2011 年 6 月 4 日 下午 13:41

  4. Mike

    哎,真是个玩笑。真的很想看看 Doom 演示。啊!在我看到演示在我的浏览器中运行之前,我不会相信这一切。

    2011 年 6 月 4 日 下午 18:39

  5. nemo

    据说被 DMCA 了 :(

    2011 年 6 月 5 日 下午 12:23

  6. farin

    全新的技术类型化数组——因此 javascript 可以像 C 程序一样使用,在没有类型化数组的情况下,它无法使用。重新发明轮子。

    2011 年 6 月 9 日 上午 03:26

    1. louisremi

      碰巧您正在浏览一个可用的 Web,它由嵌入 JavaScript 的页面组成,而不是使用类型化数组。

      2011 年 6 月 9 日 上午 03:32

  7. ZippoLag

    拜托!DOOM 不可能存在版权问题!!让我们玩它!

    2011 年 6 月 14 日 上午 08:17

  8. Janet Swisher

    DCMA 下架请求可在此处查看
    https://wiki.mozilla.org/Legal/Infringement_Notices/3_June_2011

    2011 年 6 月 17 日 下午 13:00

  9. jmdesp

    我认为这可以恢复,方法是将其描述为在线玩 Doom 引擎,并使用非商业 WAD,我不知道哪个最适合使用,但有相当数量的 WAD
    http://en.wikipedia.org/wiki/Doom_WAD#Notable_WADs
    http://www.doomworld.com/idgames/index.php?top

    Freedoom 很好,但它需要 Boom 版本的源代码
    http://en.wikipedia.org/wiki/Doom_source_port#Boom_and_derivations

    2011 年 6 月 20 日 上午 08:01

  10. James Haley

    至少将您的源代码保存在某个地方;Zenimax 绝对没有权利告诉您不能分发它,因为它受 GPL 保护,而他们绝对不能撤销它。

    我个人认为,共享软件分发许可证也为发布 DMCA 反通知提供了依据,但这可能是一个灰色地带,可能会导致诉讼。如果您有足够的钱,这将是一场值得一打的战斗。

    作为 DOOM 源代码移植作者(永恒引擎),我必须担心 Zenimax 这些唯利是图的人很快就会来找我和 DOOM 社区的其他人。

    2011 年 7 月 20 日 下午 20:40

    1. louisremi

      据我所知,游戏引擎已经开源,但游戏资产并没有。

      2011 年 7 月 21 日 上午 07:46

      1. James Haley

        该程序使用共享软件 IWAD,虽然它不在自由许可证下,但一直声明可以重新分发。

        Zenimax 显然不知道“共享软件”中的“共享”一词的含义。

        2011 年 8 月 5 日 下午 16:03

本文的评论已关闭。