《HTML5 2D游戏编程核心技术》——第2章,第2.1节使用开发者工具

本文涉及的产品
日志服务 SLS,月写入数据量 50GB 1个月
简介:

本节书摘来自华章出版社《HTML5 2D游戏编程核心技术》一书中的第2章,第2.1节使用开发者工具,作者[美] 戴维·吉尔里,更多章节内容可以访问云栖社区“华章计算机”公众号查看。

第2章
在本书中,我们将从头开始编程实现一款游戏。像所有的游戏开发者一样,在开始之前,我们必须收集原始素材,并熟悉我们的工具。对于大多数游戏来说,下面的原始素材是必备的。
图像
音效
音乐
下面的内容则是可选的,使用它们可以给你的HTML5游戏增色。
网站图标
网页背景
GIF动画
网站图标是一些小的图标,可以在浏览器的地址栏或者标签中显示。网页背景可以是图像,也可以像Snail Bait游戏一样,用CSS画出来。Snail Bait游戏在加载资源时,会显示一个GIF动画。
幸运的是,所有必要的材料,从游戏图像到GIF动画都是可以获取的。你可以轻松地在互联网上,在满足开源许可证(例如Creative Commons)的条件下,找到高品质的图像、音效和音乐资源。
下面的开发者工具则可以帮助我们将之前的原始素材转换为一款吸引人的视频游戏。
Text editor
Console
Debugger
Prof?iler
Timelines
另外,游戏开发者还将用到:
图像编辑器
声音编辑器
浏览器开发环境一般都会包含前面提到的开发者工具,或者更多,并且都是免费的。你也可以使用高质量的、可以免费获得的图像和声音编辑器,例如GIMP和Audacity。
本章简单地描述了Chrome浏览器开发者工具,并教你如何在互联网上获取免费的图形、音效以及音乐资源。你也将学习如何编辑声音、图像,以及如何创建GIF动画、网站图标和CSS背景等内容。

游戏开发并不总是如此容易

在开源资源和免费开发环境出现之前,游戏开发要困难得多。开发人员为了使用开发环境,必须负担高昂的费用,另外,为了在游戏里能够使用一些图形、声音和音乐,也要支付给艺术家和音乐家一大笔钱。

付费游戏使用开源资源

目前有许多类型的开源许可证,其中的一些,例如Creative Comments,只要你在作品中署上原作者名,几乎可以让你对开源资源做任何事情。事实上,很多在售的游戏都是完全基于开源图形的。
2.1 使用开发者工具
在创建HTML5游戏时,毫无疑问需要使用开发者工具,而且你对这些工具的熟练程度决定了你完成一个游戏的困难程度和时间长短。
在写作本书时,所有的主流浏览器厂商——Chrome、Safari、Firefox、Opera和IE,都已免费提供强有力的开发者工具。尽管这些工具的细节有所不同,基本功能却是相似的。包括开发者记录日志信息到控制台,使用调试器调试,使用探测器定位性能瓶颈,使用时间线监控事件等。
关于浏览器开发者工具的深入研究不在本书的讨论范围之内,本章以Chrome开发者工具为例,讲述开发游戏的过程。

Chrome浏览器是变化的

在本书的开发环境课程里,Chrome浏览器的外观是不断变化的。你在本书中看到的一些截图或许和最新版本的Chrome浏览器不一样,但功能应该是一致的。
2.1.1 控制台
视频游戏是基于时间的。游戏会不知疲倦地创建一个又一个的动画帧来产生移动的假象。当游戏绘制动画帧时,它会使用前一帧之后流逝的时间来决定图形对象移动的位置,图形对象被称为sprite对象。
如果你通过调试器在每一个动画帧都调用的一行代码中设置了一个断点,无论你点击调试器恢复按钮的速度有多快,都将会极大地增加两帧之间的时间。更重要的是,依赖于两个动画帧之间时间的值,例如帧速率本身,将会变得不正常,如图2.1顶部截图描绘的那样,在调试器中显示了一个小于每秒一帧的无意义帧速率。

图2.1 调试器和控制台


ce1f800f011707168e89528cedff9774c1426334

另外,到达控制台的日志不会暂停游戏代码让游戏停止运行,这样你就可以监控像帧速率这样的数值了,如图2.1底部截图所示。
在图2.1的底部截图里,Snail Bait游戏使用了console.log()方法来显示游戏帧速率。Chrome浏览器的控制台包括一些其他方法,像console.log()一样,可以向控制台传递日志信息:debug()、error()、info()和warn()。这些方法和log()类似,但是浏览器将它们分类,方便你过滤出一些特殊类型的信息。程序清单2.1显示了Snail Bait游戏是如何使用error()和warn()的。
程序清单2.1中的JavaScript代码显示了Snail Bait游戏的2个声音函数,我们将在第14章中进行详细的讨论。如果我们不能定位到声音文件的某个特殊位置,就会出错,因为seekAudio()函数被调用时,所有的声音都会被加载,我们需要能够在任何需要的时刻定位
它们。
另一方面,在某些偶发情况下,Snail Bait游戏会同时播放超过本身支持数量的音效,此时没有额外的音频通道供程序调用,Snail Bait游戏因此无法播放这个音效。但是,由于多种音效同时播放而导致的不发声现象,本身并不是我们程序的错误,因此Snail Bait游戏会向控制台发送警告信息而非错误信息。
程序清单2.1 使用控制台报告警告和错误信息


1d884d65bf8b1d5d3286320146ff8c78fca9a59f


76004666b12c383cf7d0d678aef91e3f4f4e6cf6

浏览器分别使用红色和黄色图标来描述错误及警告信息,并将它们分在错误和警告的组里,这样你就可以方便地找到相关的内容。图2.1的底部截图显示了浏览器底部状态栏中的按钮,这些按钮可以按照错误、警告、日志或者调试信息来过滤日志内容。
表2.1列出了Chrome浏览器的所有控制台特征。
表2.1 Chrome浏览器控制台API


1dc7e2abda5755eee9ae4e35526fae664556d018


69f3470d5369f4eaf42ef7d48e2c6ef9fd4815a1

方  法 描  述
assert (expression, errormsg) 如果表达式错误,浏览器显示错误信息“Assertion failed:”,并在控制台将结果字符串作为错误显示
clear() 擦除控制台的所有内容
count (label) 显示count()被某个标签调用的次数(在代码的那个位置,拥有相同的标签),并显示结果字符串,例如console.count (‘Drawing’)就会产生输出,例如Drawing:X,其中X是那行代码被Drawing调用的次数
debug (object [, object,...]) 和log()相似,但是信息被分到debug组里
dir (object) 显示对象的JavaScript表示
dirxml (object) 显示对象的XML JavaScript表示(会在元素面板中显示)
error (object, [, object,...]) 会发出带有红色图标的错误信息和堆栈跟踪信息,其他和log()类似
group (object, [, object,...]) 开始一个新的日志分组,这个分组会持续到第一次调用groupEnd()时为止。浏览器会把控制台输出分到不同的组里
groupCollapsed (object, [, object,...]) 浏览器会在开始时将分组折叠,而不是打开(默认),其他和group()类似
groupEnd() 结束一个分组,参见group()和groupCollapsed()
info (object, [, object,...]) 同log()
log (object, [, object,...]) 每一个传递的对象以空格分隔的字符串的形式显示出来。第一个对象可以是一个带格式转换字符的字符串,和C语言中的printf()类似。这些格式转换字符包括:
? %s(字符串)
? %d或%i(整型)
? %f(浮点型)
? %o(展开的DOM元素)
? %O(展开的JavaScript对象)
? %c(使用CSS进行格式化)
prof?ile (label) 启动配置文件,并指定确定的标签,配置会一直运行到你调用prof?ileEnd()为止
prof?ileEnd (label) 结束具有指定标签的探查器
time (label) 启动具有指定标签的计时器,计时器会一直运行到你调用timeEnd()为止
timeEnd (label) 结束具有指定标签的计时器,并在控制台中显示过去的时间
timeline (label) 启动具有指定标签的时间线,时间线会一直运行到你调用timelineEnd()为止
timelineEnd (label) 结束具有指定标签的时间线
timeStamp (label) 当你记录时,给时间线添加一个时间戳事件
trace() 打印一个堆栈跟踪
warn (object, [, object,...]) 抛出一个带有黄色图标的警告,其他和log()相似

在表2.1中所列的方法中,有几种方法接收了如(object, [, object, ...])形式的参数。第一个参数可以是一个带格式转换字符的字符串,格式转换字符的种类在log (object, [, object,...])方法的描述中列举出来了。浏览器会使用接下来的参数来替换这些格式转换字符,这同C语言的printf()函数类似。例如,你可以在Snail Bait的loseLife()方法中添加一个日志声明,如下所示:

Snail Bait使用lives属性记录剩余生命的数量。前面对console.log()函数的调用会替换该值,也包括“Snail Bait”,按照格式转换字符出现的顺序来替换。
然而,一些控制台方法不会处理格式信息,其中的两个对于游戏开发人员很有价值:prof?ile()和prof?ileEnd()。这两个方法可以让你开始和结束调试,相对来说,可以让你更精确地控制调试过程,而不是通过暴力点击浏览器的状态栏按钮来控制。

在线控制台API指南

读者可以在网站https://developers.google.com/chrome-developer-tools/docs/console-api上找到Chrome控制台API在线参考书。

无文档记载的方法

在本书付印之际,timeline()和timelineEnd()控制台函数在2013年底被加入控制台,但没有文档记载。关于如何使用这些方法请阅读2.14节。
2.1.2 Chrome Canary的帧速率计数器
在上一节中,我们讨论了控制台在监控帧频方面,有时会比调试器更加有效。实际中,调试器和控制台都不是有效监控帧频的方法。前者会给出没有意义的结果,而后者会降低性能,进而影响游戏的帧频。
你可以使用Chrome Canary帧频计数器代替控制台或者调试器来监控帧频,如图2.2所示。
帧频计数器默认情况下并未启用。为了启用它,可以在Chrome Canary地址栏中敲入chrome://f?lags,启用FPS计数器,如图2.3所示。

图2.2 Chrome Canary帧频计数器


a5146472745ca74562856934926c1442d7a30d04

图2.3 启用Chrome Canary帧频计数器


b0eff59614679c50a782012f1267f8800d26c998
我们将在下一章实现一个帧频计数器。
Chrome Canary

Chrome Canary就像是来自于煤矿的金丝雀一样,包含很多特征,而且一些将被整合到Chrome浏览器中,Chrome Canary的下载地址依赖于你的硬件以及语言类型。在谷歌搜索引擎中输入“Chrome Canary”可以找到合适的链接地址。
2.1.3 调试
很难想象在没有一个合适的调试器的情况下写代码,更不用说写游戏了。所有主流浏览器厂商都会提供调试器,而且可以很容易就识别出来,通过设置断点,点击恢复按钮,就可以进行步进执行、顺序执行和跳出函数的操作了。你还可以观察表达式,并查看调用堆栈,正如你在图2.4底部的截图中看到的那样。

图2.4 Chrome浏览器中的条件断点


803b42e2b65e82d58d845ac039e9dacf9124f4d0

如果利用好条件断点的优势,你的创造力会在调试中得到提升,而几乎所有主流浏览器都支持条件断点。取代通过遍历对象集合来寻找特殊的条件,你可以设置一个条件驱动的断点。例如,图2.4显示了一个条件断点,这个断点只有在sprite对象的类型是runner时才被执行。

在Chrome中设置条件断点

1.?在需要的代码行点击鼠标右键弹出断点菜单。
2.?在弹出的菜单里选择“Add Conditional Breakpoint”。
3.?在随后的对话框中键入表达式,并按回车键。

在Chrome浏览器中实时编辑JavaScript代码

你可以使用Chrome实时编辑游戏的JavaScript代码。在调试时,简单地改变代码,并使用标准保存按键,例如Windows系列操作系统中的CTRL+S,保存代码。你对代码的任何改变都会持续到下一次你重新加载页面之前。在本书完成时,Chrome浏览器是主流浏览器中唯一可以让你实时编辑JavaScript代码的浏览器,其他浏览器(如Firefox)也可以实现相同的功能。

debugger;声明语句

除了点击界面,你也可以在Chrome调试器中设置断点,只需要在你的代码里添加一个声明语句:“debugger;”即可。
2.1.4 时间线
如果你的目标仅仅是完成一款类似于“hangman”的简单游戏,那么你选错书了,因为你根本不需要担心游戏性能。如果你是为了完成一款在每个动画帧中都需要操作几十个sprite对象的视频游戏,你就需要确保在整个游戏开发过程中能够监控性能。时间线和探查器是两个有用的用于监控游戏性能的工具。
你可以通过时间线来实时监控事件、帧速率及内存的使用情况。图2.5显示了最终版本的Snail Bait游戏的帧速率。
要开始一个时间线,你只需点击图2.5左上方的填充圆圈,使圆圈变成红色。要停止时间线,点击红色圆圈,使其恢复原来的颜色。
当你想大概了解游戏的性能时,通过点击鼠标启动和停止时间线是合适的。例如,在
图2.6中,玩家可以在运行游戏的同时观察时间线,当玩家也是游戏开发人员时,这个方法很有用,因为这样可以及时发现性能瓶颈。
点击鼠标开始和停止时间线是一个相当笨拙的方法。通常来说,使用编程的方式开始和停止时间线要好一些。你可以使用Chrome浏览器控制台的timeline()和timelineEnd()函数来实现,如图2.7所示。
Chrome浏览器允许你实时编辑JavaScript代码,如图2.7所示。顶部截图中高亮的代码行是在游戏开始运行时加入到Chrome浏览器编辑器中的。文件名旁边的星号表示资源已经被临时修改过了。
新增加的代码行开始时间线使用标识符“countdown --> explosion”。Chrome浏览器在时间线开始或者停止时将这个标识符消息发向控制台并打印。

图2.5 显示帧速率的时间线


c4628d509cc8654705e570194665d79ff4dee4ca

图2.6 游戏运行时的时间线


bff863529ca540d2a154254fbe961473abafdc6f

图2.7底部截图显示了添加在Chrome浏览器编辑器中的第2行代码,用于结束“count-down --> explosion”时间线。截图也显示了在编辑器中保存更改后内容的效果,Chrome浏览器会输出一个消息到控制台,并改变编辑器的背景颜色,在文件名旁边增加一个信息图标,同时控制台发出新信息。

图2.7 用编程方式实现开始和停止时间线


58a019b12f471f1a21d305aea623dec762ad2ccc

图2.7所示调用的timeline()和timelineEnd()放在了合适的位置上。当暂停中的游戏,在3秒之后恢复时,时间线开始;当sprite对象(通常是跑步小人)爆炸时,时间线停止。3秒短暂运行的时间线结果如图2.10所示。
Chrome浏览器在图2.8顶部截图的窗口顶部显示了时间线。时间线下面是一系列发生在时间线范围内的事件(整个时间线在顶部截图中被标示出来)。你可以通过拖动范围手柄或者点击时间线来改变选择的范围,如图2.8的底部截图所示。当你修改范围时,事件列表更新为仅显示那个区间里的事件。
如果你将鼠标放在代表事件的矩形条上,如同图2.8底部截图所示,Chrome浏览器将会显示关于该事件的一个提示框。
你可以使用两种方式来过滤事件,如图2.9的顶部截图所示。你想看哪个事件类型,通过点击合适的复选框来进行加载,包括Loading、Scripting、Rendering,以及Painting事件;使用下拉菜单中的持续时间选项来过滤事件,如图2.9顶部截图所示。过滤事件不会影响时间线本身。

图2.8 改变条形图之间的范围


f09914057723352c7bc2746d1c66b920d7cf5469

图2.9 通过时间开销来过滤事件


44c6e388c032e21ef1fbcc886b8769de5305db57

过滤掉超过15毫秒的事件,对于游戏开发人员来说是合理的,因为在每秒60帧的帧率下,每一帧大约持续16.66毫秒。如果没有时间开销超过15毫秒的事件,如图2.9所示,你的游戏性能将会非常好。
现在,你已经知道如何开始和停止时间线,如何关联动画帧和时间,以及如何过滤事件,接下来,让我们关注一下时间线本身,如图2.10所示


d43fef64218fe5ba6d94f220a9a2d832d1f1bcec


时间线上的条形图代表单个动画帧,条形图的高度代表该帧的时间开销。较长的时间开销对应着较高的条形图,即较慢的帧速率,这也是为什么在
图2.10中,30fps的帧速率会显示在60fps帧速率上面。
每一个条形图都是根据Loading、Scripting、Rendering和Painting事件在一个动画帧之内所花费的时间来确定颜色的。没有颜色的区域代表空闲时间。图2.10是最终版本的Snail Bait游戏运行的一个时间线,可以看出游戏大部分时间什么事情都没有做。我们将在下一章里看到,Snail Bail游戏的空闲时间到底有多少。
从一开始就持续地监控性能
定位并修复性能瓶颈的容易程度,和用于监控游戏性能所花费的时间成反比。
2.1.5 Profiling
JavaScript prof?iling是另一个被所有主流浏览器支持的特性。它可以精确地让你看到时间花费在哪里。图2.11显示了在最终版本的Snail Bait游戏运行时,Chrome浏览器的prof?iler。Self列显示了单个函数花费的时间,Total列显示了单个函数,以及该函数中调用的其他函数花费的时间总和。
正如你在图2.11看到的那样,Snail Bait游戏性能下降最集中的地方是排烟孔粒子系统。每一个排烟孔粒子系统包含20个sprite对象,它们的artist对象将它们绘制成半透明的、慢慢消散的填充圆。
你也可以在图2.11中看到,在截图所示的时间段内,Snail Bait游戏在80%的时间里什么也没做,这令人印象深刻,但很有可能是因为Chrome浏览器的硬件加速功能加速了canvas元素的绘制。
现在你已经对浏览器开发者工具有了深层次的理解,现在让我们来看看,如何才能获取免费可用的资源,诸如图形、音效和音乐等。
在Chrome中开始和停止profiling

在Chrome中,你可以通过点击浏览器状态栏左侧的按钮来开始和停止prof?iling。为了更精确地定位性能瓶颈,你也可以像2.1.1节中介绍的那样,在代码中特定位置通过使用console.prof?ile()和console.prof?ileEnd()来开始和停止prof?iling。

图2.11 Chrome浏览器中的prof?iling


bfde214de32d6586afce08cc8a44e1537829467b
相关实践学习
日志服务之使用Nginx模式采集日志
本文介绍如何通过日志服务控制台创建Nginx模式的Logtail配置快速采集Nginx日志并进行多维度分析。
相关文章
|
移动开发 前端开发 Shell
《HTML5 Canvas核心技术 图形、动画与游戏开发》 读书笔记
《HTML5 Canvas核心技术 图形、动画与游戏开发》 读书笔记
|
移动开发 监控 前端开发
【phaser】快速实现HTML5 2d小游戏
使用 js 的 游戏框架 phaser 实现 html 小游戏
378 0
【phaser】快速实现HTML5 2d小游戏
|
JavaScript 前端开发 程序员
好程序员分享大势所趋 HTML5成Web开发者最关心的技术
  好程序员分享大势所趋 HTML5成Web开发者最关心的技术,最近,在Stack Exchange上出现了一个比较热门的问题:Web开发者最头疼的问题是什么?结果并不是大家通常认为的兼容性问题,而是关于HTML5。
1279 0
|
JSON 移动开发 前端开发
基于 HTML5 Canvas 的简易 2D 3D 编辑器
不管在任何领域,只要能让非程序员能通过拖拽来实现 2D 和 3D 的设计图就是很牛的,今天我们不需要 3dMaxs 等设计软件,直接用 HT 就能自己写出一个 2D 3D 编辑器,实现这个功能我觉得成就感还是爆棚的,哈哈!只要你会想,能做,就能根据这个编辑器延展成 big thing! 本例地址:http://www.
1324 0
|
移动开发 前端开发 HTML5
基于HTML5 Canvas 点击添加 2D 3D 机柜模型
今天又返回好好地消化了一下我们的数据容器 DataModel,这里给新手做一个典型的数据模型事件处理的例子作为参考。这个例子看起来很简单,实际上结合了数据模型中非常重要的三个事件处理的部分:属性变化事件监听、选中变化事件监听以及数据模型变化事件监听。
1263 0
|
移动开发 HTML5
基于HTML5的WebGL实现的2D3D迷宫小游戏
为了实现一个基于HTML5的场景小游戏,我采用了HT for Web来实现,短短200行代码,我就能实现用“第一人称”来操作前进后退上下左右,并且实现了碰撞检测。 先来看下实现的效果: http://hightopo.
1277 0