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 { TetriType } from '../game/ConfigProjectData'; import { tetriNode } from './tetriNode'; import { role } from './role'; const { ccclass, property } = _decorator; /**方块功能脚本不是战斗类型的方块 * TetriType == 3 每秒给一个金币 * TetriType == 4 每秒恢复特定的玩家血量 */ @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 }, ] private _config: ITableBattleCube | null = null; private _curentWeaponId: number = 0; cdTimeFix = 0 cdTime = 0 addValue = 0 roleNode: Node = null; weaponNode: Node = null; /** 异步创建角色进行中,防止 setConfig/start 并发各拉一个 */ private _roleCreating = false; setConfig(config: ITableBattleCube){ this._config = config this._curentWeaponId = config.weaponid this.addRole() } 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._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; } } const roleComp = roleNode.getComponent(role); roleComp.setFollowTarget(this.node); this.scheduleOnce(()=>{ this.setView() },0.1) } setView(){ let conf = gg.data.project.getWeaponData(this._curentWeaponId) //console.log('tetriAbility conf',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) } changeWeapon(weaponani){ return // if(this.weaponNode){ // gg.res.putNode(this.weaponNode) // this.weaponNode = null // } // this.addWeapon(weaponani) } // //增加武器和修改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) // anim.getComponent(sp.Skeleton).setAnimation(0, '待机', true) // weaponNode.getComponent(sp.Skeleton).setAnimation(0, '待机', true) // } changeIcon(typeicon){ } update(deltaTime: number) { // // if(!this.roleNode){ 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.node.getComponent(tetriNode)?.isSettled){ return } if(!this.roleNode){ return } if(!this.roleNode.isValid){ 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){ //加钱 加银币 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() }); }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() }); } } }