您好,欢迎来到三六零分类信息网!老站,搜索引擎当天收录,欢迎发信息
免费发信息
三六零分类信息网 > 本溪分类信息网,免费分类信息发布

HTML5游戏开发 之 资源加载篇(1)

2024/3/23 13:11:34发布45次查看
一) 背景介绍
利用html5进行游戏开发,相比于其他语言例如java、c++等,有很多不同,其中一个就是资源加载。本文主要对html5游戏资源加载的问题、原因以及解决方案,进行一些分析,试图解释以下问题:
如何加载不同类型的资源
如何进行批量加载
如何显示加载的进度条
如何存放资源
在文章的最后,也会列举一些游戏引擎的实现方案,供大家参考。通过此篇文章,希望可以让读者对于资源加载的技术有一个全面的了解。
二) 需要考虑的资源类型
一般游戏需要的资源,主要包括图片、音频、视频以及二进制数据文件。如果是3d游戏,还会需要一些模型文件,例如3dmax导出的obj文件。通常的情况下,这些资源文件,少则几十兆,多则几个g。对于很多客户端游戏,这个并不是特别大的问题。通常,它们可以将这些资源打在安装包中,随着安装的过程,一次性的存放在本地。
但是,web游戏面临的情况比较复杂,主要有两个原因:
因为所有的资源都放在云端的服务器上。
浏览器为了优化网页的渲染,对于图片、音频等资源的加载,通常都是异步的。
大家可以回想一下,在打开某些网页的时候,偶然也会看到,即使在网页显示完以后,总有一两个图片的位置是空白的,大约几秒钟以后,这些图片往往又在不经意中显示了出来。
除了图片、音频等二进制文件,还有一类比较特殊的文件,就是javascript文件。尤其是游戏逻辑比较庞大时,javascript文件也可能有几百k,甚至好几兆。如果仅是根据文件的大小,这类文件似乎可以忽略不计。但是由于浏览器对于javascript文件的处理是同步的,往往这些文件会成为性能的瓶颈。
举个例子,当浏览器在解析网页的过程中,碰到了碰到了3f1c4e4b6b16bbbd69b2ee476dc4f83a标签,它会立即转入对3f1c4e4b6b16bbbd69b2ee476dc4f83a标签的解析,同时阻塞的等待解析的完成。如果3f1c4e4b6b16bbbd69b2ee476dc4f83a标签,带有src属性,浏览器同样是阻塞的等待下载完成。所以,有时我们抱怨网络太慢,其实是委屈了运营商,很多时候,是脚本执行占用了太长时间,阻塞了网页的显示。
对于javascript脚本的加载,首先要解决下载的问题,通常是伪装javascript文件成资源文件,比如将javascript中的脚本,作为整个字符串,放入一个json文件,充分发挥浏览器异步下载的能力。其次要缩短每次脚本文件解析的时间,这个最重要的就是按需“执行”,也就说要将脚本模块化。模块化是比较容易理解的,就是模仿面向对象的编程方法,将不同功能的函数放在不同的文件中。
但是,这样做带来另外一个问题,因为javascript没有提供类似于面向对象语言中的模块继承功能,例如,在java中,java虚拟机会自动的将该文件依赖的其他类,导入运行时环境。为了实现模块化,也需要为javascript模拟一套类似的功能,幸运的是,目前已经有许多成熟的类库,例如requirejs。因为javascript文件的加载不属于游戏开发的专有问题,在本文中不做详细介绍。
三) 如何加载不同类型的资源
2.1 通过浏览器内置对象的回调接口,实现资源加载
对于图片文件的加载,浏览器提供了方便的回调接口,比较容易实现,如下:
var image = new image(); image.addeventlistener(“success”, function(e) { // do stuff with the image ); image.src = "/some/image.png";
但是比较麻烦的是,html并没有提供对等的audio、video对象。对于audio,虽然web audio api可以提供类似的功能,但是明显学习门槛高了一些。对于video,目前还没有可以有效的方式,可以模拟类似的功能。对于文本、二进制等文件,更是比较麻烦。
2.2 通过ajax请求,实现资源加载
利用ajax对http地址进行请求的能力,相信大家没有任何质疑。但是,在ajax请求到相关资源以后,如何将资源转化为相应的图片、音频等对象,好像又产生了一些困难。
但是幸运的是,目前ajax推出了新的标准,可以支持对二进制数据的提取。再辅助目前新的数据存储方式,比如blob、filesystem等,可以轻松的解决这个问题。
利用blob将资源转换相应的对象,代码片段如下,更多代码请参考“new trics in xhr”
window.url = window.url || window.webkiturl; // take care of vendor prefixes.var xhr = new xmlhttprequest(); xhr.open('get', '/path/to/image.png', true); xhr.responsetype = 'blob'; xhr.onload = function(e) { if (this.status == 200) { var blob = this.response; var img = document.createelement('img'); img.onload = function(e) { window.url.revokeobjecturl(img.src); // clean up after yourself. }; img.src = window.url.createobjecturl(blob); document.body.appendchild(img); ... } }; xhr.send();
利用filesystem,将资源转换为相应的对象,代码片段如下,更多完成代码,请参考“loading large assets in modern html5 games”
var xhr = new xmlhttprequest(); xhr.open('get', url, true); xhr.responsetype = 'arraybuffer'; xhr.addeventlistener('load', function() { createdir_(root, dirname_(key).split('/'), function(dir) { dir.getfile(basename_(key), {create: true}, function(fileentry) { fileentry.createwriter(function(writer) { writer.onwrite = function(e) { // save this file in the path to url lookup table. lookuptable[key] = fileentry.tourl(); callback(); }; writer.onerror = failcallback; var bb = new blobbuilder(); bb.append(xhr.response); writer.write(bb.getblob()); }, failcallback); }, failcallback); }); }); xhr.addeventlistener('error', failcallback); xhr.send();
上面两种方式,都是在获得资源后,为资源生成一个url地址对象,在将此地址赋给相关的对象。
2.3 通过创建元素的方式,获得资源
于第二种方式,相信不少读者担心不同浏览器的兼容性,毕竟里面利用了大量的html5新属性,而这些属性,很多属于刚刚发布的特性,每个浏览器支持的情况不太一样。所以,还需要一种可以兼容所有浏览器的方式。通过创建元素的方式,相对比较保险。参考如下代码:
var res = document.createelement(“image/audio/xxx”) res.src = “http://www.yourdomain.com”
但是这样的代码,也碰到了和第一个方法同样的问题,不是所有的元素都提供了onload函数。对于image,处理相对简单。但是对于audio/vido,只能利用canplaythrough等函数做一些大约估计。
总之,为了做好资源下载,可能不能完全依赖某一类方法,最有可能的方式是根据每种方法的优缺点,根据具体原因进行选择。在一些比较成熟的游戏引擎和类库的实现中,也确实是融合了这三种不同的方法。
以上就是html5游戏开发 之 资源加载篇(1)的内容。
本溪分类信息网,免费分类信息发布

VIP推荐

免费发布信息,免费发布B2B信息网站平台 - 三六零分类信息网 沪ICP备09012988号-2
企业名录