rp_11001/assets/Game/scripts/game/IconFactory.ts
2025-11-08 14:26:11 +08:00

157 lines
4.8 KiB
TypeScript

import { _decorator, Component, Node, Prefab, instantiate, v3, Vec3 } from 'cc';
import { Icon } from './Icon';
import { ICON_STATE } from './Define';
import { NodePoolManager } from '../../../Loading/scripts/manager/NodePoolManager';
const { ccclass, property, executeInEditMode } = _decorator;
@ccclass('IconFactory')
@executeInEditMode
export class IconFactory extends Component {
@property({ type: [Prefab] })
prefabs: Prefab[] = [];
// 性能优化相关常量
private static readonly INIT_POOL_SIZE = 6; // 每种图标初始池大小
private static readonly BATCH_CREATE_SIZE = 5; // 批量创建数量
// 活跃图标追踪
private activeIcons: Set<Node> = new Set();
// 创建计数
private createCounter: number[] = [];
// 初始化标记
private isInitialized: boolean = false;
// 初始化坐标
private initPos: Vec3 = v3(0, 0, 0);
// 初始化
init() {
if (this.isInitialized) return;
// 初始化计数器
this.createCounter = new Array(this.prefabs.length).fill(0);
// 预热对象池
this.warmupPools();
this.isInitialized = true;
}
// 预热对象池
private warmupPools() {
// 为每种图标预创建一定数量的节点
for (let i = 0; i < this.prefabs.length; i++) {
const poolName = `Icon_${i}`;
// 批量创建节点到对象池
for (let j = 0; j < IconFactory.INIT_POOL_SIZE; j++) {
const node = instantiate(this.prefabs[i]);
const iconComp = node.getComponent(Icon) || node.addComponent(Icon);
iconComp.index = i;
// 确保第一次初始化
iconComp.initIcon(i);
NodePoolManager.instance.putNodeToPool(poolName, node);
}
}
}
// 创建图标
icfactoryCreateIcon(index: number): Node {
// 参数检查
if (index == null || index == undefined || index < 0) {
console.error(`IconFactory createIcon Error: ${index}`);
index = 0;
}
// 确保已初始化
if (!this.isInitialized) {
this.init();
}
// 从对象池获取或创建节点
const iconNode = NodePoolManager.instance.getNodeFromPoolStatic(
`Icon_${index}`,
this.prefabs[index]
);
// 获取或添加Icon组件
const iconComp = iconNode.getComponent(Icon) || iconNode.addComponent(Icon);
iconComp.index = index;
// 确保初始化
iconComp.initIcon(index);
iconNode.setPosition(this.initPos);
// 更新计数和跟踪
this.createCounter[index]++;
this.activeIcons.add(iconNode);
// 检查是否需要补充对象池
this.checkAndReplenishPool(index);
return iconNode;
}
// 检查并补充对象池
private checkAndReplenishPool(index: number) {
const poolName = `Icon_${index}`;
const pool = NodePoolManager.instance.getNodePoolByName(poolName);
// 如果池中节点较少,补充新节点
if (pool && pool.size() < IconFactory.INIT_POOL_SIZE / 2) {
for (let i = 0; i < IconFactory.BATCH_CREATE_SIZE; i++) {
const node = instantiate(this.prefabs[index]);
const iconComp = node.getComponent(Icon) || node.addComponent(Icon);
iconComp.index = index;
iconComp.initIcon(index);
NodePoolManager.instance.putNodeToPool(poolName, node);
}
}
}
// 回收图标
recycleIcon(icon: Node) {
if (!icon) {
console.error(`IconFactory.recycleIcon null`);
return;
}
const iconComp = icon.getComponent(Icon);
if (!iconComp) return;
const index = iconComp.index;
if (index >= 0) {
// 重置节点状态
this.resetNode(icon);
// 从活跃集合中移除
this.activeIcons.delete(icon);
// 放回对象池
NodePoolManager.instance.putNodeToPool(`Icon_${index}`, icon);
}
}
// 重置节点状态
resetNode(icon: Node) {
const iconComp = icon.getComponent(Icon);
if (iconComp) {
iconComp.changeIconState(ICON_STATE.IDLE);
iconComp.showFastIcon(false);
icon.setScale(1, 1, 1);
}
}
// 获取图标数量
getIconNum(): number {
return this.prefabs.length;
}
// 清理资源
onDestroy() {
// 回收所有活跃图标
this.activeIcons.forEach(icon => {
this.recycleIcon(icon);
});
this.activeIcons.clear();
this.createCounter = [];
this.isInitialized = false;
}
}