import { _decorator, Component, Node, Prefab, sp, Sprite, UITransform, Vec3, v3, EventTarget, SpriteAtlas } from 'cc'; import { ICON_STATE, ICON_WIDTH } from './Define'; import { GameDataManager } from 'db://assets/Loading/scripts/manager/GameDataManager'; import { NodePoolManager } from 'db://assets/Loading/scripts/manager/NodePoolManager'; const { ccclass, property } = _decorator; // 声明一个全局事件总线 export const IconEventBus = new EventTarget(); // 高度映射表 - 减少重复计算 let HEIGHT_MAP = { 1: 240 / 1.35, 2: 386 / 1.15, 3: 528 / 1.05, 4: 674 }; let BTN_HEIGHT_MAP = { 1: 145, 2: 145 * 2, 3: 145 * 3, 4: 145 * 4 }; // 静态共享的Vec3对象 - 减少GC压力 let SHARED_VEC3 = v3(0, 0, 0); @ccclass('Icon') export class Icon extends Component { // /** Icon的资源 */ @property(sp.Skeleton) iconSpine: sp.Skeleton = null; @property(Node) bgNode: Node = null; // 普通框 @property(Sprite) Frame: Sprite = null; @property(Sprite) blurFrame: Sprite = null; @property(Prefab) winSpinePrefab: Prefab = null; @property(SpriteAtlas) symbolAtlas: SpriteAtlas = null; // 节点引用 private _normalNode: Node = null; private _fastNode: Node = null; private _btn: Node = null; private _frameNode: Node = null; private _fastFrameNode: Node = null; private _normalSpriteNode: Node = null; // 组件缓存 - 提高性能 private _transform: UITransform = null; private _frameTransform: UITransform = null; private _bgTransform: UITransform = null; private _fastFrameTransform: UITransform = null; private _btnTransform: UITransform = null; // 基础属性 private _iconId: number = 99; private _lheight: number = 1; // 图标的高度倍数,默认1*1 private _state = ICON_STATE.ACTIVATE; private _iconKey: string = ''; private _frameType: number = 0; private _rollerIndex: number = 0; // 缓存的向量对象,避免重复创建 private readonly _position = new Vec3(); // 组件状态标志 private _isInitialized: boolean = false; private _isFastMode: boolean = false; private _isWildOrScatter: boolean = false; private _isQKJ: boolean = false; // 动画相关 private _iconChangeCallback: Function = null; private _changeSprite: Sprite = null; // 用于切换动画的新Sprite // getter/setter set index(id: number) { this._iconId = id; this._isWildOrScatter = id === 0 || id === 1; this._isQKJ = id >= 8 } get index(): number { return this._iconId; } set lHeight(height: number) { this._lheight = height; } get lHeight(): number { return this._lheight; } set iconKey(key: string) { this._iconKey = key; } get iconKey(): string { return this._iconKey; } set rollerIndex(index: number) { this._rollerIndex = index; } get rollerIndex(): number { return this._rollerIndex; } get startPos(): number { // 检查是否有有效的图标key if (!this._iconKey || this._iconKey.length === 0) { return 0; } const parts = this._iconKey.split('_'); return parseInt(parts[1]); } set frameType(type: number) { if (this._frameType === type) return; // 避免重复设置 this._frameType = type; this.updateFrames(); } /** * 获取icon框类型 * @returns 0:普通框 1:银框 2:金框 3:百搭框 */ get frameType(): number { return this._frameType; } // 生命周期:组件加载时 onLoad() { // 缓存常用组件引用 this._transform = this.node.getComponent(UITransform) || this.node.addComponent(UITransform); this.initializeComponents(); } onIconClick() { IconEventBus.emit('ICON_CLICKED', this); } /** * 获取图标的世界坐标 * @returns 图标在世界空间中的位置 */ getWorldPosition(): Vec3 { // 获取当前图标的世界坐标 if (this._transform) { // 使用缓存的向量对象来减少内存分配 return this._transform.convertToWorldSpaceAR(v3(0, 0, 0)); } return null; } // 生命周期:组件启用时 onEnable() { if (!this._isInitialized) { this.initializeComponents(); } } // 更新框架精灵 updateFrames() { if (!this.Frame || !this.blurFrame) return; const manager = GameDataManager.instance; let frameName, blurFrameName; switch (this._frameType) { case 0: frameName = ''; blurFrameName = ''; break; case 1: frameName = `13_${this.lHeight}`; blurFrameName = `13_2_mh`; break; default: frameName = ''; blurFrameName = ''; } if (frameName == '') { this.Frame.spriteFrame = null this.blurFrame.spriteFrame = null } else { this.Frame.spriteFrame = manager.getFrameTypeCache(frameName); this.blurFrame.spriteFrame = manager.getFrameTypeCache(blurFrameName); } } // 初始化所有组件引用 private initializeComponents() { if (this._isInitialized) return; // 获取节点引用 this._normalNode = this.node.getChildByName('normal'); if (this._normalNode) { this._normalSpriteNode = this._normalNode.getChildByName('sprite'); this._frameNode = this._normalNode.getChildByName('frame'); // 缓存组件 if (this._frameNode) { this._frameTransform = this._frameNode.getComponent(UITransform); } } this._btn = this.node.getChildByName('btn'); if (this._btn) { this._btnTransform = this._btn.getComponent(UITransform); this._btn.on(Node.EventType.TOUCH_END, this.onIconClick, this); } this._fastNode = this.node.getChildByName('fast'); if (this._fastNode) { this._fastFrameNode = this._fastNode.getChildByName('frame'); // 缓存组件 if (this._fastFrameNode) { this._fastFrameTransform = this._fastFrameNode.getComponent(UITransform); } } // 缓存背景节点组件 if (this.bgNode) { this._bgTransform = this.bgNode.getComponent(UITransform); } // 设置初始状态 if (this._normalNode) this._normalNode.active = true; if (this._frameNode) this._frameNode.active = true; if (this._normalSpriteNode) this._normalSpriteNode.active = true; if (this._fastNode) this._fastNode.active = false; if (this._fastFrameNode) this._fastFrameNode.active = false; this._isInitialized = true; } // 初始化图标 initIcon(id: number, lHeight: number = 1, IconKey: string = '', frameType: number = 0, rollerIndex: number = 0) { // 确保组件已初始化 if (!this._isInitialized) { this.initializeComponents(); } // 设置基本属性 this.index = id; this.lHeight = lHeight; this.iconKey = IconKey; this.frameType = frameType; this.rollerIndex = rollerIndex; // 设置尺寸 if (this._transform) { this._transform.width = ICON_WIDTH; this._transform.height = HEIGHT_MAP[lHeight] || HEIGHT_MAP[1]; } else { this.node.getComponent(UITransform).width = ICON_WIDTH; this.updateHeightForLheight(lHeight, this.node); } // 批量更新子节点尺寸 let height = HEIGHT_MAP[lHeight] || HEIGHT_MAP[1]; // 使用缓存的UITransform组件 if (this._bgTransform) this._bgTransform.height = height; else this.updateHeightForLheight(lHeight, this.bgNode); if (this._frameTransform) this._frameTransform.height = height; else this.updateHeightForLheight(lHeight, this._frameNode); if (this._fastFrameTransform) this._fastFrameTransform.height = height; else this.updateHeightForLheight(lHeight, this._fastFrameNode); if (this._btnTransform) { this._btnTransform.height = BTN_HEIGHT_MAP[lHeight] || BTN_HEIGHT_MAP[1]; this._btnTransform.width = ICON_WIDTH; } else { if (!this._btn) return; let transform = this._btn.getComponent(UITransform); if (!transform) return; // 使用映射表而不是多个if判断 transform.height = BTN_HEIGHT_MAP[lHeight] || BTN_HEIGHT_MAP[1]; transform.width = ICON_WIDTH; } // 重置状态 this.resetState(); } // 重置状态 private resetState() { this._isFastMode = false; this.node.active = true; // 批量设置节点状态 if (this._normalNode) this._normalNode.active = true; if (this._fastNode) this._fastNode.active = false; // 根据图标类型设置显示 if (this._isWildOrScatter) { if (this.iconSpine && this.iconSpine.node) this.iconSpine.node.active = true; if (this._normalSpriteNode) this._normalSpriteNode.active = false; } else { if (this.iconSpine && this.iconSpine.node) this.iconSpine.node.active = false; if (this._normalSpriteNode) this._normalSpriteNode.active = true; } if (this._iconId >= 8) { this._normalNode.getComponent(Sprite).spriteFrame = this.symbolAtlas.getSpriteFrame(`8_${this.lHeight}`) } else { this._normalNode.getComponent(Sprite).spriteFrame = this.symbolAtlas.getSpriteFrame(`${this._iconId}_${this.lHeight}`) } } updateHeightForLheight(lheight: number, node: Node) { if (!node) return; let transform = node.getComponent(UITransform); if (!transform) return; // 使用映射表而不是多个if判断 transform.height = HEIGHT_MAP[lheight] || HEIGHT_MAP[1]; } // 更新位置 setPosition(x: number, y: number, z: number = 0) { this._position.set(x, y, z); this.node.setPosition(this._position); } // 更新缩放 setScale(x: number, y: number, z: number = 1) { this.node.setScale(x, y, z); } // 改变图标状态 changeIconState(iconState: ICON_STATE) { // if (this._state === iconState) return; // 避免重复设置状态 switch (iconState) { case ICON_STATE.ACTIVATE: this.node.active = true; break; case ICON_STATE.IDLE: this.showFastIcon(false); if (this._isWildOrScatter) { this.iconSpine.setAnimation(0, `${this.lHeight}_1`, true); } // else if (!this._isQKJ) { // this.iconSpine.setAnimation(1, "idle", true); // } break; case ICON_STATE.ROTATE: // 可以添加旋转相关逻辑 break; case ICON_STATE.FAST: this.showFastIcon(true); break; case ICON_STATE.WIN: this.showFastIcon(false); if (this._isWildOrScatter) { if (this.iconSpine && this.iconSpine.node) { this.iconSpine.node.active = true; this._normalSpriteNode && (this._normalSpriteNode.active = false); this.iconSpine.clearTracks(); this.iconSpine.setCompleteListener(null); this.iconSpine.setAnimation(0, `${this.lHeight}_2`, false); } } else if (this.iconSpine && this.iconSpine.node && !this._isQKJ) { this.iconSpine.node.active = true; this._normalSpriteNode && (this._normalSpriteNode.active = false); this.iconSpine.clearTracks(); this.iconSpine.setCompleteListener(null); this.iconSpine.setAnimation(0, 'xiaoshi', false); } if (this.iconSpine) { this.iconSpine.setCompleteListener(() => { this.iconSpine.setCompleteListener(null); if (this._isWildOrScatter) { this.iconSpine.setAnimation(0, `${this.lHeight}_1`, true); } else { this.iconSpine.clearTracks(); this.iconSpine.node.active = false; this._normalSpriteNode && (this._normalSpriteNode.active = true); } }); } break; case ICON_STATE.HIDE: this.node.active = false; break; } this._state = iconState; } playSpawnAni() { if (!this.iconSpine || !this.iconSpine.node) return; this.iconSpine.node.active = true; this._normalSpriteNode && (this._normalSpriteNode.active = false); // this.iconSpine.clearTracks(); // 使用计时器回调而不是匿名函数,减少闭包 this.playSpawnAnimation() } hideNormalSprite() { if (this._normalSpriteNode) this._normalSpriteNode.active = false; if (this._fastNode) this._fastNode.active = false; } private playSpawnAnimation() { if (!this.iconSpine) return; if (this._isWildOrScatter) { this.iconSpine.setAnimation(0, `${this.lHeight}_1`, true); // this.iconSpine.setCompleteListener(() => { // if (!this.iconSpine) return; // this.iconSpine.setAnimation(0, "1_1", true); // this.iconSpine.setCompleteListener(null); // }); } else if (this._isQKJ) { this.iconSpine.setAnimation(0, "animation", false); } else { this.iconSpine.setAnimation(0, "tan", false); } } // 显示/隐藏快速图标 showFastIcon(show: boolean) { if (this._isFastMode === show) return; // 避免重复设置 this._isFastMode = show; // 批量设置节点状态 if (this._normalNode) this._normalNode.active = !show; if (this._fastNode) this._fastNode.active = show; if (!show) { if (this._isWildOrScatter && this.iconSpine) { this.iconSpine.node.active = true; this._normalSpriteNode && (this._normalSpriteNode.active = false); this.iconSpine.clearTracks(); this.iconSpine.setCompleteListener(null); this.iconSpine.setAnimation(0, `${this.lHeight}_1`, true); } else if (this.iconSpine) { this.iconSpine.node.active = false; this.iconSpine.clearTracks(); // if (!this._isQKJ) { // this.iconSpine.setAnimation(0, "idle", true); // } this.iconSpine.setCompleteListener(null); this._normalSpriteNode && (this._normalSpriteNode.active = true); } } } // 播放获胜动画 playWinAni(show: boolean) { this.changeIconState(show ? ICON_STATE.WIN : ICON_STATE.IDLE); } // 1.2s playDeleteAni() { // 从对象池获取或重用winSpine节点 // let winSpine = NodePoolManager.instance.getNodeFromPoolStatic('winSpine', this.winSpinePrefab); // winSpine.setParent(this.node); // winSpine.setPosition(0, 0, 0); // winSpine.setScale(1, 1, 1); // let ascendWin = winSpine.getChildByName('Ascend_win'); // ascendWin.active = true; // let skeleton = ascendWin.getComponent(sp.Skeleton); // skeleton.setAnimation(0, `Sw_${this.lHeight}`, false); // skeleton.setCompleteListener(() => { // skeleton.setCompleteListener(null); // // 隐藏所有子节点 // let children = winSpine.children; // for (let i = 0; i < children.length; i++) { // children[i].active = false; // } // winSpine.removeFromParent(); // NodePoolManager.instance.putNodeToPool('winSpine', winSpine); // }) } playChangeAni(isChange: boolean) { if (isChange) { // let winSpine = NodePoolManager.instance.getNodeFromPoolStatic('winSpine', this.winSpinePrefab); // winSpine.setParent(this.node); // winSpine.setPosition(0, 0, 0); // winSpine.setScale(1, 1, 1); // let ascendWin = winSpine.getChildByName('Ascend_win'); // let ascendSwitch = winSpine.getChildByName('Ascend_switch'); // let skeleton1 = ascendWin.getComponent(sp.Skeleton); // let skeleton2 = ascendSwitch.getComponent(sp.Skeleton); // ascendWin.active = true; // skeleton1.setAnimation(0, `Sw_${this.lHeight}`, false); this.scheduleOnce(() => { // skeleton1.setCompleteListener(null); // ascendWin.active = false; // ascendSwitch.active = true; // skeleton2.setAnimation(0, `Sw_${this.lHeight}`, true); this.playChangeSprite(true); }, 1) } else { // 清理winSpine节点 // let winSpine = this.node.getChildByName('winSpine'); // if (winSpine) { // // 停用所有子节点 // let children = winSpine.children; // for (let i = 0; i < children.length; i++) { // children[i].active = false; // } // // 回收节点 // winSpine.removeFromParent(); // NodePoolManager.instance.putNodeToPool('winSpine', winSpine); // } // 停止精灵切换动画 this.playChangeSprite(false); } } playChangeSprite(isChange: boolean) { // 先清理之前的回调 if (this._iconChangeCallback) { this.unschedule(this._iconChangeCallback); this._iconChangeCallback = null; } if (isChange) { // 隐藏原始节点 if (this._normalSpriteNode) { this._normalSpriteNode.active = false; } // 复用现有changeNode或创建新的 let changeNode = this.node.getChildByName('ChangeSprite'); if (!changeNode) { changeNode = new Node('ChangeSprite'); changeNode.setParent(this.node); } if (this._normalSpriteNode) { changeNode.setPosition(this._normalSpriteNode.position); changeNode.setScale(this._normalSpriteNode.scale); } // 获取或添加Sprite组件 this._changeSprite = changeNode.getComponent(Sprite) || changeNode.addComponent(Sprite); // 复制原始Sprite的属性 if (this._normalSpriteNode) { let originalSprite = this._normalSpriteNode.getComponent(Sprite); if (originalSprite && originalSprite.spriteFrame) { this._changeSprite.spriteFrame = originalSprite.spriteFrame; this._changeSprite.sizeMode = originalSprite.sizeMode; this._changeSprite.trim = originalSprite.trim; } } // this._iconChangeCallback = this.updateChangeSpriteFrame; // this.schedule(this._iconChangeCallback, 0.1); } else { // 停止动画并清理 if (this._iconChangeCallback) { this.unschedule(this._iconChangeCallback); this._iconChangeCallback = null; } // 移除切换动画节点 if (this._changeSprite && this._changeSprite.node) { this._changeSprite.node.destroy(); this._changeSprite = null; } } } updateChangeSpriteFrame = () => { if (this._changeSprite) { this._changeSprite.spriteFrame = GameDataManager.instance.getRandomSymbol(); } } // 获取精灵帧 getSkeData(): sp.SkeletonData { return this.iconSpine ? this.iconSpine.skeletonData : null; } // 生命周期:组件禁用时 onDisable() { // 移除切换动画节点 if (this._changeSprite && this._changeSprite.node) { this._changeSprite.node.destroy(); this._changeSprite = null; } } protected onDestroy(): void { this.node.off(Node.EventType.TOUCH_END, this.onIconClick, this); } }