import { _decorator, Component, Node, find, CCFloat, resources, JsonAsset } from 'cc'; import { BundleLoader } from '../../Core/BundleLoader'; import { GameManager } from '../../LevelSystem/GameManager'; import { InGameManager } from '../../LevelSystem/IN_game'; import { SkillButtonController } from './SkillButtonController'; import { SkillManager, SkillData } from './SkillManager'; import { Wall } from '../Wall'; import { EnemyController } from '../EnemyController'; const { ccclass, property } = _decorator; // 移除本地SkillData声明,直接用SkillManager中的SkillData interface SkillConfig { skills: SkillData[]; } /** * SkillSelectionController * 放在 Canvas/SelectSkillUI 节点上。 * 负责监听技能按钮点击,随机选择技能显示,并按顺序播放缩小动画,最后关闭整个 SelectSkillUI。 */ @ccclass('SkillSelectionController') export class SkillSelectionController extends Component { @property({ type: [SkillButtonController], tooltip: '技能按钮控制器列表,留空则自动从 SkillsContainer 获取' }) public skillButtons: SkillButtonController[] = []; @property({ type: CCFloat, tooltip: '收缩动画时长' }) public shrinkDuration: number = 0.3; // 防止重复点击标记 private _clicked = false; // 技能配置数据 private _skillConfig: SkillConfig | null = null; // 当前显示的技能数据 private _currentSkills: SkillData[] = []; start() { this.loadSkillConfig(); } /** * 每次界面激活时刷新技能状态 */ protected onEnable() { // 如果技能配置已加载,重新随机选择技能并更新UI if (this._skillConfig && this.skillButtons.length > 0) { this.randomizeSkills(); } } /** * 加载技能配置 */ private async loadSkillConfig() { try { const bundleLoader = BundleLoader.getInstance(); const skillData = await bundleLoader.loadDataJson('skill'); if (!skillData) { console.error('技能配置文件内容为空'); return; } this._skillConfig = skillData.json as SkillConfig; // 初始化技能管理器 const skillManager = SkillManager.getInstance(); if (skillManager) { skillManager.initSkills(this._skillConfig.skills); } this.setupSkillButtons(); this.randomizeSkills(); } catch (error) { console.error('加载技能配置失败:', error); } } private setupSkillButtons() { if (this.skillButtons.length === 0) { const container = this.node.getChildByName('SkillsContainer'); if (container) { this.skillButtons = container.children .map(child => child.getComponent(SkillButtonController)) .filter(controller => controller !== null) as SkillButtonController[]; } } this.skillButtons.forEach(skillButton => { skillButton.setClickCallback((selectedButton) => this.onSkillSelected(selectedButton)); }); } /** * 随机选择3个技能显示 */ private randomizeSkills() { if (!this._skillConfig || this._skillConfig.skills.length < 3) { console.error('技能配置不足,无法随机选择'); return; } const skillManager = SkillManager.getInstance(); if (!skillManager) { console.error('SkillManager未初始化'); return; } // 将技能分为满级和非满级两组 const nonMaxLevelSkills: SkillData[] = []; const maxLevelSkills: SkillData[] = []; this._skillConfig.skills.forEach(skill => { if (skillManager.isSkillMaxLevel(skill.id)) { maxLevelSkills.push(skill); } else { nonMaxLevelSkills.push(skill); } }); // 优先从非满级技能中选择 this._currentSkills = []; const availableSkills = [...nonMaxLevelSkills]; // 先从非满级技能中随机选择 while (this._currentSkills.length < 3 && availableSkills.length > 0) { const randomIndex = Math.floor(Math.random() * availableSkills.length); this._currentSkills.push(availableSkills.splice(randomIndex, 1)[0]); } // 如果非满级技能不足3个,再从满级技能中补充 const remainingMaxLevelSkills = [...maxLevelSkills]; while (this._currentSkills.length < 3 && remainingMaxLevelSkills.length > 0) { const randomIndex = Math.floor(Math.random() * remainingMaxLevelSkills.length); this._currentSkills.push(remainingMaxLevelSkills.splice(randomIndex, 1)[0]); } // 更新UI显示 this.updateSkillUI(); } /** * 更新技能UI显示 */ private updateSkillUI() { this.skillButtons.forEach((skillButton, index) => { if (index < this._currentSkills.length) { const skillData = this._currentSkills[index]; skillButton.setSkillData(skillData); // 确保显示当前等级的描述 const skillManager = SkillManager.getInstance(); if (skillManager) { const currentLevel = skillManager.getSkillLevel(skillData.id); console.log(`[SkillSelectionController] 技能 ${skillData.name} 当前等级: ${currentLevel}`); // 强制刷新技能等级显示 skillButton.refreshSkillLevel(); } } else { skillButton.setSkillData(null); } }); } /** * 玩家选择某技能按钮 */ private onSkillSelected(selectedButton: SkillButtonController) { if (this._clicked) return; this._clicked = true; // 获取选中的技能 const selectedSkill = selectedButton.getSkillData(); if (selectedSkill) { // 通过技能管理器升级技能 const skillManager = SkillManager.getInstance(); if (skillManager) { skillManager.upgradeSkill(selectedSkill.id); // 立即更新UI显示新的星级 this.skillButtons.forEach(btn => btn.refreshSkillLevel()); // 如果是治疗技能,立即应用治疗效果 if (selectedSkill.id === 'heal') { this.applyHealEffect(selectedSkill.id); } } } const otherButtons = this.skillButtons.filter(btn => btn !== selectedButton); let finishedOthers = 0; // 所有其他按钮完成动画后,再收缩选中按钮 const onOtherFinished = () => { finishedOthers++; if (finishedOthers >= otherButtons.length) { // 收缩选中按钮 selectedButton.playShrinkAnimation(this.shrinkDuration, undefined, () => { const igm = this.getInGameManager(); if (igm) { igm.resetEnergyValue(); // 检查是否需要播放diban动画 // 通过InGameManager处理后续逻辑 igm.onSkillSelectionComplete(); } // 关闭后立刻重置UI this.resetUI(); }); } }; // 播放其他按钮动画 const targetPos = selectedButton.node.position.clone(); otherButtons.forEach(btn => { btn.playShrinkAnimation(this.shrinkDuration, targetPos, onOtherFinished); }); } /** * 重置 UI 状态,供下次开启时使用 */ public resetUI() { this._clicked = false; // 重新启用所有按钮交互 this.skillButtons.forEach(btn => { btn.resetAnimationState(); btn.setInteractable(true); }); // 重新随机选择技能(这里会自动获取最新的技能等级状态) 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; } }