CocosCreator+TS资源管理类

你可能感兴趣:

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);
        }
    }

 我在这里目前就放了这几个方法,其他有需要的小伙伴可自行扩展。

你可能感兴趣的:(Cocos,Creator,cocos-creator,typescript)