import { _decorator, Component, Node, Button, find, Label, Sprite, Vec3, CCFloat, resources, JsonAsset, SpriteFrame } from 'cc'; import { GameManager } from '../../LevelSystem/GameManager'; import { InGameManager } from '../../LevelSystem/IN_game'; import { SkillButtonAnimator } from './SkillButtonAnimator'; // GamePause已通过事件系统解耦,不再需要直接导入 import { SkillManager, SkillData } from './SkillManager'; import { Wall } from '../Wall'; import { EnemyController } from '../EnemyController'; import EventBus, { GameEvents } from '../../Core/EventBus'; const { ccclass, property } = _decorator; // 移除本地SkillData声明,直接用SkillManager中的SkillData interface SkillConfig { skills: SkillData[]; } /** * SkillSelectionController * 放在 Canvas/SelectSkillUI 节点上。 * 负责监听技能按钮点击,随机选择技能显示,并按顺序播放缩小动画,最后关闭整个 SelectSkillUI。 */ @ccclass('SkillSelectionController') export class SkillSelectionController extends Component { @property({ type: [Node], tooltip: '技能按钮节点列表,留空则自动从 SkillsContainer 获取' }) public skillButtons: Node[] = []; @property({ type: CCFloat, tooltip: '收缩动画时长' }) public shrinkDuration: number = 0.3; // 防止重复点击标记 private _clicked = false; // 技能配置数据 private _skillConfig: SkillConfig | null = null; // 当前显示的技能数据 private _currentSkills: SkillData[] = []; start() { this.loadSkillConfig(); } /** * 加载技能配置 */ private loadSkillConfig() { resources.load('data/skill', JsonAsset, (err, jsonAsset: JsonAsset) => { if (err) { console.error('加载技能配置失败:', err); return; } this._skillConfig = jsonAsset.json as SkillConfig; // 初始化技能管理器 const skillManager = SkillManager.getInstance(); if (skillManager) { skillManager.initSkills(this._skillConfig.skills); } this.setupSkillButtons(); this.randomizeSkills(); }); } private setupSkillButtons() { if (this.skillButtons.length === 0) { const container = this.node.getChildByName('SkillsContainer'); if (container) { this.skillButtons = container.children.slice(); } } this.skillButtons.forEach(btnNode => { const btn = btnNode.getComponent(Button); if (btn) { btn.node.on(Button.EventType.CLICK, () => this.onSkillSelected(btnNode), this); } }); } /** * 随机选择3个技能显示 */ private randomizeSkills() { if (!this._skillConfig || this._skillConfig.skills.length < 3) { console.error('技能配置不足,无法随机选择'); return; } // 从6个技能中随机选择3个 const allSkills = [...this._skillConfig.skills]; this._currentSkills = []; for (let i = 0; i < 3 && allSkills.length > 0; i++) { const randomIndex = Math.floor(Math.random() * allSkills.length); this._currentSkills.push(allSkills.splice(randomIndex, 1)[0]); } // 更新UI显示 this.updateSkillUI(); } /** * 更新技能UI显示 */ private updateSkillUI() { this.skillButtons.forEach((btnNode, index) => { if (index < this._currentSkills.length) { const skillData = this._currentSkills[index]; // 更新技能图标 const skillSprite = btnNode.getChildByName('SkillSprite'); if (skillSprite) { const sprite = skillSprite.getComponent(Sprite); if (sprite) { // 加载技能图标 - 参考UpgradeController的加载方式,在路径后添加'/spriteFrame' const framePath = `${skillData.icon}/spriteFrame`; resources.load(framePath, SpriteFrame, (err, spriteFrame) => { if (!err && spriteFrame && sprite && sprite.isValid) { sprite.spriteFrame = spriteFrame; console.log(`技能图标加载成功: ${skillData.icon}`); } else if (err) { console.warn(`加载技能图标失败: ${skillData.icon}`, err); } }); } } // 更新技能名称 const skillName = btnNode.getChildByName('SkillName'); if (skillName) { const label = skillName.getComponent(Label); if (label) { label.string = skillData.name; } } // 更新技能介绍 const skillIntroduce = btnNode.getChildByName('SkillIntroduce'); if (skillIntroduce) { const label = skillIntroduce.getComponent(Label); if (label) { label.string = skillData.description; } } // 设置星级显示 - 从SkillManager获取实际的技能等级 const animator = btnNode.getComponent(SkillButtonAnimator); if (animator) { const skillManager = SkillManager.getInstance(); const actualLevel = skillManager ? skillManager.getSkillLevel(skillData.id) : 0; animator.setSkillLevel(actualLevel); console.log(`设置技能 ${skillData.name} 星级: ${actualLevel}`); } btnNode.active = true; } else { btnNode.active = false; } }); } /** * 玩家选择某技能按钮 */ private onSkillSelected(selectedBtn: Node) { if (this._clicked) return; this._clicked = true; // 获取选中的技能 const btnIndex = this.skillButtons.indexOf(selectedBtn); if (btnIndex >= 0 && btnIndex < this._currentSkills.length) { const selectedSkill = this._currentSkills[btnIndex]; // 通过技能管理器升级技能 const skillManager = SkillManager.getInstance(); if (skillManager) { skillManager.upgradeSkill(selectedSkill.id); // 立即更新UI显示新的星级 this.updateSkillUI(); // 如果是治疗技能,立即应用治疗效果 if (selectedSkill.id === 'heal') { this.applyHealEffect(selectedSkill.id); } } } const otherBtns = this.skillButtons.filter(btn => btn !== selectedBtn); let finishedOthers = 0; // 所有其他按钮完成动画后,再收缩选中按钮 const onOtherFinished = () => { finishedOthers++; if (finishedOthers >= otherBtns.length) { // 收缩选中按钮 const selAnim = selectedBtn.getComponent(SkillButtonAnimator); selAnim?.playShrink(this.shrinkDuration, undefined, () => { const igm = this.getInGameManager(); if (igm) { igm.resetEnergyValue(); // 检查是否需要播放diban动画 // 通过InGameManager处理后续逻辑 igm.onSkillSelectionComplete(); } // 关闭后立刻重置UI this.resetUI(); }); } }; // 播放其他按钮动画 const targetPos = selectedBtn.position.clone(); otherBtns.forEach(btn => { const anim = btn.getComponent(SkillButtonAnimator); anim?.playShrink(this.shrinkDuration, targetPos, onOtherFinished); }); } /** * 重置 UI 状态,供下次开启时使用 */ public resetUI() { this._clicked = false; // 重新启用所有按钮交互 this.skillButtons.forEach(btn => { // 重置按钮动画状态 const anim = btn.getComponent(SkillButtonAnimator); anim?.resetState(); }); // 重新随机选择技能 this.randomizeSkills(); } /** * 应用治疗技能效果 */ private applyHealEffect(skillId: string) { const skillManager = SkillManager.getInstance(); if (!skillManager) return; const skillLevel = skillManager.getSkillLevel(skillId); if (skillLevel <= 0) return; // 查找墙体组件 const wall = this.findWallComponent(); if (!wall) { console.warn('[SkillSelectionController] 未找到墙体组件,无法应用治疗效果'); return; } // 计算治疗量:使用SkillManager的计算方法 const maxHealth = wall.getMaxHealth(); const healAmount = SkillManager.calculateInstantHeal(maxHealth, skillLevel); // 应用治疗效果 wall.heal(healAmount); // 由于治疗技能会增加最大血量,需要更新血量显示 wall.updateHealthDisplay(); console.log(`[SkillSelectionController] 应用治疗效果: +${healAmount} 血量,技能等级: ${skillLevel}`); } /** * 查找墙体组件 */ private findWallComponent(): Wall | null { // 尝试从EnemyController获取墙体组件 const enemyController = EnemyController.getInstance(); if (enemyController) { // 通过topFenceNode或bottomFenceNode查找Wall组件 if (enemyController.topFenceNode) { const wall = enemyController.topFenceNode.getComponent(Wall); if (wall) return wall; } if (enemyController.bottomFenceNode) { const wall = enemyController.bottomFenceNode.getComponent(Wall); if (wall) return wall; } } // 备用方案:直接在场景中查找 const wallNode = find('Canvas/GameLevelUI/GameArea/TopFence') || find('Canvas/GameLevelUI/GameArea/BottomFence') || find('Canvas/GameLevelUI/Wall') || find('Canvas/Wall'); if (wallNode) { return wallNode.getComponent(Wall); } return null; } private getGameManager(): GameManager | null { const gmNode = find('Canvas/GameLevelUI/GameManager'); return gmNode?.getComponent(GameManager) || null; } private getInGameManager(): InGameManager | null { const gm = this.getGameManager(); return gm ? gm.getInGameManager() : null; } }