本节书摘来异步社区《html5游戏编程核心技术与实战》一书中的第1章,第1.2节,作者: 向峰 责编: 杨海玲,更多章节内容可以访问云栖社区“异步社区”公众号查看。
html5游戏编程核心技术与实战
准备好html5开发工具之后,我都迫不急待地想看看html5给我们带来了哪些让人激动不已的新特性,相信,你也会和我一样,对它感到兴奋。由于html5新增加了很多元素,这里,我们重点简单介绍一下在游戏中会使用到的一些元素,在介绍每一个新的元素时,我都会列举一些小的例子。现在假定读者有一定的html以及javascript方面的知识,如果您对这些代码完全不清楚,没关系,后面的章节中会详细地解说。目前,我们只需要知道html5能做什么就足够了。
canvas是html5中一个非常重要的元素,canvas元素提供了硬件加速机制,能够让我们实现高效的绘图功能。第2章我们会详细介绍canvas功能,这里,我们先来领略一下canvas的魅力。
打开你的编辑工具,输入以下代码:
虽然有点长,但当你完成它的时候,我想,一定不会让你失望的,这是一个不错的开始,也许现在你可能还看不太懂,没关系,第2章就会对canvas元素进行详细介绍。以上代码通过canvas元素完成了一个在浏览器中使用的画板,可以通过chrome浏览器打开它,看到的效果如图1-9所示,你可以选择不同颜色的画笔在画板上进行涂鸦。

除了支持2d渲染技术外,canvas还提供了通过webgl的方式,利用硬件加速提供3d渲染技术。以下代码使用了开源的three.js的3d引擎,完成了一个简单的旋转方块,注意,该3d效果完全使用webgl技术,不需要安装任何插件。顺便说一下,three.js是一款完全免费使用的3d引擎,该引擎完全基于webgl编写,事实上webgl也是在canvas上进行渲染,目前对webgl支持比较好的浏览器有chrome、firefox以及safari等。
整个代码实现了一个绕y轴旋转的方块,最好使用chrome浏览器进行浏览,运行效果如图1-10所示。
当然,对于代码的细节暂时可以不用去关注,目前,我们只需要知道使用webgl能做什么就足够了,对于目前的html5来说,2d的游戏将会是比3d更好的选择。
正如我们所期待的一样,html5中增加了两个多媒体元素以及
<video></video>
比如,以下代码可以直接在浏览器中播放mp3音频文件。
在浏览器中可以看到一个带有简单控制面板的音频播放器,如图1-11所示。
html5提供了一组关于地理信息的api,通过这组api我们可以获取到客户端所在的经度和纬度,利用这些信息可以向这个坐标附近的区域提供服务。这些服务一般指的是基于位置的服务(lbs),lbs能够广泛支持需要动态地理空间信息的应用,从寻找旅馆、急救服务到导航,从社交游戏到生活服务,几乎可以覆盖生活中的所有方面。常见的一些lbs的应用有:位置信息查询、急救服务、道路辅助与导航、社交游戏等。
借助html提供的geolocation api功能,很容易获取到用户当前的位置,结合这组api,我们可以编写基于lbs的社交类游戏。
同样地,我们给出一段简单的代码,可以获取用户所在的位置信息。
代码绑定一个“获取位置信息”的按钮,单击按钮将会调用issupportgeo方法检测浏览器是否支持地理信息,如果支持的话就调用getcurrentposition获取当前设备的地理信息。需要注意的是,第一次访问地理信息的时候由于个人隐私的问题,浏览器会弹出一个窗口询问用户是否允许让浏览器访问自己的位置,用户可以选择接受或者拒绝,如果拒绝的话将会得到一个错误。
我们知道在传统的web应用程序开发过程中,当客户端和服务器进行数据交互时,远程服务器需要存储客户端的各种数据,如果需要在客户端保留数据,可以采用“cookie”的形式,但cookie的存储量很小,通常只有4 kb,而且安全性和使用性都还有所欠缺。为了能够满足于html5本地应用的迅速发展,弥补html在本地数据持久化的弱势,html5推出了新的本地存储规范,提供了容量更大、更安全和更易于使用的本地存储方案。
html5中使用web storage技术进行本地存储,能够在web客户端进行数据存储。web storage曾经属于html5的规范,目前已经被独立出来形成单独的规范体系。简单来说使用web本地存储类似于hashmap一样,采用键值对的形式保存数据,而且保存的数据会根据需要持久化在浏览器所在的客户端,具体来说web storage又可以分为以下两种。
localstorage。将数据保存在客户端本地的硬件设备(通常指硬盘,但也可以是其他硬件设备)中,即使浏览器被关闭了,该数据仍然存在,下次打开浏览器访问网站时仍然可以继续使用。
sessionstorage。将数据保存在session对象中。session对象就是会话对象,session中存储的数据独立于每个客户,该数据会随着浏览器的关闭而消失。
这两者的区别在于,sessionstorage为临时保存,而localstorage为永久保存。localstorage提供了5 mb的存储空间,而sessiongstorage甚至没有限制,取决于内存的大小。
对于这两种本地存储对象都可以使用以下方法进行数据存取。
setitem(key, value)。使用键值对的方式保存数据,key为键,value为值,键是一个字符串,而数据则可以是任何类型的javascript基本数据类型,包括字符串、boolean、整数和浮点数。需要注意的是,这些数据在存储时实际上是以字符串保存的。因此在访问数据时需要进行数据类型的转换,也可以直接用localstorage.key = value或者localstorage[key] = value的方式设置,对于复杂的数据类型,可以使用json格式的对象转换成字符串对象存储。
getitem(key)。根据key键值来获取数据,也可以直接用localstorage.key或者localstorage[key]获取,需要注意的是,这些数据在取出来时实际上是字符串。因此在访问数据时需要进行数据类型的转换。
例如,以下简单的代码用于记录用户访问页面的总次数:
上面代码中记录了用户访问页面次数,第一次访问时,获取的count为空,设置其为1,随后的访问中获取数据后通过number函数转成数字进行累加并重新设置到localstorage中。需要注意的是,即使关闭浏览器,下次打开时,数据依然存在,因为localstorage的数据实际上持久化在本地文件中。
一直以来,http的无状态性和单向性作为常用的应用已经足够,但还无法实现游戏中需要的实时双向通信技术,而html5中新增加的websocket通信元素则弥补了这一缺陷,使用新的web sockets技术对于实现高效的web网络游戏提供了基础。
我们可以使用以下代码连接支持web sockets协议的服务器端,并发送数据。
当然,需要注意的是,以上只是使用websocket元素的客户端代码,需要有支持websocket协议的服务器端支持,在本书的第5章会详细介绍使用websocket的客户端以及node.js的服务器端通信技术。
web worker技术填补了javascript中一直所缺少的多线程技术,之前的html中,进行dom元素渲染以及执行javascript脚本都是在单一的线程中执行,一旦在javascript中需要执行比较耗时间的操作,则会阻塞当前线程的执行。所带来的效果就是,当前的浏览器处于无响应状态,直到浏览器会弹出一个提示脚本运行时间过长的信息。这里,我们看一个简单的例子。
在该例子中,提供了一个通过级数获取圆周率的函数,参数n表示迭代次数,次数越高,计算越精确。然后提供一个按钮计算圆周率在文本框中显示,在浏览器中运行,我们发现当迭代次数很高的时候,计算量较大,在得到计算结果之前,按钮和文本框都是处于无法响应的状态,这也符合实际情况,因为此时dom元素的更新被大计算量的程序给阻塞了。如果使用web worker则不会出现此情况,我们可以把计算量大的工作放到一个单独的线程中运行,不会阻塞当前线程。
创建后台线程可以使用以下方式:
var worker = new worker(“worker.js”)
我们把计算工作放到worker.js文件中,前台可以通过postmessage方法发送消息给worker线程,请求worker进行工作,直到worker线程工作完毕返回结果。
对于前面计算pi的例子,我们可以修改如下,首先,创建worker.js文件,代码如下:
worker.js文件中定义了计算pi的函数,我们需要定义一个onmessage函数,当前台通过调用worker对象的postmessage方法时,该回调函数被响应。
然后,把显示结果的页面修改如下:
这里,首先创建了一个worker对象,然后在workder对象中注册一个onmessage回调函数。注意,这个回调函数和workder.js文件中的onmessage是不同的,这里的回调函数当woker.js文件中的onmessage函数执行完毕后响应,最后,调用worker对象的postmessage方法发送计算请求,此时,woker.js文件中的onmessage函数就会执行。
修改成worker版本后,你会发现,当单击按钮得到计算结果之前,按钮和文本框都是可以响应的,因为此时计算线程被独立出来了。