| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293 |
- import { _decorator, Component, Node, find, CCFloat, resources, JsonAsset } from 'cc';
- 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();
- }
-
- /**
- * 加载技能配置
- */
- 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
- .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}`);
- }
- } 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;
- }
- }
|