制作游戲時,如何管理游戲資源?
逐行注釋!
開發環境:
CocosCreator v2.3.1
node.js v10.16.0
vscode 1.46.1
基本思路:使用插件腳本,
1.定義一張表,將資源名和路徑一一映射,
2.選擇按組加載資源,記錄loadNum,配合ProgressBar節點可以實作一個畫面流暢的資源加載界面
3.然后將資源以{型別:{資源名,…},…}的結構保存在物件中,再將其存盤在全域window下,方便隨時獲取,

優點:
1.使用資源管理器(res.js)來統一加載資源,可以避免因資源數量過多、即時加載資源時間過短而導致的各種資源獲取錯誤問題,
2.可以根據實時變化的loadNum設計你的加載界面
代碼如下:
res.js
/**
\* JavaScript里(()=>{})和(function(){})是標準的函式,
\* 它們沒有賦值給任何變數,沒有函式名,被稱為匿名函式,
\* 因為沒有名字,所以在定義完成就要呼叫,(()=>{})(),
\* 后面的()是呼叫運行這個匿名函式
*/
(() => {
//資源映射表
let TABLE = {
? //音頻類------一級key,一般取名資源的型別(自定義)
? audio: {
? /**
? \* 此資源的路徑,通常我們會把專案中需要動態加載的資源放在 resources 目錄下, 此處resources省略不寫
? \* 所有需要通過腳本動態加載的資源,都必須放置在 resources 檔案夾或它的子檔案夾下,
? \* resources 檔案夾需要在 assets 根目錄 下手動創建
? */
? path: "audio/",
? //資源型別,Class for audio data handling.音瞥澩類
? type: cc.AudioClip,
? //資源串列,即同路徑下同型別的所有資源
? list: ["MayRain", "別再問我什么是迪斯科", "思凡", "執迷不悔", "走鋼索的人", "龍卷風"]
? },
? //預制類
? prefab: {
? path: "prefab/",
? type: cc.Prefab,
? list: ["chapter", "menu", "block", "tip1", "tip2"]
? },
? //teture2D紋理類
? authorImage: {
? path: "texture/author/",
? type: cc.SpriteFrame,
? list: ["MayRain", "別再問我什么是迪斯科", "思凡", "執迷不悔", "走鋼索的人", "龍卷風"]
? }
}
/**新建一個Cres資源加載類,實體化為g_Res并存在window下
\* window物件:
\* 所有瀏覽器都支持 window 物件,它代表瀏覽器的視窗,
\* 所有全域 JavaScript 物件,函式和變數自動成為 window 物件的成員,
\* 全域變數是 window 物件的屬性,
\* 全域函式是 window 物件的方法,
\* 甚至(HTML DOM 的)document 物件也是 window 物件屬性
*/
window.g_Res = new class CRes {
? //建構式中,初始化一個用于存放資源的_data物件,初始化需要加載的資源數量loadNum
? constructor() {
? this._data = {};
? this.loadNum = -1;
? }
? //資源加載入口函式
? loadRes() {
? this.loadNum = 0;
? for (let key in TABLE) {
? //統計資源映射TABLE中有多少個一級key,即有多少種資源
? this.loadNum++;
? //按類加載資源
? this.doLoadRes(key);
? }
? }
? //實際的資源加載函式,加載key類資源
? doLoadRes(key) {
? //拼湊資源型別和名稱,結構為["audio/MayRain","..."],作為按組加載資源的第一個引數
? let resList = [];
? for (let name of TABLE[key].list) {
? let resName = TABLE[key].path + name;
? resList.push(resName);
? }
? //在_data物件中開辟一級結構,結構為this._data = {audio: {},...}
? this._data[key] = {};
? //定義加載資源方法,5個資源呼叫一次
? let func = () => {
? //從中資源串列中從首切分5個
? let tempList = resList.splice(0, 5);
? /**
? \* 按組加載資源方法,
? \* 第一個引數:資源組,
? \* 第二個引數:資源型別,
? \* 第三個引數:回呼函式(err,data)=>{},err:錯誤資訊,data:加載后的資源
? */
? cc.loader.loadResArray(
? tempList,
? TABLE[key].type,
? (err, data) => {
? //判斷此類資源是否加載完成,是,則讓loadNum-1,外部腳本可以通過獲取loadNum的值來判斷資源加載的進度;
? if (resList.length <= 0) {
? this.loadNum--;
? } else {
? //如果此類資源沒有加載完成,則繼續選擇5個一組的方式繼續加載
? func();
? }
? //如果加載錯誤,則列印具體的加載錯誤資訊
? if (err) {
? console.log(err);
? }
? for (let res of data) {
? //在_data物件中開辟二級結構,結構為this._data = {"audio": {"MayRain":它的audioClip,...},...}
? this._data[key][res.name] = res;
? }
? }
? );
? }
? //呼叫上面定義的資源加載方法func
? func();
? }
? //定義獲取資源加載數的函式
? getLoadNum() {
? return this.loadNum;
? }
? //定義獲取資源方法,通過資源的型別key和名稱name來獲取你已經加載好的任和資源
? getRes(key, name) {
? //判斷獲取資源時時,是否所有的資源都已經加載完畢,否,則列印它的型別和名字方便開發者找錯
? if (this.loadNum != 0) {
? console.log("資源未加載完畢!", key, name);
? }
? //安全驗證
? if (this._data[key]) {
? return this._data[key][name];
? } else {
? console.log("目標資源不存在,請檢查資源名!", key, name);
? }
? }
}
})()
附贈加載界面的loading.js腳本
loading.js
cc.Class({
extends: cc.Component,
properties: {
},
loadRes() {
? let curResNum = g_Res.getLoadNum(); //未加載資源
? let readyResNum = this.resNum - curResNum; //已加載資源
? this.goal = readyResNum / this.resNum / 2; //前50%是用來加載資源的,所以進度最多到50%
? //判斷資源是否加載完畢
? if (this.progressBar.progress >= 0.5) {
? this.loadScene(); //預加載場景函式
? }
},
loadScene() {
? this.step = 2;
? cc.director.preloadScene( //預加載場景(只加載場景,場景中的onload()在場景打開后才加載)
? "main",
? (cur, all) => { // cur:已經加載的資源數 all:總共有多少資源數
? this.goal = cur / all / 2 + 0.5;
? },
? () => { },
? );
},
init() {
? this.step = 3;
? cc.director.loadScene("main");
},
playAnim() {
? this.whiteBlock.getComponent(cc.Animation).play("whiteBlock");
},
// LIFE-CYCLE CALLBACKS:
// onl oad() {},
start() {
? g_Res.loadRes();
? this.progressBar = cc.find("Canvas/UILayer/temporatyUI/progressBar").getComponent(cc.ProgressBar);
? this.proLabel = cc.find("Canvas/UILayer/temporatyUI/proLabel").getComponent(cc.Label);
? this.whiteBlock = cc.find("Canvas/UILayer/permanentUI/title/whiteBlock");
? this.progressBar.progress = 0;
? this.goal = 0;
? this.speed = 0.01;
? this.step = 1;
? this.resNum = g_Res.getLoadNum();
? this.playAnim();
},
update(dt) {
? if (this.progressBar.progress < this.goal) {
? this.progressBar.progress += this.speed;
? this.proLabel.string = "進度" + Math.floor(this.progressBar.progress * 100) + "%"
? }
? if (this.step == 1) { //第一步,加載資源
? this.loadRes();
? } else if (this.step == 2 && this.progressBar.progress >= 1) {
? this.init();
? }
},
});
this.progressBar.progress < this.goal) {
? this.progressBar.progress += this.speed;
? this.proLabel.string = "進度" + Math.floor(this.progressBar.progress * 100) + "%"
? }
? if (this.step == 1) { //第一步,加載資源
? this.loadRes();
? } else if (this.step == 2 && this.progressBar.progress >= 1) {
? this.init();
? }
},
});


轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/46675.html
標籤:其他
上一篇:機器視覺halcon
