/// /* loader.js:负责对资源的加载 */ 'use strict'; function loader() { this._init(); } loader.prototype._init = function () {}; ////// 设置加载进度条进度 ////// loader.prototype._setStartProgressVal = function (val) { core.dom.startTopProgress.style.width = val + '%'; }; ////// 设置加载进度条提示文字 ////// loader.prototype._setStartLoadTipText = function (text) { core.dom.startTopLoadTips.innerText = text; }; loader.prototype._load = function (callback) { if (main.useCompress) { this._load_async(callback); } else { this._load_sync(callback); } }; loader.prototype._load_sync = function (callback) { this._loadAnimates_sync(); this._loadMusic_sync(); core.loader._loadMaterials_sync(function () { core.loader._loadExtraImages_sync(function () { core.loader._loadAutotiles_sync(function () { core.loader._loadTilesets_sync(callback); }); }); }); }; loader.prototype._load_async = function (callback) { core.loader._setStartLoadTipText('正在加载资源文件...'); var all = {}; var _makeOnProgress = function (name) { if (!all[name]) all[name] = { loaded: 0, total: 0, finished: false }; return function (loaded, total) { all[name].loaded = loaded; all[name].total = total; var allLoaded = 0, allTotal = 0; for (var one in all) { allLoaded += all[one].loaded; allTotal += all[one].total; } if (allTotal > 0) { if (allLoaded == allTotal) { core.loader._setStartLoadTipText( '正在处理资源文件... 请稍候...' ); } else { core.loader._setStartLoadTipText( '正在加载资源文件... ' + core.formatSize(allLoaded) + ' / ' + core.formatSize(allTotal) + ' (' + ((allLoaded / allTotal) * 100).toFixed(2) + '%)' ); } core.loader._setStartProgressVal((allLoaded / allTotal) * 100); } }; }; var _makeOnFinished = function (name) { return function () { setTimeout(function () { all[name].finished = true; for (var one in all) { if (!all[one].finished) return; } callback(); }); }; }; this._loadAnimates_async( _makeOnProgress('animates'), _makeOnFinished('animates') ); this._loadMusic_async(_makeOnProgress('sounds'), _makeOnFinished('sounds')); this._loadMaterials_async( _makeOnProgress('materials'), _makeOnFinished('materials') ); this._loadExtraImages_async( _makeOnProgress('images'), _makeOnFinished('images') ); this._loadAutotiles_async( _makeOnProgress('autotiles'), _makeOnFinished('autotiles') ); this._loadTilesets_async( _makeOnProgress('tilesets'), _makeOnFinished('tilesets') ); }; // ----- 加载资源文件 ------ // loader.prototype._loadMaterials_sync = function (callback) { this._setStartLoadTipText('正在加载资源文件...'); this.loadImages( 'materials', core.materials, core.material.images, function () { core.loader._loadMaterials_afterLoad(); callback(); } ); }; loader.prototype._loadMaterials_async = function (onprogress, onfinished) { this.loadImagesFromZip( 'project/materials/materials.h5data', core.materials, core.material.images, onprogress, function () { core.loader._loadMaterials_afterLoad(); onfinished(); } ); }; loader.prototype._loadMaterials_afterLoad = function () { var images = core.splitImage(core.material.images['icons']); for (var key in core.statusBar.icons) { if (typeof core.statusBar.icons[key] == 'number') { core.statusBar.icons[key] = images[core.statusBar.icons[key]]; if (core.statusBar.image[key] != null) core.statusBar.image[key].src = core.statusBar.icons[key].src; } } }; // ------ 加载使用的图片 ------ // loader.prototype._loadExtraImages_sync = function (callback) { core.material.images.images = {}; this._setStartLoadTipText('正在加载图片文件...'); core.loadImages( 'images', core.images, core.material.images.images, callback ); }; loader.prototype._loadExtraImages_async = function (onprogress, onfinished) { core.material.images.images = {}; var images = core.images; // Check .gif var gifs = images.filter(function (name) { return name.toLowerCase().endsWith('.gif'); }); images = images.filter(function (name) { return !name.toLowerCase().endsWith('.gif'); }); this.loadImagesFromZip( 'project/images/images.h5data', images, core.material.images.images, onprogress, onfinished ); // gif没有被压缩在zip中,延迟加载... gifs.forEach(function (gif) { this.loadImage('images', gif, function (id, image) { if (image != null) { core.material.images.images[gif] = image; } }); }, this); }; // ------ 加载自动元件 ------ // loader.prototype._loadAutotiles_sync = function (callback) { core.material.images.autotile = {}; var keys = Object.keys(core.material.icons.autotile); var autotiles = {}; this._setStartLoadTipText('正在加载自动元件...'); this.loadImages('autotiles', keys, autotiles, function () { core.loader._loadAutotiles_afterLoad(keys, autotiles); callback(); }); }; loader.prototype._loadAutotiles_async = function (onprogress, onfinished) { core.material.images.autotile = {}; var keys = Object.keys(core.material.icons.autotile); var autotiles = {}; this.loadImagesFromZip( 'project/autotiles/autotiles.h5data', keys, autotiles, onprogress, function () { core.loader._loadAutotiles_afterLoad(keys, autotiles); onfinished(); } ); }; loader.prototype._loadAutotiles_afterLoad = function (keys, autotiles) { // autotile需要保证顺序 keys.forEach(function (v) { core.material.images.autotile[v] = autotiles[v]; }); setTimeout(function () { core.maps._makeAutotileEdges(); }); }; // ------ 加载额外素材 ------ // loader.prototype._loadTilesets_sync = function (callback) { core.material.images.tilesets = {}; this._setStartLoadTipText('正在加载额外素材...'); this.loadImages( 'tilesets', core.tilesets, core.material.images.tilesets, function () { callback(); } ); }; loader.prototype._loadTilesets_async = function (onprogress, onfinished) { core.material.images.tilesets = {}; this.loadImagesFromZip( 'project/tilesets/tilesets.h5data', core.tilesets, core.material.images.tilesets, onprogress, function () { onfinished(); } ); }; // ------ 实际加载一系列图片 ------ // loader.prototype.loadImages = function (dir, names, toSave, callback) { if (!names || names.length == 0) { if (callback) callback(); return; } var items = 0; for (var i = 0; i < names.length; i++) { this.loadImage(dir, names[i], function (id, image) { core.loader._setStartLoadTipText('正在加载图片 ' + id + '...'); if (toSave[id] !== undefined) { if (image != null) toSave[id] = image; return; } toSave[id] = image; items++; core.loader._setStartProgressVal(items * (100 / names.length)); if (items == names.length) { if (callback) callback(); } }); } }; loader.prototype.loadImage = function (dir, imgName, callback) { try { var name = imgName; if (name.indexOf('.') < 0) name = name + '.png'; var image = new Image(); image.onload = function () { image.setAttribute('_width', image.width); image.setAttribute('_height', image.height); callback(imgName, image); }; image.onerror = function () { callback(imgName, null); }; image.src = 'project/' + dir + '/' + name + '?v=' + main.version; if (name.endsWith('.gif')) callback(imgName, null); } catch (e) { console.error(e); } }; // ------ 从zip中加载一系列图片 ------ // loader.prototype.loadImagesFromZip = function ( url, names, toSave, onprogress, onfinished ) { if (!names || names.length == 0) { if (onfinished) onfinished(); return; } core.unzip( url + '?v=' + main.version, function (data) { var cnt = 1; names.forEach(function (name) { var imgName = name; if (imgName.indexOf('.') < 0) imgName += '.png'; if (imgName in data) { var img = new Image(); var url = URL.createObjectURL(data[imgName]); cnt++; img.onload = function () { cnt--; URL.revokeObjectURL(url); img.setAttribute('_width', img.width); img.setAttribute('_height', img.height); if (cnt == 0 && onfinished) onfinished(); }; img.src = url; toSave[name] = img; } }); cnt--; if (cnt == 0 && onfinished) onfinished(); }, null, false, onprogress ); }; // ------ 加载动画文件 ------ // loader.prototype._loadAnimates_sync = function () { this._setStartLoadTipText('正在加载动画文件...'); if (main.supportBunch) { if (core.animates.length > 0) { core.http( 'GET', '/all/__all_animates__?v=' + main.version + '&id=' + core.animates.join(','), null, function (content) { var u = content.split('@@@~~~###~~~@@@'); for (var i = 0; i < core.animates.length; ++i) { if (u[i] != '') { core.material.animates[core.animates[i]] = core.loader._loadAnimate(u[i]); } else { console.error( '无法找到动画文件' + core.animates[i] + '!' ); } } }, 'text/plain; charset=x-user-defined' ); } return; } core.animates.forEach(function (t) { core.http( 'GET', 'project/animates/' + t + '.animate?v=' + main.version, null, function (content) { core.material.animates[t] = core.loader._loadAnimate(content); }, function (e) { console.error(e); core.material.animates[t] = null; }, 'text/plain; charset=x-user-defined' ); }); }; loader.prototype._loadAnimates_async = function (onprogress, onfinished) { core.unzip( 'project/animates/animates.h5data?v=' + main.version, function (animates) { for (var name in animates) { if (name.endsWith('.animate')) { var t = name.substring(0, name.length - 8); if (core.animates.indexOf(t) >= 0) core.material.animates[t] = core.loader._loadAnimate( animates[name] ); } } onfinished(); }, null, true, onprogress ); }; loader.prototype._loadAnimate = function (content) { try { content = JSON.parse(content); var data = {}; data.ratio = content.ratio; data.se = content.se; data.pitch = content.pitch; data.images = []; content.bitmaps.forEach(function (t2) { if (!t2) { data.images.push(null); } else { try { var image = new Image(); image.src = t2; data.images.push(image); } catch (e) { console.error(e); data.images.push(null); } } }); data.frame = content.frame_max; data.frames = []; content.frames.forEach(function (t2) { var info = []; t2.forEach(function (t3) { info.push({ index: t3[0], x: t3[1], y: t3[2], zoom: t3[3], opacity: t3[4], mirror: t3[5] || 0, angle: t3[6] || 0 }); }); data.frames.push(info); }); return data; } catch (e) { console.error(e); return null; } }; // ------ 加载音乐和音效 ------ // loader.prototype._loadMusic_sync = function () { this._setStartLoadTipText('正在加载音效文件...'); core.bgms.forEach(function (t) { core.loader.loadOneMusic(t); }); core.sounds.forEach(function (t) { core.loader.loadOneSound(t); }); // 直接开始播放 core.playBgm(main.startBgm); }; loader.prototype._loadMusic_async = function (onprogress, onfinished) { core.bgms.forEach(function (t) { core.loader.loadOneMusic(t); }); core.unzip( 'project/sounds/sounds.h5data?v=' + main.version, function (data) { // 延迟解析 setTimeout(function () { for (var name in data) { if (core.sounds.indexOf(name) >= 0) { core.loader._loadOneSound_decodeData(name, data[name]); } } }); onfinished(); }, null, false, onprogress ); // 直接开始播放 core.playBgm(main.startBgm); }; loader.prototype.loadOneMusic = function (name) { var music = new Audio(); music.preload = 'none'; if (main.bgmRemote) music.src = main.bgmRemoteRoot + core.firstData.name + '/' + name; else music.src = 'project/bgms/' + name; music.loop = 'loop'; core.material.bgms[name] = music; }; loader.prototype.loadOneSound = function (name) { core.http( 'GET', 'project/sounds/' + name + '?v=' + main.version, null, function (data) { core.loader._loadOneSound_decodeData(name, data); }, function (e) { console.error(e); core.material.sounds[name] = null; }, null, 'arraybuffer' ); }; loader.prototype._loadOneSound_decodeData = function (name, data) { if (data instanceof Blob) { var blobReader = new zip.BlobReader(data); blobReader.init(function () { blobReader.readUint8Array(0, blobReader.size, function (uint8) { core.loader._loadOneSound_decodeData(name, uint8.buffer); }); }); return; } try { core.musicStatus.audioContext.decodeAudioData( data, function (buffer) { core.material.sounds[name] = buffer; }, function (e) { console.error(e); core.material.sounds[name] = null; } ); } catch (e) { console.error(e); core.material.sounds[name] = null; } }; loader.prototype.loadBgm = function (name) { name = core.getMappedName(name); if (!core.material.bgms[name]) return; // 如果没开启音乐,则不预加载 if (!core.musicStatus.bgmStatus) return; // 是否已经预加载过 var index = core.musicStatus.cachedBgms.indexOf(name); if (index >= 0) { core.musicStatus.cachedBgms.splice(index, 1); } else { // 预加载BGM this._preloadBgm(core.material.bgms[name]); // core.material.bgms[name].load(); // 清理尾巴 if ( core.musicStatus.cachedBgms.length == core.musicStatus.cachedBgmCount ) { this.freeBgm(core.musicStatus.cachedBgms.pop()); } } // 移动到缓存最前方 core.musicStatus.cachedBgms.unshift(name); }; loader.prototype._preloadBgm = function (bgm) { bgm.volume = 0; bgm.play(); }; loader.prototype.freeBgm = function (name) { name = core.getMappedName(name); if (!core.material.bgms[name]) return; // 从cachedBgms中删除 core.musicStatus.cachedBgms = core.musicStatus.cachedBgms.filter(function ( t ) { return t != name; }); // 清掉缓存 core.material.bgms[name].removeAttribute('src'); core.material.bgms[name].load(); core.material.bgms[name] = null; if (name == core.musicStatus.playingBgm) { core.musicStatus.playingBgm = null; } // 三秒后重新加载 setTimeout(function () { core.loader.loadOneMusic(name); }, 3000); };