五邑隐侠,本名关健昌,10年游戏生涯,现隐居五邑。本系列文章以TypeScript为介绍语言。

在初识篇,我介绍过怎样加载prefab。cocos提供了一系列的加载接口,包括cc.loader.load,cc.loader.loadRes,cc.loader.loadResArray,cc.loader.loadResDir。

static load(resources: string|string[]|{uuid?: string, url?: string, type?: string}, completeCallback?: Function): void;

static loadRes(url: string, type: typeof cc.Asset, completeCallback: (error: Error, resource: any) => void): void;

static loadResArray(url: string[], type: typeof cc.Asset, progressCallback: (completedCount: number, totalCount: number, item: any) => void, completeCallback: ((error: Error, resource: any[]) => void)|null): void;

static loadResDir(url: string, type: typeof cc.Asset, progressCallback: (completedCount: number, totalCount: number, item: any) => void, completeCallback: ((error: Error, resource: any[], urls: string[]) => void)|null): void;

这些接口除了加载资源外,也负责资源管理。所以,在界面被销毁时,如果在cc.loader里还有该资源,资源是不会释放的。对于资源的管理,有两种方式,一种是资源加载后,cc.loader不管理资源,通过界面的引用来确定是否销毁资源。一种是cc.loader管理资源,界面使用资源,在模块退出时,通过cc.loader销毁资源。我偏向于第二种方式,这样避免依赖内存gc,资源可以得到即时释放。为了避免错误释放资源,在资源管理模块对加载的资源设置引用计数,引用计数为0时才实际销毁。

下面说说这几个接口的使用场景:

1.cc.loader.load用于加载第三方远程资源,在游戏中一般用于加载第三方平台的头像资源,如果该资源的链接没有文件后缀名,需要加参数{type:"png"}。

2.cc.loader.loadRes用于加载assets/resources目录下单个资源

3.cc.loader.loadResArray用于批量加载assets/resources目录下资源,比较适合于进度条加载界面,通过进度变化更新进度条。

4.cc.loader.loadResDir用于加载assets/resources目录下单个目录的资源,一般我会把单个spine骨骼动画放在一个目录,把一个界面的资源放在一个目录。这样就可以通过这个接口加载单个spine动画或者一个界面的资源。

在初识篇提到,我们建立assets/resources目录用于存放资源,目的是可以通过上述除了cc.loader.load外的接口加载资源,简化使用。

资源加载管理模块,可以划分为ResLoader、ViewLoader。其中ResLoader负责基础资源加载,另外提供超时、重试机制。ViewLoader负责对加载的prefab、重用界面的node进行缓存管理。这类工具性的类,我都习惯做成单例,一来游戏里只需要一个对象,另外单例有利于这些对象可以全局访问。

ResLoader,封装cc.loader上述几个接口,以及对应的释放接口。

超时实现:设置回调控制变量,settimeout回调中设置变量,并调用超时回调,在成功失败处理中判断变量是否触发成功失败的回调。由于cc.loader本身有做资源管理,所以下次调用加载时如果已经通过cc.loader正在加载和成功加载的资源不会重复加载。

重试实现:通过变量记录加载次数,在失败和超时处理中判断是否达到重试次数,未达到则重新加载。

/**
* 加载 resources 目录下单个资源
* @param url
* @param type
* @param progressCallback
* @param completeCallback
*/
public static loadRes(url: string, type: typeof cc.Asset, completeCallback: (error: Error, resource: any) => void): void {
let count = ResLoader.retryCount + 1;
let hasCb = false; // timeout
let timer = setTimeout(() => {
hasCb = true;
completeCallback && completeCallback({
name: "timeout",
message: "timeout",
}, null);
}, ResLoader.timeout); // real load
let realLoad = function() {
count--; // load
cc.loader.loadRes(url, type, (err, result) => {
if (!err || count <= 0) {
clearTimeout(timer);
!hasCb && completeCallback && completeCallback(err, result);
return;
} realLoad();
});
}; realLoad();
}

ViewLoader,负责prefab和重用界面node的缓存,所以每个prefab都设置一个对应的tag,加载的prefab存放在Dictionary<number,cc.Prefab>类型的prefabDict属性中(Dictionary可以通过两个数组存放key-value封装出来),重用界面的node存放在Dictionary<number,cc.Node>类型的nodeDict属性中。

  private static tag2prefabPathMap: Dictionary<number, string> = new Dictionary<number, string>();
private static tag2prefabMap: Dictionary<number, cc.Prefab> = new Dictionary<number, cc.Prefab>();
private static tag2nodeMap: Dictionary<number, cc.Node> = new Dictionary<number, cc.Node>();

通过ResLoader加载cc.Prefab。cc.instantiate实例出node节点

        let instantiatePrefab = function(prefab: cc.Prefab) {
let node = cc.instantiate(prefab);
if (reuse && !ViewLoader.tag2nodeMap.hasKey(tag)) {
ViewLoader.tag2nodeMap.set(tag, node);
} cb && cb(node);
}

资源加载管理先聊到这里,下一篇我们将介绍下怎样做网络通信。

cocos creator主程入门教程(三)—— 资源管理的更多相关文章

  1. cocos creator主程入门教程(一)—— 初识creator

    五邑隐侠,本名关健昌,10年游戏生涯,现隐居五邑.本系列文章以TypeScript为介绍语言. 我们在cocos creator新建一个Hello TypeScript项目,都会有一个assets/S ...

  2. cocos creator主程入门教程(七)—— MVC架构

    五邑隐侠,本名关健昌,10年游戏生涯,现隐居五邑.本系列文章以TypeScript为介绍语言. 这一篇将介绍在游戏客户端常用的架构MVC架构.一个游戏的MVC如下划分: M:1)单例全局的数据中心Wo ...

  3. cocos creator主程入门教程(二)—— 弹窗管理

    五邑隐侠,本名关健昌,10年游戏生涯,现隐居五邑.本系列文章以TypeScript为介绍语言. 我们已经知道怎样制作.加载.显示界面.但cocos没有提供一个弹窗管理模块,对于一个多人合作的项目,没有 ...

  4. cocos creator主程入门教程(四)—— 网络通信

    五邑隐侠,本名关健昌,10年游戏生涯,现隐居五邑.本系列文章以TypeScript为介绍语言. 前面已经介绍怎样加载资源.管理弹窗.开发一个网络游戏,难免要处理网络通信.有几点问题需要注意: 1.服务 ...

  5. cocos creator主程入门教程(五)—— 日志系统

    五邑隐侠,本名关健昌,10年游戏生涯,现隐居五邑.本系列文章以TypeScript为介绍语言. 这一篇介绍日志系统的设计.一般我们开发一个demo,只会简单的用cocos提供的cc.log打印下日志, ...

  6. cocos creator主程入门教程(十一)—— 有限状态机和行为树

    五邑隐侠,本名关健昌,10年游戏生涯,现隐居五邑.本系列文章以TypeScript为介绍语言. 本篇介绍有限状态机和行为树.有限状态机用于有限的状态下的AI,由于同时只能处于一个状态,多个状态需要多个 ...

  7. cocos creator主程入门教程(十)—— A*寻路

    摘要: 五邑隐侠,本名关健昌,10年游戏生涯,现隐居五邑.本系列文章以TypeScript为介绍语言. 这一篇介绍A*寻路算法.在RPG.SLG.模拟经营类游戏,有需要给角色寻路的需求,一般寻路我们采 ...

  8. cocos creator主程入门教程(九)—— 瓦片地图

    五邑隐侠,本名关健昌,10年游戏生涯,现隐居五邑.本系列文章以TypeScript为介绍语言. 这一篇介绍瓦片地图,在开发模拟经营类游戏.SLG类游戏.RPG游戏,都会使用到瓦片地图.瓦片地图地面是通 ...

  9. cocos creator主程入门教程(八)—— 代码结构

    五邑隐侠,本名关健昌,10年游戏生涯,现隐居五邑.本系列文章以TypeScript为介绍语言. 这一篇简单介绍下代码结构,清晰的代码结构更有利于团队对项目的理解和维护. 1.前面我们介绍了一系列基础功 ...

随机推荐

  1. POJ_2104_K-th Number_主席树

    POJ_2104_K-th Number_主席树 题意:给定一个长度为n的序列,m次询问区间第k小 分析: 主席树模板 主席树可以理解成为n棵权值线段树的前缀和 但我们不能建n棵线段树,只需要对于每个 ...

  2. Postman----打开postman console控制台,查看接口测试打印log

    经常在脚本中使用变量时,你可能需要看到变量获取到的值,你可以使用Postman Console去实现的.操作步骤:应用菜单-->View--->Show Postman Console,去 ...

  3. 从零开始学 Web 之 CSS(三)链接伪类、背景、行高、盒子模型、浮动

    大家好,这里是「 Daotin的梦呓 」从零开始学 Web 系列教程.此文首发于「 Daotin的梦呓 」公众号,欢迎大家订阅关注.在这里我会从 Web 前端零基础开始,一步步学习 Web 相关的知识 ...

  4. 【STM32H7教程】第10章 STM32H7的FLASH,RAM和栈使用情况(map和htm文件)

    完整教程下载地址:http://forum.armfly.com/forum.php?mod=viewthread&tid=86980 第10章       STM32H7的FLASH,RAM ...

  5. python——对图像进行卷积操作,使用多个滤波器

    线性滤波可以说是图像处理最基本的方法,它可以允许我们对图像进行处理,产生很多不同的效果.做法很简单.首先,我们有一个二维的滤波器矩阵(有个高大上的名字叫卷积核)和一个要处理的二维图像.然后,对于图像的 ...

  6. WebGL three.js学习笔记 自定义顶点建立几何体

    自定义顶点建立几何体与克隆 Three.js本身已经有很多的网格模型,基本已经够我们的使用,但是如果我们还是想自己根据顶点坐标来建立几何模型的话,Three.js也是可以的. 基本效果如图: 点击查看 ...

  7. 学习 JavaScript (四)核心概念:操作符

    JavaScript 的核心概念主要由语法.变量.数据类型.操作符.语句.函数组成,前面三个上一篇文章已经讲解完了.后面三个内容超级多,这篇文章主要讲解的是操作符. 操作符 什么叫做操作符? 这是一种 ...

  8. 详解synchronized与Lock的区别与使用

    知识点 1.线程与进程 在开始之前先把进程与线程进行区分一下,一个程序最少需要一个进程,而一个进程最少需要一个线程.关系是线程–>进程–>程序的大致组成结构.所以线程是程序执行流的最小单位 ...

  9. Java并发编程面试题 Top 50 整理版

    本文在 Java线程面试题 Top 50的基础上,对部分答案进行进行了整理和补充,问题答案主要来自<Java编程思想(第四版)>,<Java并发编程实战>和一些优秀的博客,当然 ...

  10. DSAPI 生成桌面图标(带数字)

    功能:在桌面上创建一个带有指定数字的图标. 效果图: 生成的ICO图标 代码 Private Sub 生成桌面图标(消息数量 As Integer) Try Dim B As New Bitmap(M ...