rp_11001/assets/Game/scripts/game/Icon.ts
TJH f466306084
All checks were successful
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 1m19s
代码整理
2025-12-22 16:17:40 +08:00

606 lines
19 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.

import { _decorator, Component, Node, Prefab, sp, Sprite, UITransform, Vec3, v3, EventTarget, SpriteAtlas, instantiate } 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.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.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);
} 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();
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 = instantiate(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, `${this.lHeight}`, false);
this.schedule(() => {
skeleton.setCompleteListener(null);
skeleton.clearTracks()
ascendWin.active = false;
// 隐藏所有子节点
let children = winSpine.children;
for (let i = 0; i < children.length; i++) {
children[i].active = false;
}
winSpine.removeFromParent();
}, 0.6)
}
playChangeAni(isChange: boolean) {
if (isChange) {
this.scheduleOnce(() => {
this.playChangeSprite(true);
}, 0.1)
} else {
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;
}
}
} 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);
}
}