65.9K
CodeProject 正在变化。 阅读更多。
Home

在HTML5浏览器中实现《割绳子》

starIconstarIconstarIconstarIconstarIcon

5.00/5 (5投票s)

2012 年 8 月 10 日

CPOL

13分钟阅读

viewsIcon

33151

利用 HTML5 的强大功能实现《割绳子》游戏。

30 天开发一个 Windows 8 应用

《割绳子》是一款几乎所有玩过它的人都会立即喜爱的游戏。它既有趣又可爱。于是我们产生了一个想法:通过使用 HTML5 的强大功能将其提供给网络,让更多人能够玩到这款出色的游戏。

为此,微软的 Internet Explorer 团队与《割绳子》的开发者 ZeptoLab 以及专家 Pixel Lab 合作,在浏览器中将《割绳子》带入生活。最终成果是将这款游戏真实地迁移到 Web 上,展示了 HTML5 最出色的特性:Canvas 渲染图形、基于浏览器的音频和视频、CSS3 样式以及 WOFF 字体个性。

您可以在以下网址玩到《割绳子》的 HTML5 版本:www.cuttherope.ie

我们认为 HTML5 版本让网络变得更有趣,并且它展示了最新版 Internet Explorer 在标准支持方面取得的进步。考虑到这一点,我们希望分享一些该项目中使用的酷炫的“幕后”技术细节,以帮助您构建自己的 HTML5 网站,并最终为 Windows 8 应用商店做好准备!

《割绳子》在 IE9 中作为 HTML5 应用程序运行,是从原始 iOS 源代码移植而来的。

此版本特有的一些精心设计的关卡截图。

Objective-C 至 JavaScript

在将《割绳子》迁移到新平台时,我们希望确保保留其独特的物理效果、运动和游戏体验的个性。因此,我们很早就决定将这款游戏作为从原生 iOS 版本“移植”过来(而不是重写)。我们从对原始 Objective-C 代码库的广泛研究开始。事实证明,这是一款庞大而复杂的游戏。原生 iOS 版本包含大约 15,000 行代码(不包括库)!代码库中最复杂的部分是物理、动画和绘图引擎。它们本身就很复杂,而且由于这三者紧密相连且高度优化,使得它们更加复杂。

这是一项艰巨的任务:将这些代码移植到浏览器,同时保持玩家所习惯的独特个性和令人难以置信的质量。为了实现这一目标,我们选择了 JavaScript。

过去,JavaScript 被认为是一种运行缓慢的语言。坦白说,这种声誉最初是有效的。较早的 JavaScript 引擎是为简单的“脚本”任务设计的(因此得名)。然而,如今,JavaScript 引擎已经得到了高度优化。凭借即时编译等功能,JavaScript 现在可以接近原生速度执行。

此外,我们知道为 JavaScript 编码与使用编译语言编码不同,并且需要不同的思维方式。在我们从 Objective-C 移植游戏的过程中,我们知道我们需要承担起进行此类更改和优化的任务。

一个显而易见的例子是 JavaScript 中缺乏 结构体(structs)。结构体是相关属性的轻量级聚合。很容易使用 JavaScript 对象来存储一组属性,但这与真正的结构体存在重要差异。第一个区别是,每当结构体被赋给变量或传递给函数时,结构体都会被复制。因此,用 Objective-C 等编译语言编写的函数可以修改作为参数传递的结构体,而不会影响调用者中的值。即使在函数内部,将结构体赋给不同的变量也会复制值。另一方面,JavaScript 对象是按引用传递的。因此,当函数修改对象参数时,更改将对调用者可见。

模拟结构体特性的一个简单方法是创建 JavaScript 对象副本以进行赋值或参数传递。在原生语言中,使用结构体的开销通常很小。在 JavaScript 中创建对象成本更高,因此我们必须非常小心地尽量减少分配的数量。特别是在赋值时,只要可能,我们都尝试复制单个属性,而不是创建全新的对象实例。

另一个例子是 Objective-C 代码库的面向对象特性。JavaScript 提供的是原型继承,而不是传统的基于对象的继承。这是一种高度简化的对象继承形式,实际上与 Objective-C 等传统面向对象语言不兼容。幸运的是,有各种类库可以帮助您为 JavaScript 编写面向对象编程(OOP)风格的代码;我们使用了 John Ressig(jQuery 开发者)编写的一个非常简单的类库。(请注意,ECMAScript5,即最新版 JavaScript 的规范,也包含一些对类的支持,但由于我们对该版本语言不熟悉且开发进度紧迫,因此在此次移植中我们没有使用它。)

除了从 Objective-C 移植到 JavaScript,我们还需要将图形代码从 OpenGL 移植到 HTML5 Canvas API。总的来说,这进行得很顺利。Canvas 是一个惊人的快速渲染表面,尤其是在浏览器中,该 API 是硬件加速的(例如 Internet Explorer 9)。

使用 Canvas API 绘制带有锯齿消除线的绳子的示例。

令人惊讶的是,我们遇到了一些 Canvas 比《割绳子》移动版本使用的 OpenGL ES 版本功能更强大的领域。一个例子是绘制抗锯齿线。在 OpenGL 中绘制抗锯齿线需要将线细分为三角形条带,并使端点的透明度逐渐减弱直至完全透明。HTML5 Canvas 会自动处理其 line API 绘制的线条的抗锯齿。这意味着我们实际上需要从 OpenGL 版本中删除代码。展开 OpenGL 代码中的三角形顶点数组也比尝试本地复制绘制线条的三角形条带方法提供了更好的性能。

最终,我们在浏览器中执行了近 15,000 行代码(代码已压缩,如果您在浏览器中查看源代码,行数会少很多)。考虑到如此庞大的代码量带来的复杂性,ZeptoLab 的开发总监 Denis Morozov 在早期就提出了一个公平的问题:HTML5 能否为这款游戏提供我们所需的速度和性能?

为了回答这个问题,我们创建了一个早期的“性能”里程碑,专注于让游戏中最激烈的部分的最小化版本运行起来。也就是说,我们想看看绳子看起来如何,以及我们能否在浏览器中处理复杂的物理引擎。

性能

项目进行到第三周,我们终于完成了物理和绘图引擎的基础,并用一个简单的计时器来引导动画。我们现在可以将几根绳子、一颗星星和 Om Nom 精灵渲染到游戏场景中。进展顺利!到第四周,我们加入了一些基本的鼠标交互,通过这些交互我们实际上可以玩游戏了!我们一直在测试性能,但我们想让 ZeptoLab 的团队给我们反馈。

当我们与 ZeptoLab 分享代码时,他们对我们在现代浏览器中看到的性能(特别是游戏的流畅度和速度)感到惊喜。老实说,我们当时也有些忐忑。我们预计 JavaScript 会很快,但物理计算非常密集,而且必须实时进行。这是一个很好的例子,说明了对 JavaScript“运行缓慢”的普遍看法是错误的。最新一代的 JavaScript 引擎速度极快。

在这种情况下,我们是在 Internet Explorer 9 中预览这款游戏。加载游戏时,Internet Explorer 9 的 Chakra JavaScript 引擎会在后台线程中预编译代码,就像编译器编译 Objective-C 或 C++ 等语言一样。然后,它实时将编译后的代码(字节码)发送到游戏线程执行。其结果是近乎原生的执行速度。令人惊讶的是,这是 JavaScript 引擎免费提供的功能——我们无需在代码中做任何特殊处理。

项目早期帧率测试结果(请注意,帧率上限为 60FPS)

我们对 JavaScript 的投资开始得到回报,因此我们将注意力转向了硬件和浏览器。凭借 Internet Explorer 的硬件加速渲染堆栈以及我们在 Disney Tron 和其他 HTML5 网站方面的经验,我们对它在我们测试机器上完美运行游戏的性能没有任何担忧。我们轻松地达到了设定的 60 FPS(每秒帧数)上限目标。但是,我们希望确保游戏能在其他硬件和浏览器上良好运行。在进行了一些初步测试后,我们看到了这样的结果

根据这些数字,我们将 30 FPS 设定为我们的最低标准。我们决定,当浏览器低于此阈值时,我们将通知用户。他们仍然可以玩游戏,但我们会告知他们可能会感觉有些迟缓。这确保了我们支持种类繁多的硬件和软件,并为所有游戏访客提供尽可能好的体验。

我们想指出两点。第一,当前版本的游戏在带有鼠标的台式电脑和 Mac 上运行效果最佳。我们尚未添加对触摸输入的支持,但这是我们正在考虑未来版本的功能。

第二,当前版本的 Chrome(16 版)存在与媒体播放相关的已知问题,这使得《割绳子》中的声音不可预测。我们研究了解决方法,并尝试了多种格式(包括 WebM)的重新编码,但没有找到任何能可靠解决此问题的方法、MIME 配置或其他任何方法。这些似乎是浏览器错误和已知问题。更重要的是,尽管音频存在间歇性问题,但游戏仍然可玩且令人愉快。有鉴于此,虽然我们可以说 Internet Explorer 9 用户获得了出色的无插件体验,但 Chrome 和一些 Firefox 用户可能会遇到音频问题,但他们会注意到我们回退到 Flash 插件以确保声音效果和音乐能够正常工作。

工具

HTML5 的一个好处是,您无需学习新语言即可掌握这项新技术的力量。如果您了解并掌握了 JavaScript,您就已经拥有了访问现代浏览器所有功能的能力。您甚至可以创建自己的类似游戏!

代码编辑器和开发环境

Visual Web Developer 2010 Express 可免费下载,是经验丰富的 Web 开发人员的优秀编辑器。

性能分析器截图,显示了在 Calc2PointBezier 函数中花费了不成比例的时间,该函数用于计算绳段的位置。

有一些很棒的免费工具可以轻松地使用 JavaScript 和 HTML5 进行开发。我们的许多开发工作都在 Visual Web Developer 2010 中完成(“Express”版本可在此免费获取)。这是一个非常强大的 Web 编辑器,支持 JavaScript 和 CSS 的自动完成。Express 版本免费真是太棒了!我们在 Windows 7 上的 Internet Explorer 9 中进行了大部分测试,偶尔也会在 Firefox、Chrome、Safari 和 Internet Explorer 10 开发者预览版中进行测试。总的来说,所有主流浏览器都对我们使用的 HTML5 功能实现了非常一致的兼容,并且在大多数情况下,在 Internet Explorer 9 中测试过的任何内容在其他地方都“能正常工作”。

查看我们的资源加载器!

《割绳子》拥有非常独特且精美的视觉风格——大量的媒体形式,包括图像、声音和视频——这些都需要付出一定的成本。结果是整个游戏比普通网站大得多。加起来大约是 6MB(相比之下,典型的网站是 200-300K)。如此大量的媒体下载可能需要一些时间,而且我们必须等到所有内容都可用后才能开始游戏。一个传统的网页如果缺少一两个图像可能不会有问题,但 HTML5 Canvas API(drawImage)在图像不可用时会失败。

为了应对这一挑战,我们希望创建一个资源加载器,该加载器可以下载页面所需的所有内容,并在内容下载过程中提供良好的反馈。这段代码做了很多智能的事情:

  1. 它处理不同浏览器如何处理下载以及它们如何通知您下载进度的特殊性。
  2. 它允许您就下载顺序做出明智的决定(例如,您可能想先下载大文件,或者在下载游戏图像之前下载所有菜单图像)。
  3. 最后,它会在内容到达时提供智能事件,以便您可以向用户显示进度,甚至在第一组内容完成后启动游戏的一部分。

构建这些类型的库要做好很难。由于我们对这一切如何协同工作感到非常满意,因此我们希望与您分享我们的资源加载器的代码。结果是 PxLoader,一个 JavaScript 资源加载器库,您可以将其用于 HTML5 应用程序、游戏和网站的预加载器。它是开源且免费的。您可以从页面顶部获取,或者直接点击此处

Internet Explorer 中的性能工具

开发过程中另一个不可或缺的工具是 Internet Explorer 9 中的 JavaScript Profiler。性能分析可帮助您发现代码中的热点和瓶颈。在我们第一个性能相关的里程碑中,当发现我们在某些机器上卡在 20 或 30 FPS 时,我们几乎放弃了。

我们进行了一些初步的代码审查,但没有什么明显的问题。我们加载了带有性能分析器的游戏,并立即发现我们在 satisfyConstraints() 函数中花费了大量时间。该函数计算了与绳索物理相关的一些数学运算。我们移植的 Objective-C 实现是递归编写的,将一个新对象传递给每一个更深层次的调用。

在微软的指导下,我们决定用一个“解压”的迭代版本替换递归函数。结果令人惊叹。我们在每个浏览器中都看到了 10 倍的性能提升!坦白说,如果没有 Internet Explorer 9 中的性能分析工具,我们永远也找不到这一点。

接下来是什么?

在九月份的 BUILD 大会上,微软展示了 Windows 8 的开发者预览版。随着这一公告的发布,HTML5 的故事变得更加有趣,因为 Metro 风格的应用程序可以使用多种开发工具集来创建,包括 HTML5。这意味着 Web 开发人员可以将为 Web 编写的代码轻松无缝地移植到 Windows 8。现在在网上投入沉浸式体验的投资,未来可以通过 Windows 应用商店获得实际利润。

事实上,经过很少的额外工作,我们就能够将这个 HTML5 体验移植到 Windows 8 Metro 风格的应用程序。阅读有关《割绳子》及其与 Windows 应用商店集成的信息,请参阅这篇博文

我们很高兴看到开发人员今天能用 HTML5 构建出什么。您可以下载 Internet Explorer 9 并访问 www.beautyoftheweb.com 上的其他精美网站,或者在 dev.windows.com 下载 Windows 8 的开发者预览版。

© . All rights reserved.