开发者实例论述如何向HTML5平台发展

<![CDATA[

作者:David Galeano, Duncan Tebbs

与其它平台一样,HTML5也遭遇了各种各样的批评,有些批评是正当的,但是也有许多是听信谣言或基于过时信息的荒谬之谈。不过不管怎样,该领域大多数成功的企业领导者还是非常支持HTML5,并且出现在turbulenz.com上的游戏也向我们证明了HTML5适用于高质量的游戏。所以我将在这篇文章中详细解释我们之所以支持,并愿意继续支持HTML5的原因。

HTML5能够快速将网页变成高质量游戏的最佳平台。瞄准这一网页标准的游戏不仅能够基于各种环境而运行,同时还能利用潜在硬件的强大能力以及现代设备的连通性。

Turbulenz投入了大量的研究和设计力量去创造一个面向网页的高性能游戏平台。基于主机的游戏技术开发背景,我们从游戏开发者的角度接近了HTML5以及相关技术(并始终牢记高保真度与性能)。

这一系列文章便是描写我们从主机转向网页所获得的重要经验:什么最有效,该何时使用,如何为解决持续的问题而优化策略和工作环境等。

有些基于Turbulenz的游戏能够利用turbulenz.com的游戏网站,即使用我们的HTML5平台和基础设施向在线玩家传达高质量的3D游戏。这家公司是在2009年初由一群来自Electronic Arts的主管和首席设计师所创建的,随后该团队不断扩展,又吸纳了来自世界各地主要娱乐公司的开发者和业务专家们。

turbulenzgroup(from gamasutra)

在第一篇文章中,我们将讨论HTML5当前的发展以及与游戏相关的技术,并概述游戏开发者们所期待的开发环境和工作流程。

浏览器作为一个游戏平台

浏览器已经成为了一种全新的操作系统,而在呈现出各种问题的同时也带来了巨大的机遇。在过去,游戏总是孤立地存在着,在消耗资源的同时也从机器身上提取着完整的性能。运行于浏览器上的游戏代码将与其余的浏览器过程展开竞争,包括运行于其它标签或窗口的游戏(以及其它运行于该机器上的内容)。

在某种程度上,每个浏览器都必须被当成一个不同的平台:在所有浏览器中,有些界面较为常见,有些资源也是通用的,但从更高级的功能来看,开发者们必须在执行期间不断检查功能,并提供各种代码路径和变通方法。

包含浏览器,浏览器版本,OS,OS版本以及硬件的测试参数非常广泛。除此之外,尽管硬件资源不能被直接当成原生应用,但是开发者还必须处理图像驱动的漏洞以及藏在浏览器层面(与这些驱动程序连接在一起)的漏洞。

基于快节奏的浏览器更新,以及有些浏览器是进行自动更新,我们很难维持一个特定的支持版本列表进行测试。在Turbulenz,我们总是使用每个浏览器的最新版本以及一列最有名的浏览器版本。在写这篇文章时,我们面对的便是Explorer 8,9,10,Firefox 3.6以及最新版本,Safari 5.1以及最新版本(基于Mac OS X),Chrome的最新版本。我们使用了来自Nvidia,AMD以及Intel的视频卡去测试一系列硬件(从较低端的上网本到高端笔记本)。

作为开发平台,浏览器比其它平台拥有多个优势。总的来说,其迭代速度非常快(JavaScript在正常开发和更新时不需要经历编译阶段,只需直接加载和运行最新的代码版本)。网页开发者们一直热衷于使用一系列工具去排除故障并分析性能,而这也构成了非常有效的开发环境。

一般而言,我们会建议开发商保守地编译代码,在不同浏览器上进行测试,并不断监控新版本的状态。

基于JavaScript的游戏开发

只有一种通用编程语言能够用于浏览器中,那就是JavaScript。它还有一个官方名称:ECMAScript。我们并不是要在本文介绍这一语言,而是打算强调在基于C/C++背景使用JavaScript时所突出的一些元素或意想不到的性能影响。

特别是当我们将一个大项目从C/C++转移到JavaScript时,开发者们将会面对一定的挑战。JavaScript的语法与C语言类似,但其实它与功能语言(如Lisp)拥有更多共同点;它拥有闭包和一等函数。

我们发现闭包非常强大,能够更轻松且更清楚地创造异步程序。但是如果开发者不清楚自己的行为便会引起一些小问题。

例如,在循环中创造闭包并引用在执行循环时发生改变的变量便会引起一个常见的错误。因为变量是关于闭包执行时的价值(而不是在其创造时刻)。

JavaScript拥有一等函数意味着我们可以将函数当成参数进行传递,从其它参数过度给各种变量,并储存在词典库里。我们可以在运行时将字符串编译到函数中,不过出于安全原因,我们并不会建议开发者们这么做,因为字符串是源自未知的来源,并需要向代码的其它部分妥协。

语言具有面向目标的功能,但却不存在类别。JavaScript拥有构造函数和面向原型的继承。对象扮演着数据词典的角色,能够保存所有内容,并通过名称进行索引。我们还发现使用错误的名称去访问价值是个常出现的错误,而这通常是由代码的打字错误所引起的。

对象可以被指定为其它对象的原型。如果我们不能在一个对象中找到性能,那么运行时间将检查原型对象。我们可以将函数储存在对象中,而对象也可以分享原型,原型机制还可以让方法和代码基于相同的方式重新使用。除此之外,函数与对象一样也可以用于储存,并基于名称检索性能。

JavaScript并未拥有析构函数。当不存在任何参考时,JavaScript的运行时间将安排其销毁的时间点,并且JavaScript代码不会收到任何通知。我们发现在JavaScript代码中找到内存泄漏的重要性(也就是将参考传递到对象上时,对象拒绝收集任何无用的内容)。有些JavaScript分析工具所提供的对象数是基于它们所累积的快照,这一点虽然很有帮助,但是它们同样也要求对象必须源自非文字构造函数,并使用新的运算符(从而更好地进行区分)。有些分析工具同样也提供参考去追踪它们的堆积快照,这能帮助开发者鉴定哪些目标并不属于垃圾。

我们建议开发者们可以创建一个清晰且定义明确的对象所有权政策。这能让我们更轻松地指出哪些代码是用于维持特定对象的参考。

JavaScript并未拥有静态类型,所以变量可以拥有不同的类型,并且如果在同样的操作中使用不同类型变量便会出现自动转换。例如在字符串上添加数字将引起一连串的数字转变成字符串。最终导致我们很难找到问题所在,并对性能造成影响。

另外一个漏洞来源便是JavaScript逐位运算,即使用大端法次序并基于二进制补码格式将参数转变成32位体整数。举个例子来说吧,以下两种表述都是合理的:

(0×80 << 24) !== 0×80000000
(0×80 << 24) === -2147483648

如果使用的是无符号整数的话,这两种表述都将是错的。同时我们还需要使用三重远算符,因为如果操作对象具有不同的类型,它便不能执行类型的转换。相反的,双重运算符能够执行类型转换,并且能在代码中隐藏失误。

尽管JavaScript变量拥有布尔值,但是其它基本的类型也能够用于条件表达式中,以下名称都是用于表示错误值:零,未定义,空串,“0”,非数值。

<

p >JavaScript并未拥有区块范]
]>