8、节点池

import { NodePool } from "cc";

NodePool 是用于管理节点对象的对象缓存池。

它可以帮助您提高游戏性能,适用于优化对象的反复创建和销毁

以前 cocos2d-x 中的 pool 和新的节点事件注册系统不兼容,因此请使用 NodePool 来代替。

新的 NodePool 需要实例化之后才能使用,每种不同的节点对象池需要一个不同的对象池实例,这里的种类对应于游戏中的节点设计,一个 prefab 相当于一个种类的节点。

在创建缓冲池时,可以传入一个包含 unuse, reuse 函数的组件类型用于节点的回收和复用逻辑。

一些常见的用例是:

import { _decorator, Component, instantiate, Node, NodePool, Prefab } from 'cc';
const { ccclass, property } = _decorator;

interface INodePollMap{
    [name: string]: NodePool
}

interface IPrefabMap{
    [name: string]: Prefab
}

// 节点池控制类
@ccclass('NodePoolController')
export class NodePoolController {
    
    // 按照类型分类管理节点池
    private static iNodePollMap: INodePollMap = {}

    // 缓存用过的预制
    private static iPrefabMap: IPrefabMap = {}

    // 获取节点
    public static getNode(prefab: Prefab,parent: Node): Node{
        // 缓存该预制
        var name = prefab.name;
        NodePoolController.iPrefabMap[name] = prefab;
        var node: Node = null;
        var pool = NodePoolController.iNodePollMap[name];
        // 判断是否存在该类型节点池
        if(pool){
            // 判断该节点池中是否存在节点对象
            if(pool.size() > 0){
                // 存在节点对象则直接返回
                node = pool.get();
            }else{
                // 不存在则实例化一个新的节点对象
                node = instantiate(prefab);
            }
        }else{
            // 没有该类型的节点池,则创建一个
            NodePoolController.iNodePollMap[name] = new NodePool();
            node = instantiate(prefab);
        }
        // 激活
        node.active = true;
        // 设置父节点
        node.setParent(parent);
        return node;
    }

    // 节点无用后放回节点池
    public static putNode(node: Node){
        var name = node.name;
        // 设置禁用
        node.active = false;
        // 判断该类型节点的节点池是否存在,不存在则创建
        if(!NodePoolController.iNodePollMap[name]){
            NodePoolController.iNodePollMap[name] = new NodePool();
        }
        NodePoolController.iNodePollMap[name].put(node);
    }
}