欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

制作游戏时,如何管理游戏资源? 逐行注释!

程序员文章站 2024-01-01 08:42:46
制作游戏时,如何管理游戏资源?逐行注释开发环境:CocosCreator v2.3.1node.js v10.16.0vscode 1.46.1基本思路:使用插件脚本。1.定义一张表,将资源名和路径一一映射。2.选择按组加载资源,记录loadNum,配合ProgressBar节点可以实现一个画面流畅的资源加载界面3.然后将资源以{类型:{资源名,…},…}的结构保存在对象中,再将其存储在全局window下,方便随时获取。优点:1.使用资源管理器(res.js)来统一加载资源,可以避免因...

制作游戏时,如何管理游戏资源?

逐行注释!

开发环境:

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对象,初始化需要加载的资源数量loadNumconstructor() {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;}});}//调用上面定义的资源加载方法funcfunc();}//定义获取资源加载数的函数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:



  // onLoad() {},



  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://blog.csdn.net/qq_45236472/article/details/108586552

上一篇:

下一篇: