cb/assets/Script/module/NodePool/NodePoolMgr.ts
2026-02-26 17:08:56 +08:00

174 lines
4.9 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// NodePoolMgr.ts
const { ccclass } = cc._decorator;
@ccclass
export default class NodePoolMgr extends cc.Component {
// 私有属性
private nodePool: any = null;
private itemPrefab: cc.Prefab = null;
private poolArray: cc.Node[] = [];
onLoad() {
this.init();
}
/**
* 初始化组件
*/
private init() {
// 首先尝试使用原生NodePool
try {
// 检查cc.NodePool是否存在且可用
if (typeof cc.NodePool === 'function') {
this.nodePool = new cc.NodePool();
console.log("NodePool初始化成功");
return;
}
} catch (error) {
console.warn("原生NodePool初始化失败:", error);
}
// 如果原生NodePool不可用使用自定义实现
console.log("使用自定义NodePool实现");
this.nodePool = {
size: () => this.poolArray.length,
get: () => {
if (this.poolArray.length > 0) {
return this.poolArray.pop();
}
return null;
},
put: (node: cc.Node) => {
if (node && cc.isValid(node)) {
// 重置节点状态
node.active = true;
node.opacity = 255;
node.scale = 1;
node.rotation = 0;
node.position = cc.Vec3.ZERO;
this.poolArray.push(node);
}
},
clear: () => {
// 销毁所有池中的节点
for (let node of this.poolArray) {
if (node && cc.isValid(node)) {
node.destroy();
}
}
this.poolArray = [];
}
};
}
/**
* 获取一个列表项节点
* @param prefab 列表项预制体(可选,如果不传则使用之前设置的预制体)
*/
public getItem(prefab?: cc.Prefab): cc.Node {
// 如果传入了新的预制体,则更新当前预制体
if (prefab) {
this.itemPrefab = prefab;
}
let itemNode: cc.Node = null;
try {
// 使用自定义或原生NodePool
if (this.nodePool && typeof this.nodePool.get === 'function') {
itemNode = this.nodePool.get();
}
// 如果没有从池中获取到节点且有预制体,则实例化新节点
if (!itemNode && this.itemPrefab) {
itemNode = cc.instantiate(this.itemPrefab);
}
if (!itemNode) {
console.warn("NodePoolMgr: No prefab available to instantiate item");
}
} catch (error) {
console.error("getItem时发生错误:", error);
// 出错时直接实例化
if (this.itemPrefab) {
try {
itemNode = cc.instantiate(this.itemPrefab);
} catch (instantiateError) {
console.error("实例化节点失败:", instantiateError);
}
}
}
return itemNode;
}
/**
* 回收列表项节点
* @param itemNode 列表项节点
*/
public putItem(itemNode: cc.Node) {
if (!itemNode || !cc.isValid(itemNode)) {
return;
}
try {
if (this.nodePool && typeof this.nodePool.put === 'function') {
this.nodePool.put(itemNode);
} else {
// 直接移除节点
itemNode.removeFromParent();
}
} catch (error) {
console.error("putItem时发生错误:", error);
// 出错时直接移除节点
try {
itemNode.removeFromParent();
} catch (removeError) {
console.error("移除节点失败:", removeError);
}
}
}
/**
* 设置预制体
* @param prefab 新的预制体
*/
public setItemPrefab(prefab: cc.Prefab) {
this.itemPrefab = prefab;
}
/**
* 获取当前预制体
*/
public getItemPrefab(): cc.Prefab {
return this.itemPrefab;
}
/**
* 清空节点池
*/
public clear() {
try {
if (this.nodePool && typeof this.nodePool.clear === 'function') {
this.nodePool.clear();
} else {
// 清空自定义数组
for (let node of this.poolArray) {
if (node && cc.isValid(node)) {
node.destroy();
}
}
this.poolArray = [];
}
} catch (error) {
console.error("清空节点池时出错:", error);
}
}
/**
* 销毁时清理资源
*/
onDestroy() {
this.clear();
}
}