当前位置:网站首页>CocosCreator+TypeScripts自己写一个对象池

CocosCreator+TypeScripts自己写一个对象池

2022-07-06 14:48:00 卡西莫多说

为什么需要对象池?

在运行时进行节点的创建(cc.instantiate)和销毁(node.destroy)操作是非常耗费性能的,因此我们在比较复杂的场景中,通常只有在场景初始化逻辑(onLoad)中才会进行节点的创建,在切换场景时才会进行节点的销毁。如果制作有大量敌人或子弹需要反复生成和被消灭的动作类游戏,我们要如何在游戏进行过程中随时创建和销毁节点呢?

 很多人都会去官方文档去查看一下,有没有什么办法解决?官方文档关于对象池的链接:

使用对象池 · Cocos Creatorhttps://docs.cocos.com/creator/2.3/manual/zh/scripting/pooling.html?q=那么这次为大家介绍一下自己写的对象池:PoolMgr.ts

定义一个对象,将初始化的对象放到里面:

public static _dictPool: Object = {}

初始化hui对象池:

    /**
     * 初始化对象池
     * @param count 生成的数量
     * @param prefab 生成为节点的预制体
     */
    public static initPool(count:number,prefab:cc.Prefab){
        for (let index = 0; index < count; index++) {
            let node:cc.Node =  cc.instantiate(prefab);
            this.setNode(node);
        }
    }

这个是自己写的初始化,一般在加载界面将对象初始化好,在游戏中就可以直接调用。

获取对象池中的某个对象:

    /**
     * 获取节点
     * @param prefab 生成为节点的预制体
     * @param parent 该节点的父节点
     * @returns 生成或者对象池中的节点
     */
    public static getNode(prefab:cc.Prefab,parent:cc.Node){
        let name = prefab.name;
        let node:cc.Node = null;
        if(this._dictPool[name]){
            let pool = this._dictPool[name];
            if (pool && pool.size() > 0) {
                node = pool.get();
            } else {
                node = cc.instantiate(prefab);
            }
        }
        else{
            let pool = new cc.NodePool();
            this._dictPool[name] = pool;
            node = cc.instantiate(prefab);
        }
        node.parent = parent;
        return node;
    }

回收某个对象:

    /**
     * 回收节点
     * @param node 回收的节点
     */
    public static setNode(node:cc.Node){
        const name = node.name;
        let pool = null;
        if(this._dictPool[name]){
            pool = this._dictPool[name];
        }
        else{
            pool = new cc.NodePool();
            this._dictPool[name] = pool;
        }
        if(pool.size() > 100){
            node.destroy();
            return;
        }
        pool.put(node);
    }

使用示例:

let count:number = 10;
let path:string = "xx";
sc.load.LoadPrefab(path,(prefab:cc.Prefab)=>{
    PoolMgr.initPool(count,prefab);
});

加载资源时调用初始化接口,这样就初始化了10个对应路径的预制体;

设置:

let node = PoolMgr.getNode(prefab,parent);

获取预制体,设置父节点,即可获得该节点;

回收:

PoolMgr.setNode(node);

 回收节点时注意:如果对这个节点做了什么改变,比如它的旋转、缩放等,注意在再次使用时它的属性。

原网站

版权声明
本文为[卡西莫多说]所创,转载请带上原文链接,感谢
https://blog.csdn.net/qq_42597694/article/details/125557653