import { _decorator, Animation, AnimationClip, Component, instantiate, Label, Node, Prefab, resources, Sprite, SpriteFrame, v3, tween, Vec3 } from 'cc'; import { oops } from 'db://oops-framework/core/Oops'; import { getHeroList, HeroInfo, HType, HTypeName } from '../common/config/heroSet'; import { smc } from '../common/SingletonModuleComp'; import { GameEvent } from '../common/config/GameEvent'; import { CCComp } from 'db://oops-framework/module/common/CCComp'; import { ecs } from 'db://oops-framework/libs/ecs/ECS'; const { ccclass, property } = _decorator; @ccclass('HInfoComp') @ecs.register('HInfoComp', false) export class HInfoComp extends CCComp { h_uuid:number=0 name_node:any=null type_node:any=null ap_node:any=null hp_node:any=null def_node:any=null // 重新定义节点映射,使名称更清晰 // 当前显示的英雄节点数组(7个位置) heroNodes: (Node | null)[] = [null, null, null, null, null, null, null]; // 英雄位置定义 hero_pos:any={ 0:v3(420,-109,0), // 不在屏幕内 1:v3(280,-109,0), 2:v3(140,-109,0), 3:v3(0,-109,0), 4:v3(-140,-109,0), 5:v3(-280,-109,0), 6:v3(-420,-109,0), // 不在屏幕内 } // 动画锁定标志:防止快速点击导致的动画冲突 private isMoving: boolean = false; // 保存待处理的setTimeout句柄,用于取消前一个异步操作 private moveTimeoutId: any = null; protected onLoad(): void { // this.on(GameEvent.MissionStart,this.mission_start,this) } // 位置索引常量 private static center_pos = 3; start() { this.name_node=this.node.getChildByName("hero").getChildByName("hname").getChildByName("name") this.type_node=this.node.getChildByName("hero").getChildByName("hname").getChildByName("type") this.ap_node=this.node.getChildByName("info").getChildByName("base").getChildByName("ap").getChildByName("num") this.hp_node=this.node.getChildByName("info").getChildByName("base").getChildByName("hp").getChildByName("num") this.def_node=this.node.getChildByName("info").getChildByName("base").getChildByName("def").getChildByName("num") this.h_uuid=smc.fight_hero this.update_data(this.h_uuid) this.load_all_hero(this.h_uuid) } update(deltaTime: number) { } update_data(uuid:number){ this.h_uuid=uuid this.name_node.getComponent(Label).string=HeroInfo[uuid].name this.type_node.getComponent(Label).string=HTypeName[HeroInfo[uuid].type] this.ap_node.getComponent(Label).string=HeroInfo[uuid].ap.toString() this.hp_node.getComponent(Label).string=HeroInfo[uuid].hp.toString() this.def_node.getComponent(Label).string=HeroInfo[uuid].def.toString() } load_all_hero(uuid:number){ // 清除之前的英雄节点 this.claear_hero(); // 获取英雄列表 let heros = getHeroList(); let currentIndex = heros.indexOf(uuid); // 载入7个英雄节点(当前英雄及前后各3个) for(let i = 0; i < 7; i++) { // 计算索引位置(考虑循环) let indexOffset = i - 3; // -3, -2, -1, 0, 1, 2, 3 let heroIndex = currentIndex + indexOffset; // 处理循环边界 if(heroIndex < 0) { heroIndex = heros.length + heroIndex; } else if(heroIndex >= heros.length) { heroIndex = heroIndex - heros.length; } // 获取英雄UUID let heroUuid = heros[heroIndex]; // 载入英雄预制体并设置位置 this.heroNodes[i] = this.load_hui(heroUuid, i); } } load_hui(uuid:number, pos_index: number){ var path = "game/gui/hui"; var prefab: Prefab = oops.res.get(path, Prefab)!; var node = instantiate(prefab); // 将节点添加到父节点下 this.node.getChildByName("hero").addChild(node); // 设置节点位置 node.setPosition(this.hero_pos[pos_index]); // 加载并播放动画 let anm_path=HeroInfo[uuid].path; resources.load("game/heros/hero/"+anm_path+"/idle", AnimationClip, (err, clip) => { if (!err && clip) { let animComponent = node.getComponent(Animation); if(animComponent) { animComponent.addClip(clip); animComponent.play("idle"); } } else { console.error(`[HInfoComp]: Failed to load animation for hero ${uuid}`, err); } }); return node; } mission_start(){ this.claear_hero() } claear_hero(){ for (let i = 0; i < this.heroNodes.length; i++) { if (this.heroNodes[i]) { this.heroNodes[i].destroy(); this.heroNodes[i] = null; } } } next_hero(){ // 检查是否正在动画中,防止快速点击导致的冲突 if (this.isMoving) return; // 获取英雄列表 let heros = getHeroList(); let index = heros.indexOf(this.h_uuid); index++; if(index == heros.length) index = 0; let nextHero = heros[index]; // 更新数据 this.h_uuid = nextHero; smc.updateFihgtHero(nextHero) this.update_data(nextHero); // 执行平滑移动动画 this.moveHeroesRight(); } prev_hero(){ // 检查是否正在动画中,防止快速点击导致的冲突 if (this.isMoving) return; // 获取英雄列表 let heros = getHeroList(); let index = heros.indexOf(this.h_uuid); index--; if(index == -1) index = heros.length - 1; let prevHero = heros[index]; // 更新数据 this.h_uuid = prevHero; smc.updateFihgtHero(prevHero) this.update_data(prevHero); // 执行平滑移动动画 this.moveHeroesLeft(); } moveHeroesLeft() { // 取消前一个待处理的异步操作 if (this.moveTimeoutId !== null) { clearTimeout(this.moveTimeoutId); } // 设置动画锁定 this.isMoving = true; // 在动画开始前,直接销毁hero_pos[6]上的节点 if (this.heroNodes[6]) { this.heroNodes[6].destroy(); this.heroNodes[6] = null; } // 移动所有现有节点向左(除了已销毁的heroNodes[6]) for (let i = 0; i < 6; i++) { if (this.heroNodes[i]) { // 计算目标位置:向左移动 let targetPos = this.hero_pos[i + 1]; // 使用Tween执行平滑移动 tween(this.heroNodes[i]) .to(0.2, { position: targetPos }) .start(); } } // 延迟重排数组和创建新节点,等待动画完成 this.moveTimeoutId = setTimeout(() => { // 移动数组元素(向后平移) for (let i = 6; i > 0; i--) { this.heroNodes[i] = this.heroNodes[i - 1]; } // 创建新节点放在hero_pos[0]位置 let heros = getHeroList(); let currentIndex = heros.indexOf(this.h_uuid); let newIndex = currentIndex - 3; // 新的最左侧英雄索引 // 处理循环边界 if (newIndex < 0) { newIndex = heros.length + newIndex; } this.heroNodes[0] = this.load_hui(heros[newIndex], 0); // 动画完成,解除锁定 this.isMoving = false; this.moveTimeoutId = null; }, 200); // 与动画时间保持一致 } moveHeroesRight() { // 取消前一个待处理的异步操作 if (this.moveTimeoutId !== null) { clearTimeout(this.moveTimeoutId); } // 设置动画锁定 this.isMoving = true; // 在动画开始前,直接销毁hero_pos[0]上的节点 if (this.heroNodes[0]) { this.heroNodes[0].destroy(); this.heroNodes[0] = null; } // 移动所有现有节点向右(除了已销毁的heroNodes[0]) for (let i = 1; i < this.heroNodes.length; i++) { if (this.heroNodes[i]) { // 计算目标位置:向右移动 let targetPos = this.hero_pos[i - 1]; // 使用Tween执行平滑移动 tween(this.heroNodes[i]) .to(0.2, { position: targetPos }) .start(); } } // 延迟重排数组和创建新节点,等待动画完成 this.moveTimeoutId = setTimeout(() => { // 移动数组元素(向前平移) for (let i = 0; i < 6; i++) { this.heroNodes[i] = this.heroNodes[i + 1]; } // 创建新节点放在hero_pos[6]位置 let heros = getHeroList(); let currentIndex = heros.indexOf(this.h_uuid); let newIndex = currentIndex + 3; // 新的最右侧英雄索引 // 处理循环边界 if (newIndex >= heros.length) { newIndex = newIndex - heros.length; } this.heroNodes[6] = this.load_hui(heros[newIndex], 6); // 动画完成,解除锁定 this.isMoving = false; this.moveTimeoutId = null; }, 200); // 与动画时间保持一致 } reset() { this.node.destroy() } }