174 lines
4.9 KiB
TypeScript
174 lines
4.9 KiB
TypeScript
// 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();
|
||
}
|
||
} |