| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120 |
- import { _decorator, Component, Node, Button, Vec3, find} from 'cc';
- import SkillButtonAnimator from './SkillButtonAnimator';
- import { GameManager } from '../../LevelSystem/GameManager';
- const { ccclass, property } = _decorator;
- /**
- * SkillSelectionController
- * 放在 Canvas/SelectSkillUI 节点上。
- * 负责监听技能按钮点击,并按顺序播放缩小动画,最后关闭整个 SelectSkillUI。
- */
- @ccclass('SkillSelectionController')
- export class SkillSelectionController extends Component {
- @property({ type: [Node], tooltip: '技能按钮节点列表,留空则自动从 SkillsContainer 获取' })
- public skillButtons: Node[] = [];
- @property({ tooltip: '缩小动画时长(秒)' })
- public shrinkDuration: number = 0.25;
- private _clicked = false;
- start() {
- // 自动收集按钮
- if (this.skillButtons.length === 0) {
- const container = this.node.getChildByName('SkillsContainer');
- if (container) {
- this.skillButtons = container.children;
- }
- }
- // 绑定点击事件
- this.skillButtons.forEach(btn => {
- const buttonComp = btn.getComponent(Button);
- if (buttonComp) {
- buttonComp.node.on(Button.EventType.CLICK, () => this.onSkillSelected(btn));
- } else {
- // 兜底:直接监听触摸
- btn.on(Node.EventType.TOUCH_END, () => this.onSkillSelected(btn));
- }
- });
- }
- /**
- * 玩家选择某技能按钮
- */
- private onSkillSelected(selectedBtn: Node) {
- if (this._clicked) return; // 只允许一次
- this._clicked = true;
- // 禁用所有按钮交互
- this.skillButtons.forEach(btn => {
- const b = btn.getComponent(Button);
- if (b) b.interactable = false;
- });
- 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, () => {
- // 关闭整个 UI
- this.node.active = false;
- // 恢复游戏并重置能量
- const gm = this.getGameManager();
- if (gm) {
- gm.resetEnergy();
- gm.resumeGame();
- }
- // 关闭后立刻重置UI
- this.resetUI();
- });
- }
- };
- // 播放其他按钮动画
- const targetPos = selectedBtn.position.clone();
- otherBtns.forEach(btn => {
- const anim = btn.getComponent(SkillButtonAnimator);
- anim?.playShrink(this.shrinkDuration, targetPos, onOtherFinished);
- });
- }
- private resetUI() {
- this._clicked = false;
- this.skillButtons.forEach(btn => {
- // 恢复交互
- const b = btn.getComponent(Button);
- if (b) b.interactable = true;
- // 恢复缩放
- btn.setScale(Vec3.ONE);
- // 恢复位置(如果有初始位置记录,建议用初始位置)
- // btn.setPosition(初始位置);
- // 恢复透明度等
- // btn.opacity = 255;
- // 还原动画状态
- const anim = btn.getComponent(SkillButtonAnimator);
- anim?.resetState?.();
- });
- }
- private _gameManager: GameManager = null;
- private getGameManager(): GameManager {
- if (this._gameManager && this._gameManager.isValid) return this._gameManager;
- // 尝试在 Canvas 下递归查找
- const canvas = find('Canvas');
- if (canvas) {
- this._gameManager = canvas.getComponentInChildren(GameManager);
- if (this._gameManager) return this._gameManager;
- }
- }
- }
- export default SkillSelectionController;
|