import { _decorator, Component, Label, Node, Tween, tween } from 'cc'; import { GBundle } from '../game/ConfigRes'; import { TetriType } from '../game/ConfigProjectData'; import { tetriNode } from './tetriNode'; const { ccclass } = _decorator; /**方块功能脚本不是战斗类型的方块 * TetriType == 3 每秒给一个金币 * TetriType == 4 每秒恢复特定的玩家血量 */ @ccclass('tetriAbility') export class tetriAbility extends Component { /** 旧版:飘字挂在「角色」local(0,50)→(0,150),角色带 mainPosi 与 scale */ private static readonly ICON_PREFAB_SCALE = 4; private static readonly ICON_FLOAT_START_Y = 50; private static readonly ICON_FLOAT_END_Y = 150; private static readonly ICON_LAYOUT: Record = { Tetris_coin_1: { scaleX: -0.25, scaleY: 0.25, mainPosi: { x: -2.225, y: -19.558 } }, Tetris_heal_1: { scaleX: -0.15, scaleY: 0.15, mainPosi: { x: -1.523, y: -8.577 } }, Tetris_heal_2: { scaleX: -0.15, scaleY: 0.15, mainPosi: { x: -0.473, y: -10.624 } }, }; private _config: ITableBattleCube | null = null; private _curentWeaponId: number = 0; cdTimeFix = 0 cdTime = 0 addValue = 0 setConfig(config: ITableBattleCube) { this._config = config this._curentWeaponId = config.weaponid this._removeLegacyRoleNodes() this.setView() } start() { this._removeLegacyRoleNodes() if (this._config) { this.setView() } } /** 旧版会在方块下挂「角色」预制体;现改为方块 spine 表情,不再创建 */ private _removeLegacyRoleNodes(): void { if (!this.node?.isValid) return; const kids = this.node.children.slice(); for (const ch of kids) { if (ch?.isValid && ch.name === '角色') { ch.destroy(); } } } setView() { let conf = gg.data.project.getWeaponData(this._curentWeaponId) if (!conf) { return } this.cdTime = conf.cd this.cdTimeFix = conf.cd let weaponLevel = gg.data.project.getWeaponLevel(conf.id); let levelPara = gg.data.project.getLevelParaByWeaponLevel(weaponLevel, conf.id) let weapon_para = conf.weapon_para this.addValue = Math.floor(weapon_para * levelPara) } /** 挂到方块根节点时,用锚点复刻旧版「角色」→飘字层级(prefab scale=4 由角色 scale 缩小) */ private _setupFloatingIcon(iconNode: Node, addNum: number): void { const layout = tetriAbility.ICON_LAYOUT[this._config?.cubename ?? ''] ?? { scaleX: -0.25, scaleY: 0.25, mainPosi: { x: 0, y: 0 } }; Tween.stopAllByTarget(iconNode); const anchor = new Node('__floatIconAnchor'); anchor.setParent(this.node); anchor.setPosition(layout.mainPosi.x, layout.mainPosi.y, 0); anchor.setScale(layout.scaleX, layout.scaleY, 1); iconNode.setParent(anchor); iconNode.active = true; iconNode.setScale(tetriAbility.ICON_PREFAB_SCALE, tetriAbility.ICON_PREFAB_SCALE, 1); iconNode.setPosition(0, tetriAbility.ICON_FLOAT_START_Y, 0); iconNode.opacity = 100; const labNode = iconNode.getChildByName('lab'); // prefab 默认 scaleX=-1,配合 anchor 负 scaleX,文字方向与旧版一致 labNode?.setScale(-1, 1, 1); const lab = labNode?.getComponent(Label); if (lab) { lab.string = '+' + addNum.toString(); } tween(iconNode) .to(0.5, { y: tetriAbility.ICON_FLOAT_END_Y, opacity: 255 }) .call(() => { Tween.stopAllByTarget(iconNode); if (iconNode?.isValid) { labNode?.setScale(-1, 1, 1); iconNode.setScale(tetriAbility.ICON_PREFAB_SCALE, tetriAbility.ICON_PREFAB_SCALE, 1); gg.res.putNode(iconNode); } if (anchor?.isValid) { anchor.destroy(); } }) .start(); } update(deltaTime: number) { if (!this._config) return; if (!this.node.getComponent(tetriNode)?.isSettled) { return } if (!gg.game?.CurentBattle?.canUpdateFrame() && !gg.game?.CurentBattle?.IsWarnTimeActive) return; this.cdTime += deltaTime * gg.game.CurentBattle.TimeScale if (this.cdTime >= this.cdTimeFix) { this.cdTime = 0 this.addValueFunc() } } addValueFunc() { if (!this._config) return; if (!this.node.getComponent(tetriNode)?.isSettled) { return } let getNodeLevel = this.node.getComponent(tetriNode)?.getNodeLevel() || 1 let addNum = this.addValue * getNodeLevel; if (this._config.type == TetriType.Tetris_BaseGold) { gg.game.CurentBattle.curentCoinNumChange(addNum); void gg.res.getNodeAsync('角色/', '金币icon', GBundle.tetriCards).then((iconNode) => { if (!iconNode?.isValid || !this.node?.isValid) return; this._setupFloatingIcon(iconNode, addNum); }); } else if (this._config.type == TetriType.Tetris_Baseheal) { gg.game.CurentBattle.addWallHp(addNum); void gg.res.getNodeAsync('角色/', '爱心icon', GBundle.tetriCards).then((iconNode) => { if (!iconNode?.isValid || !this.node?.isValid) return; this._setupFloatingIcon(iconNode, addNum); }); } } }