import { _decorator, resources, Sprite, SpriteAtlas ,Node, ProgressBar, tween, v3, Label, Animation, CCString, CCInteger, sp} from "cc"; import { ecs } from "../../../../extensions/oops-plugin-framework/assets/libs/ecs/ECS"; import { CCComp } from "../../../../extensions/oops-plugin-framework/assets/module/common/CCComp"; import { GameEvent } from "../common/config/GameEvent"; import { CdType, SkillSet } from "../common/config/SkillSet"; import { smc } from "../common/SingletonModuleComp"; import { oops } from "db://oops-framework/core/Oops"; import { MissionEvent } from "../common/config/MissionEvent"; import { HeroInfo } from "../common/config/heroSet"; const { ccclass, property } = _decorator; /** 英雄数据接口 */ interface HeroData { uuid: number; name: string; type: number; // 1 被动 0 主动 level: number; quality: number; cd: number; cd_time: number; active: boolean; } /** 视图层对象 */ @ccclass('HeroUiComp') @ecs.register('HeroUi', false) export class HeroUiComp extends CCComp { heroes: HeroData[] = [] private readonly MAX_HEROES = 3 private readonly HERO_NODE_NAMES = ['hero1', 'hero2', 'hero3'] /** 视图层逻辑代码分离演示 */ onLoad() { this.on(GameEvent.FightReady,this.fight_ready,this) this.on(GameEvent.UseHeroCard,this.get_hero,this) this.on(GameEvent.FightEnd,this.fight_end,this) // this.node.getChildByName("icon").getChildByName("cd").active=false } start(){ this.fight_ready() } fight_end(){ this.heroes=[] this.clearAllHeroIcons() } fight_ready(){ console.log("[HeroUiComp]: fight_ready",this.node) this.heroes = [] for(let i = 0; i < this.MAX_HEROES; i++) { this.heroes.push(this.createDefaultHero()) } } private createDefaultHero(): HeroData { return { uuid: 0, name: "hero", type: 0, //1 被动 0 主动 level: 1, quality: 0, cd: 0, cd_time: 0, active: false, } } update(dt: number): void { if(!smc.mission.play||smc.mission.pause) return } get_hero(e: GameEvent, data: { uuid: number }) { console.log("[HeroUiComp]: get_hero", data) // 尝试升级现有英雄 if (this.tryUpgradeExistingHero(data.uuid)) { return } // 添加新英雄 this.addNewHero(data) } /** * 尝试升级现有英雄 * @param uuid 英雄UUID * @returns 是否成功升级 */ private tryUpgradeExistingHero(uuid: number): boolean { for (let i = 0; i < this.heroes.length; i++) { if (this.heroes[i].uuid === uuid) { this.heroes[i].level++ // 播放升级动画 this.playCardScaleAnimation(i) return true } } return false } /** * 添加新英雄 * @param data 英雄数据 */ private addNewHero(data: { uuid: number }) { const heroInfo = HeroInfo[data.uuid] if (!heroInfo) { console.error("[HeroUiComp]: Hero info not found for uuid:", data.uuid) return } // 查找空闲位置 const emptySlotIndex = this.findEmptyHeroSlot() if (emptySlotIndex === -1) { console.warn("[HeroUiComp]: No empty slot available for new hero") return } // 设置英雄数据 this.heroes[emptySlotIndex] = { uuid: data.uuid, name: heroInfo.name, type: heroInfo.type, level: 1, quality: heroInfo.quality, cd: 0, cd_time: 0, active: false, } // 更新UI this.updateHeroUI(emptySlotIndex, heroInfo) // 播放新卡牌动画 this.playCardScaleAnimation(emptySlotIndex) } /** * 查找空闲英雄槽位 * @returns 空闲槽位索引,-1表示没有空闲槽位 */ private findEmptyHeroSlot(): number { for (let i = 0; i < this.heroes.length; i++) { if (this.heroes[i].uuid === 0) { return i } } return -1 } /** * 更新英雄UI(图标和信息) * @param heroIndex 英雄索引 * @param heroInfo 英雄信息 */ private updateHeroUI(heroIndex: number, heroInfo: { path: string }) { const heroNodeName = this.HERO_NODE_NAMES[heroIndex] const heroNode = this.node.getChildByName(heroNodeName) if (!heroNode) return const iconNode = heroNode.getChildByName("icon") if (iconNode) { iconNode.active = true this.loadHeroIcon(iconNode, heroInfo.path) } } /** * 加载英雄图标 * @param iconNode 图标节点 * @param heroPath 英雄路径 */ private loadHeroIcon(iconNode: Node, heroPath: string) { iconNode.parent.getChildByName("iconbg").active=false const icon_path = "game/heros/heros/"+heroPath // resources.load(icon_path, sp.SkeletonData, (err, skeleton) => { // if(err) return // const spine = iconNode.getComponent(sp.Skeleton); // if (spine) { // spine.skeletonData = skeleton; // spine.setAnimation(0, "Idle", true); // } // else{ // console.error("[HeroUiComp]: loadHeroIcon error",err) // } // }); } /** * 播放卡牌缩放动画 * @param heroIndex 英雄索引 */ private playCardScaleAnimation(heroIndex: number) { const heroNodeName = this.HERO_NODE_NAMES[heroIndex] const heroNode = this.node.getChildByName(heroNodeName) if (!heroNode) return // 停止可能存在的动画 tween(heroNode).stop() // 播放缩放动画:放大 -> 恢复原始大小 tween(heroNode) .to(0.1, { scale: v3(1.2, 1.2, 1) }, { easing: 'backOut' }) .to(0.15, { scale: v3(1, 1, 1) }, { easing: 'backOut' }) .start() } /** * 清空英雄图标 * @param heroIndex 英雄索引 */ private clearHeroIcon(heroIndex: number) { const heroNodeName = this.HERO_NODE_NAMES[heroIndex] const heroNode = this.node.getChildByName(heroNodeName) if (!heroNode) return const iconNode = heroNode.getChildByName("icon") if (iconNode) { iconNode.active = false } heroNode.getChildByName("iconbg").active=true } /** * 清空所有英雄图标 */ public clearAllHeroIcons() { for (let i = 0; i < this.MAX_HEROES; i++) { this.clearHeroIcon(i) } } /** 视图对象通过 ecs.Entity.remove(ModuleViewComp) 删除组件是触发组件处理自定义释放逻辑 */ reset() { this.node.destroy(); } }