HTML5游戏技术开发难点分析

HTML5游戏的优劣势

最近微信公众游戏平台讨论得如火如荼,HTML5游戏的热度也一波高过一波,那么开发HTML5游戏和传统游戏相比有什么优劣势呢?

首先看优势,当属跨平台最受欢迎,开发一套游戏即可在PC,平板、手机中无缝切换,而且统一标准的API也极大地方便开发者。其次,HTML5原生浏览器支持,无需任何插件支持,这对用户来说也是很大的一个优点。最后当属各大公司的鼎力支持,GoogleMicrosoftTecent, UC web等等

然而目前来看,HTML5的劣势主要体现在性能不足和游戏开发特殊API的缺失等,这篇文章将和大家分享在HTML5游戏开发中,常见的技术瓶颈以及如何解决。

输入事件响应

总所周知,游戏玩家点击频率是相当高的,能够达到120次每秒,而一款游戏显示达到30 FPS 即相当流畅,人眼基本感受不出间隔了。那么在HTML5中如何去处理这些输入事件呢? 由于JavaScript的单线程特性,如果原封不动地去处理这些输入事件,那么可想而知,UI现成将完全被阻塞掉。

解决方法分为三步:

1.      在缓存中记录每个输入事件,并非立刻处理事件

2.      在每次渲染时处理缓存

3.      自动清空缓存中已经处理过的事件

示例程序如下,我们分别通过bufferno buffer情况下,一直按按钮来观察瞬时FPS的变化,通过在IE上面测试有buffer的情况下,性能要高于no buffer情况下20%左右,当点击频率高时,性能提升更加明显。读者可以下载App在本机进行测试。下载地址在本文附件中: 下载

 

时间轴

开发过Flash游戏的朋友肯定对时间轴很有感情,用来做关键帧动画等非常方便。那么在HTML5中有没有时间轴可以用呢?如何精确控制帧动画。

解决方案有两个:

1.    使用setInterval动画可以达到目的,但是setInterval的精度比较低,在空闲状态下setInterval()的精度量级为10mssetInterval的示例代码如下:

2.    更好的方案是在每一秒里面计算已渲染的帧数,同时设置很小的回调间隔,仅在正确的时间进行渲染,这样可以方便的得到FPS信息, 示例代码如下:

图层

图层是游戏开发中,非常重要的概念,使用图层可以将活动物体和背景静止物体相分离,分开渲染和绘制,仅仅重绘必要部分并缓存以固定模式变化的帧动画来提高性能,通过图层,还可以由Play/Stop/Show/Hide等封装游戏逻辑。在事件处理上,图层同样很重要,通过只处理落在图层上的事件,可以提升游戏体验。但是在HTML5中并没有图层工具,这给游戏开发者增加开发难度。

第一个解决方案是通过共享canvas的逻辑图层,具体步骤为:使用同一个canvas将绘图代码按逻辑关系封装成“图层”。这种方法难点在于如何尽可能缩小重绘区域。它的优点是可最大化绘图性能,方便实现timing function;缺点是图层间无法完全独立,需要反复重绘同样内容。这种方法比较适合于存在大量动态图元的场景。

第二个解决是基于DOM元素层级关系来将Canvas分级创建多个canvas结点,每一个独立渲染,用zIndex管理层级关系。这样来处理的优点是图层互相不干扰,业务逻辑可完全独立;缺点在于动态渲染效率较低。适用场景是背景动画/游戏菜单/独立的动画元件等。

其结构如下:

关键帧

Flash游戏开发中,通过设置关键帧可以快速创建出动画效果,那么在HTML5游戏中,关键帧可以通过以下方法来设置:

第一步,将关键帧事先绘制好,制作成图片,然后配置帧出现的时间点、帧与帧之间的间隔最后将将关键帧图片打包成整张图片。

这个方法对应于两个方案,分别是Canvas方案和CSS Animation的方案。Canvas方案用drawImage绘制图片,通过设置合适的clip区域来动态绘制的关键帧,可使用getImageData/putImageData来绘制。CSS Animation的方案keyframes Timing functions来操作。

音频效果

音频效果的处理详见另一篇文章的介绍:HTML5 Audio API开发游戏音乐

Canvas绘图性能

Canvas绘图是游戏开发最需要注意的点。下图是一款游戏的性能分析,可以看出,stroke占用了84.74%的性能。

我们可以通过以下几个方法来提升Canvas性能:

1.    预渲染场景中的部分物体最后一次性Stoke()/fill()

我们分别测试了上图中的直接渲染方案和预渲染方案,结果显示在Chrome中,有接近100%的性能提升。

2.    使用 水平/竖直的直线绘图性能比斜线性能要好,同时可以使用Rotate, Scale等避免多次绘图操作,如下图所示,斜线,四边形等都可以由左边的正方形通过变形得到。

3.    避免做重复的像素操作。在游戏中,经常出现一个角色有不同的配色方案,这时候,我们通过色彩和透明度的调节和叠加比直接像素操作更高效。如我们需要渲染下图中的黄忠,同时我们还需绿色,紫色等等。那么我们通过几种基本颜色进行叠加来获得所要的效果更好。

Canvas的绘图性能一直是游戏开发者最为繁琐的事情,那么下面列出三种替代Canvas的选择,但是也是各有各的有点和缺点:

1.       WebGL-2d使用webGL 渲染2d canvasWebGL可以充分使用GPU来渲染,提高性能。但是目前浏览器对WebGL的支持度还不如Canvas,尤其在移动端浏览器上面。

2.    SVG + CSS3

Adobe WallabyFlash动画导出成 SVG + CSS3 Animation

3.    简单动画采用DOM元素

通过Absolute positioning: 改变left/top/right/bottomCSS translate来做动画

第二和第三个方案都仅适合于动画比较简单的场合。

参考

1.    Cocos2d-HTML5 https://github.com/cocos2d/cocos2d-html5

2.    Huan Du HTML5 game challenges and solutions

 

Para obter informações mais completas sobre otimizações do compilador, consulte nosso aviso de otimização.