這里說的是在需要的使用加載圖片,比如游戲中的某個關卡的圖片,不用在游戲一開始就加載(萬一用戶玩不到那關,豈不是很冤,流量費了那么多),否則載入速度也慢。這種方式加載資源要用到cc.loader官方文檔上有介紹(http://www.cocos2d-x.org/docs/manual/framework/html5/v3/cc-loader/zh),主要有
- loadJs
- loadJsWithImg
- loadTxt
- loadBinary
- loadImg
- loadJson
文檔給出了一個例子如下:
cc.loader.loadTxt("res/a.txt", function(err, data){ if(err) return console.log("load failed"); //success });
可見loadTxt中的第二個是一個回調函數(等待ajax數據返回后調用),文檔中對啟動load系列函數參數都沒有說,其實都是如此,回調函數第一個參數表示是否有錯誤發生(成功的話是null),第二個參數data表示本次請求返回的數據(不同load系列函數會對返回數據進行一個解析,就是解析的結果了,比如loadImg)。其實第一次看文檔的時候沒看到這段示例代碼,全是回調函數只有一個參數的示例代碼,當時我就想啊,尼瑪這異步調用數據怎么取啊?文檔也不說一聲,只好去看源碼,開源的好處就是這樣,以下是loadBinary的代碼:
/** * Load binary data by url. * @function * @param {String} url * @param {Function} [cb] */ cc.loader.loadBinary = function (url, cb) { var self = this; var xhr = this.getXMLHttpRequest(), errInfo = "load " + url + " failed!"; xhr.open("GET", url, true); if (/msie/i.test(navigator.userAgent) && !/opera/i.test(navigator.userAgent)) { // IE-specific logic here xhr.setRequestHeader("Accept-Charset", "x-user-defined"); xhr.onreadystatechange = function () { if (xhr.readyState == 4 && xhr.status == 200) { var fileContents = cc._convertResponseBodyToText(xhr["responseBody"]); cb(null, self._str2Uint8Array(fileContents)); } else cb(errInfo); }; } else { if (xhr.overrideMimeType) xhr.overrideMimeType("text\/plain; charset=x-user-defined"); xhr.onload = function () { xhr.readyState == 4 && xhr.status == 200 ? cb(null, self._str2Uint8Array(xhr.responseText)) : cb(errInfo); }; } xhr.send(null); }; cc.loader._str2Uint8Array = function (strData) { if (!strData) return null; var arrData = new Uint8Array(strData.length); for (var i = 0; i < strData.length; i++) { arrData[i] = strData.charCodeAt(i) & 0xff; } return arrData; };
可以看到這里對回調函數的調用:
xhr.readyState == 4 && xhr.status == 200 ? cb(null, self._str2Uint8Array(xhr.responseText)) : cb(errInfo);
再來給出一個自己的使用實例(加載游戲關卡的參數和圖片):
/* helper function to fetch level data using ajax */ var fetch_level = function(level, callback, callback_data) { cc.loader.loadJson("api/level/" + level, function (x, new_level_data) { cc.log("fetch level json data:", new_level_data); current_level_data = new_level_data; cc.loader.loadImg(current_level_data.photo, function (x, img) { cc.log("fetch level photo img:", img); current_level_data.img = img; if (!!callback) { callback(callback_data); } }) }) };