小熊1986

导航

ccc-设计之资源管理

重点

  • 需求:h5 游戏资源都是需要先加载,才能使用
  • 资源的分类
  • api的编写

需求

因为所有的h5游戏都需要从服务器上下载资源,而且只有加载完毕的资源我们才能正常的显示到,如果没有加载完毕的话,就不会显示,这样我们通过管理预加载对资源进行管理,和删除资源

资源的分类

  1. 图片资源
  2. 预制体资源
  3. 声音资源
  4. 打包图片集合资源等

api的设计

核心设计

事件的监听

preload_res_pkg api设计

// res_set:  {prefabs: [], sprite_frames:[], audio_clips: [], sprite_atlases: []}
// on_progress: 进度条函数: function(per) [0, 1]
// on_load_finished 装载结束的函数,  function() {}  
preload_res_pkg(res_set, on_progress, on_load_finished) {
  			//当前加载的数量
        this.now_loaded = 0;
  			//总数
        this.total_num = 0;

  			//计算总数
        var key = null;
        for(key in res_set) {
            this.total_num += res_set[key].length;
        }

  			//总数为0直接加载完毕
        if (this.total_num === 0) {
            if (on_load_finished) {
                on_load_finished();
            }
            return;
        }

        var self = this;
        for(key in res_set) {
            for(var i = 0; i < res_set[key].length; i ++) {
                var url = res_set[key][i];
              	//核心区域
                cc.loader.loadRes(url, function(err, obj) {
                    if (err) {
                        cc.error("[res_mgr]", err);
                    }

                    self.now_loaded ++;
                  //更新所有的数据
                    if (on_progress) {
                        on_progress(self.now_loaded / self.total_num);
                    }
										//加载完毕以后
                    if (self.now_loaded >= self.total_num) {
                        if (on_load_finished) {
                            on_load_finished();
                        }
                    }
                });
            }
        }
},

删除资源包 release_res_pkg

release_res_pkg(res_set) {
    if (res_set.sprite_frames && res_set.sprite_frames.length > 0) {
      //核心删除资源的操作
      cc.loader.release(res_set.sprite_frames)
    }

    if (res_set.audio_clips && res_set.audio_clips.length > 0) {
      cc.loader.release(res_set.audio_clips)
    }

    if (res_set.sprite_atlases && res_set.sprite_atlases.length > 0) {
      cc.loader.release(res_set.sprite_atlases)
    }
		//核心删除prefabs操作
    if (res_set.prefabs && res_set.prefabs.length > 0) {
      for(var i = 0; i < res_set.prefabs.length; i ++) {
        var url = res_set.prefabs[i];
        var deps = cc.loader.getDependsRecursively(url);
        cc.loader.release(deps);
        cc.loader.release(url);
      }
    }
},

获得相关资源操作get_res

get_res(url) {
  return cc.loader.getRes(url);
},

测试代码

var game_mgr = require("game_mgr");
var event_mgr = require("event_mgr");
var res_mgr = require("res_mgr");

var game_app = cc.Class({
	extends: game_mgr,

	statics: {
		Instance: null, 
	},

	properties: {
	},

	onLoad() {
		if (game_app.Instance === null) {
			game_app.Instance = this;
		}
		else {
			cc.error("[error]:game_app has multi instances");
			this.destroy();
			return;
		}
		game_mgr.prototype.onLoad.call(this);

		//获得ui添加的资源操作
		this.canvas = cc.find("Canvas");
		if (this.canvas === null) {
			cc.error("[game_app]: canvas is null");
		}
	},

	start() {
		var ui = null;
		var pkg = {
			prefabs: [
				"ui_prefabs/LoginUI", 
			],
			sprite_frames:[
				"image/login/ocean_back",
				"image/login/logo",
				"image/login/start_text"
			],
		};
		//核心部分
		res_mgr.Instance.preload_res_pkg(
			pkg,

			function(per) {
				console.log("$$$$$$$$", per);
			}, 

			function() {
				ui = cc.instantiate(res_mgr.Instance.get_res("ui_prefabs/LoginUI"));
				this.canvas.addChild(ui);
				var bg = ui.getChildByName("bg").getComponent(cc.Sprite);
				console.log(res_mgr.Instance.get_res("image/login/start_text"));
				bg.spriteFrame.setTexture = res_mgr.Instance.get_res("image/login/start_text")

			}.bind(this),
		);


		this.scheduleOnce(function() {
			if(ui){
				//删除
				ui.removeFromParent();
				ui.destroy();
			}
			res_mgr.Instance.release_res_pkg(pkg);
		}.bind(this), 5);
	},

	
});

posted on 2021-05-04 16:53  小熊1986  阅读(67)  评论(0编辑  收藏  举报