From 47835bb8f44bdf6dbf705f89c2c6465a3b20a452 Mon Sep 17 00:00:00 2001 From: chenanghui <220722433@qq.com> Date: Thu, 27 Aug 2026 19:54:20 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96=E9=87=91=E5=B8=81=E6=96=B9?= =?UTF-8?q?=E5=9D=97=E8=B7=9F=E5=9B=9E=E8=A1=80=E6=96=B9=E5=9D=97=E4=BC=9A?= =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E4=B9=8B=E5=89=8D=E8=8B=B1=E9=9B=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- assets/script/tetriCard/tetriAbility.ts | 286 +++++++----------------- 1 file changed, 77 insertions(+), 209 deletions(-) diff --git a/assets/script/tetriCard/tetriAbility.ts b/assets/script/tetriCard/tetriAbility.ts index 9aba282..9cc7b6e 100644 --- a/assets/script/tetriCard/tetriAbility.ts +++ b/assets/script/tetriCard/tetriAbility.ts @@ -1,10 +1,8 @@ -import { _decorator, Component, find, isValid, Label, Node, sp, Tween, tween } from 'cc'; -import { SpriteLoad } from '../../mx/components/SpriteLoad'; -import { GBundle, GPath } from '../game/ConfigRes'; +import { _decorator, Component, Label, Node, Tween, tween } from 'cc'; +import { GBundle } from '../game/ConfigRes'; import { TetriType } from '../game/ConfigProjectData'; import { tetriNode } from './tetriNode'; -import { role } from './role'; -const { ccclass, property } = _decorator; +const { ccclass } = _decorator; /**方块功能脚本不是战斗类型的方块 * TetriType == 3 每秒给一个金币 @@ -13,14 +11,15 @@ const { ccclass, property } = _decorator; @ccclass('tetriAbility') export class tetriAbility extends Component { - roleConfig = [ - {id:1, name:"Tetris_coin_1", mainPosi:{x:-2.225,y:-19.558},animSkin:'小黄',scalex:-0.25, scaley:0.25 }, - {id:2, name:"Tetris_heal_1", mainPosi:{x:-1.523,y:-8.577},animSkin:'小绿',scalex:-0.15, scaley:0.15 }, - {id:3, name:"Tetris_heal_2", mainPosi:{x:-0.473,y:-10.624},animSkin:'小绿',scalex:-0.15, scaley:0.15 }, - - ] - - + /** 旧版:飘字挂在「角色」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; @@ -30,254 +29,123 @@ export class tetriAbility extends Component { addValue = 0 - roleNode: Node = null; - weaponNode: Node = null; - /** 异步创建角色进行中,防止 setConfig/start 并发各拉一个 */ - private _roleCreating = false; - - setConfig(config: ITableBattleCube){ + setConfig(config: ITableBattleCube) { this._config = config this._curentWeaponId = config.weaponid - this.addRole() + this._removeLegacyRoleNodes() + this.setView() } start() { - //功能方块:setConfig 通常已调过 addRole;此处兜底,靠 inflight/roleNode 防重 - this.addRole() - } - private safePutPoolNode(n: Node | null): void { - if (!n) return; - if (!isValid(n)) return; - try { - if (n.parent) n.destroy(); - //gg.res.putNode(n); - } catch (e) { - console.warn('[tetriWeaponCarrier] safePutPoolNode failed', e); - } - } - onDestroy(): boolean { - gg.game?.CurentBattle?.pruneDetachedBattleLayers?.(this.node); - const role = this.roleNode; - - this.roleNode = null; - this._roleCreating = false; - // 武器挂在「角色/武器」下,先回收武器再回收角色,避免子随父一起进半销毁态 - - this.safePutPoolNode(role); - return true - } - - addRole(){ - if(this.roleNode || this._roleCreating){ - return - } - if(!this._config){ - return - } - // instantiate / 拷贝可能已带「角色」;清掉多余的,避免叠两个 - let existingRole: Node | null = null; - for (let i = 0; i < this.node.children.length; i++) { - const c = this.node.children[i]; - if (c.name !== '角色') continue; - if (!existingRole) existingRole = c; - else if (c?.isValid) c.destroy(); - } - if (existingRole?.isValid) { - this._setupRoleNode(existingRole); - return; + this._removeLegacyRoleNodes() + if (this._config) { + this.setView() } - this._roleCreating = true; - void gg.res.getNodeAsync('角色/', '角色', GBundle.tetriCards).then((roleNode) => { - this._roleCreating = false; - if(!roleNode?.isValid || !this.node?.isValid){ - return - } - // 并发回调晚到:已有角色则销毁多余实例 - if (this.roleNode?.isValid) { - this.safePutPoolNode(roleNode); - return; - } - this._setupRoleNode(roleNode); - }); } - private _setupRoleNode(roleNode: Node) { - this.roleNode = roleNode - roleNode.setParent(this.node) - roleNode.active = true - let conf = this.roleConfig.find(item => item.name == this._config.cubename) - if(conf){ - roleNode.setPosition(conf.mainPosi.x, conf.mainPosi.y) - roleNode.setScale(conf.scalex, conf.scaley) - const anim = roleNode.getChildByName('anim'); - const animSk = anim?.getComponent(sp.Skeleton); - if (animSk) { - animSk.setSkin(conf.animSkin); - } - // 产币/回血改用方块根节点 spine 三态表情;旧「角色/anim」仅产效时短暂播放 - if (anim?.isValid) { - anim.active = false; + /** 旧版会在方块下挂「角色」预制体;现改为方块 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(); } } - - const roleComp = roleNode.getComponent(role); - roleComp.setFollowTarget(this.node); - - this.scheduleOnce(()=>{ - this.setView() - },0.1) } - setView(){ + setView() { let conf = gg.data.project.getWeaponData(this._curentWeaponId) - //console.log('tetriAbility conf',conf) - if(!conf){ + 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) - this.changeIcon(conf.typeicon) - - console.log('tetriAbility addValue',this.addValue) } + /** 挂到方块根节点时,用锚点复刻旧版「角色」→飘字层级(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 } }; - changeWeapon(weaponani){ - return - // if(this.weaponNode){ - // gg.res.putNode(this.weaponNode) - // this.weaponNode = null - // } - // this.addWeapon(weaponani) - } + Tween.stopAllByTarget(iconNode); - // //增加武器和修改icon图片 - // addWeapon(weaponani){ - // //创建武器 - - // let anim = find('角色/anim', this.node) - // let wuqiNode = find('角色/武器', this.node) - // let weaponNode = gg.res.getNode('prefab/', weaponani, GBundle.tetriWeapon) - // this.weaponNode = weaponNode - // weaponNode.setParent(wuqiNode) + 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); - // anim.getComponent(sp.Skeleton).setAnimation(0, '待机', true) - // weaponNode.getComponent(sp.Skeleton).setAnimation(0, '待机', true) - // } + 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; - changeIcon(typeicon){ - - - } + 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.roleNode){ + if (!this._config) return; + if (!this.node.getComponent(tetriNode)?.isSettled) { 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 += deltaTime * gg.game.CurentBattle.TimeScale + if (this.cdTime >= this.cdTimeFix) { this.cdTime = 0 this.addValueFunc() } - - } - - addValueFunc(){ - - //没有放稳不生效 - if(!this.node.getComponent(tetriNode)?.isSettled){ - return - } - if(!this.roleNode){ - return - } - if(!this.roleNode.isValid){ + addValueFunc() { + if (!this._config) return; + if (!this.node.getComponent(tetriNode)?.isSettled) { return } - let anim = find('anim', this.roleNode) - if (!anim?.isValid) return; - anim.active = true; - anim.getComponent(sp.Skeleton).setAnimation(0, '攻击', false) - this.scheduleOnce(()=>{ - if (!anim?.isValid) return; - anim.getComponent(sp.Skeleton).setAnimation(0, '待机', true) - anim.active = false; - },1) - let getNodeLevel = this.node.getComponent(tetriNode)?.getNodeLevel() || 1 let addNum = this.addValue * getNodeLevel; - if(this._config.type == TetriType.Tetris_BaseGold){ - //加钱 加银币 + if (this._config.type == TetriType.Tetris_BaseGold) { gg.game.CurentBattle.curentCoinNumChange(addNum); - void gg.res.getNodeAsync('角色/', '金币icon', GBundle.tetriCards).then((iconNode) => { - if (!iconNode?.isValid) return; - //播动画 - let jueseNode = this.roleNode//find('角色', this.node) - iconNode.setParent(jueseNode) - iconNode.active = true - - let lab = iconNode.getChildByName('lab').getComponent(Label) - iconNode.setPosition(0,50) - iconNode.opacity = 100 - lab.string = '+' + addNum.toString() - let posiy = iconNode.y - tween(iconNode) - .to(0.5,{y:150, opacity:255}) - .call(()=>{ - gg.res.putNode(iconNode) - iconNode = null - }) - .start() + if (!iconNode?.isValid || !this.node?.isValid) return; + this._setupFloatingIcon(iconNode, addNum); }); - }else if(this._config.type == TetriType.Tetris_Baseheal){ - //回血 + } 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) return; - //播动画 - let jueseNode = this.roleNode//find('角色', this.node) - iconNode.setParent(jueseNode) - iconNode.active = true - - let lab = iconNode.getChildByName('lab').getComponent(Label) - lab.string = '+' + addNum.toString() - let posiy = iconNode.y - iconNode.setPosition(0,50) - iconNode.opacity = 100 - tween(iconNode) - .to(0.5,{y:150, opacity:255}) - .call(()=>{ - gg.res.putNode(iconNode) - iconNode = null - }) - .start() + if (!iconNode?.isValid || !this.node?.isValid) return; + this._setupFloatingIcon(iconNode, addNum); }); } - - - } } - -