你可能感兴趣:
Cocos Creator+TS自己写一个消息机制
Cocos Creator+TS改造日志系统
在开发游戏过程中,游戏资源的管理是一个不可避免的问题,cocoscreator准备了对象池为我们处理节点、预制体等资源做了基础,这次分享一个资源管理类给大家做参考。
里面添加了一些通过路径获取节点资源名称,对象池中是否有了需要的节点,获取节点,读取节点资源等方法,为之后做界面和弹窗管理做准备。
为需要的资源类型做一个接口,里面是他们的名字和类型。
interface Resources {
//节点类型
Node: { [propName: string]: cc.Node },
Prefab: { [PropName: string]: cc.Prefab },
NodePool: { [propName: string]: cc.NodePool },
//资源动画
AnimationClip: { [propName: string]: cc.AnimationClip },
ParticleAsset: { [propName: string]: cc.ParticleAsset },
TiledMapAsset: { [propName: string]: cc.TiledMapAsset },
Mesh: { [propName: string]: cc.Mesh },
AudioClip: { [propName: string]: cc.AudioClip },
Font: { [propName: string]: cc.Font },
JsonAsset: { [propName: string]: cc.JsonAsset },
SceneAsset: { [propName: string]: cc.SceneAsset },
SpriteAtlas: { [propName: string]: cc.SpriteAtlas },
SpriteFrame: { [propName: string]: cc.SpriteFrame },
TextAsset: { [propName: string]: cc.TextAsset },
Texture2D: { [propName: string]: cc.Texture2D },
Material: { [propName: string]: cc.Material },
//龙骨
DragonBonesAsset: { [propName: string]: dragonBones.DragonBonesAsset },
DragonBonesAtlasAsset: { [propName: string]: dragonBones.DragonBonesAtlasAsset },
}
同样,在处理这个资源管理的时候,也做成了一个单例。
//资源管理者唯一实例
private static _instance: ResManager = null;
//类中对资源接口的声明,必须声明接口中的全部属性或者方法
private _allResources:Resources = {
Node: {},
Prefab: {},
NodePool: {},
AnimationClip: {},
ParticleAsset: {},
TiledMapAsset: {},
Mesh: {},
AudioClip: {},
Font: {},
JsonAsset: {},
SceneAsset: {},
SpriteAtlas: {},
SpriteFrame: {},
TextAsset: {},
Texture2D: {},
Material: {},
DragonBonesAsset: {},
DragonBonesAtlasAsset: {}
};
//资源管理者类的构造函数
private constructor() { }
/**将资源管理者设置为单例模式
* @returns {ResManager} 返回资源管理唯一实例
*/
public static get instance(): ResManager {
if (!this._instance) {
this._instance = new ResManager();
}
return this._instance
}
下面是它的一些方法,我在里面已经注释好他们的功能、参数、返回值等,这里就不做过多介绍了。
/**
* 通过路径获取节点资源名称
* @param {string} path 要获取的节点资源的路径
* @returns {string} 返回节点名称的字符串
*/
public getResourcesName(path:string):string{
let index = path.lastIndexOf("/");
if(index === -1){
return path;
}
else{
return path.slice(index + 1);
}
}
是否已经实例出这个节点:
/**
* 判断是否已经有了这个节点资源
* @param {string} resName 判断是否已经存在节点资源的名字
* @param {string} path 可选配置,节点资源的路径
* @returns {boolean} 有返回true,没有返回false
*/
public hasNode(resName:string,path?:string):boolean{
let name:string;
if(path){
name = this.getResourcesName(path);
}
else{
name = resName;
}
if(this._allResources.Node[name]){
return true;
}
if(this._allResources.NodePool[name]){
return true;
}
if(this._allResources.Prefab[name]){
return true;
}
return false;
}
获取节点:
/**
* 获取节点,如果handle的Map中有就直接获取到,没有的话就实例化出来
* @param {string} resName 要获取的节点名称
* @param {string} path 可选参数,资源路径
* @returns {cc.Node} 返回节点或者undefined
*/
public getNode(resName: string, path?: string):cc.Node|undefined{
let name;
if(path){
name = this.getResourcesName(path);
}
else{
name = resName;
}
//如果名称为name的节点池不存在,就新建一个;如果存在,判断大小,有就取出来用
let nodePool = this._allResources.NodePool[name];
if(!nodePool){
nodePool = this._allResources.NodePool[name] = new cc.NodePool();
}
if(nodePool.size() > 0){
return nodePool.get();
}
//如果存在名称为name的节点,就实例化出来
if(this._allResources.Node[name]){
let node:cc.Node = cc.instantiate(this._allResources.Node[name]);
//CocosCreator的节点上面本来不存在, 添加一个表示节点所在的NodePool的名字
node.CProperty = {nodePoolName:name};
return node;
}
//如果存在名称为name的预制体,就实例化出来
if(this._allResources.Prefab[name]){
let node:cc.Node = cc.instantiate(this._allResources.Prefab[name]);
node.CProperty = {nodePoolName:name};
return node;
}
}
加载资源:
/**
* 加载预制体资源
* @param path 预制体资源的路径
* @param completeCallback 完成之后的回调
*/
public loadPrefab(path:string,completeCallback:(error:Error,resource:cc.Prefab)=>void){
let prefabName = this.getResourcesName(path);
if(this._allResources.Prefab[prefabName]){
completeCallback(undefined,this._allResources.Prefab[prefabName]);
}
else{
let callFunc = (error:Error,resource:cc.Prefab)=>{
if(!error){
this._allResources.Prefab[prefabName] = resource;
}
completeCallback(error,resource);
}
cc.loader.loadRes(path,cc.Prefab,callFunc);
}
}
/**
* 加载其他资源
* @param path 加载的资源的路径
* @param type 加载的资源的类型
* @param completeCallback 加载完成之后的回调
*/
public loadResource(path:string,type:typeof cc.Asset,completeCallback:(error:Error,resource:cc.Asset)=>void){
let assetName = this.getResourcesName(path);
let typeName = type.name;
if(this._allResources[typeName][assetName]){
completeCallback(undefined,this._allResources[typeName][assetName]);
}
else{
let callFunc = (err:Error,resource:cc.Asset)=>{
if(!err){
this._allResources[typeName][assetName] = resource;
}
completeCallback(err,resource);
}
cc.loader.loadRes(path,type,callFunc);
}
}
我在这里目前就放了这几个方法,其他有需要的小伙伴可自行扩展。