| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143 |
- import { _decorator, Component, Node, Button, Tween, tween, Vec3 } from 'cc';
- const { ccclass, property } = _decorator;
- @ccclass('ButtonManager')
- export class ButtonManager extends Component {
- private static _instance: ButtonManager = null;
-
- @property({ type: [Button], displayName: "按钮数组" })
- public buttons: Button[] = [];
-
- // 存储每个按钮的原始缩放值
- private buttonOriginalScales: Map<Node, Vec3> = new Map();
-
- // 动画参数
- private readonly SCALE_REDUCTION = 0.15; // 缩放减少量
- private readonly ANIMATION_DURATION = 0.1; // 动画持续时间
-
- public static get instance(): ButtonManager {
- return ButtonManager._instance;
- }
-
- onLoad() {
- // 设置单例
- if (ButtonManager._instance === null) {
- ButtonManager._instance = this;
- } else {
- this.destroy();
- return;
- }
-
- // 初始化按钮事件
- this.initButtonEvents();
- }
-
- onDestroy() {
- if (ButtonManager._instance === this) {
- ButtonManager._instance = null;
- }
- }
-
- private initButtonEvents() {
- this.buttons.forEach((button, index) => {
- if (button && button.node) {
- // 存储按钮的原始缩放值
- this.buttonOriginalScales.set(button.node, button.node.scale.clone());
-
- // 添加点击事件监听
- button.node.on(Button.EventType.CLICK, () => {
- this.playClickAnimation(button.node);
- }, this);
- }
- });
- }
-
- /**
- * 播放按钮点击动画
- * @param buttonNode 按钮节点
- */
- private playClickAnimation(buttonNode: Node) {
- if (!buttonNode) return;
-
- // 停止之前的动画
- Tween.stopAllByTarget(buttonNode);
-
- // 获取按钮的原始缩放值
- const originalScale = this.buttonOriginalScales.get(buttonNode);
- if (!originalScale) {
- // 如果没有存储原始缩放值,则使用当前缩放值作为原始值
- const currentScale = buttonNode.scale.clone();
- this.buttonOriginalScales.set(buttonNode, currentScale);
- return this.playClickAnimation(buttonNode);
- }
-
- // 先恢复到原始缩放,确保动画基准正确
- buttonNode.scale = originalScale.clone();
-
- // 计算目标缩放值(基于原始缩放减去0.15)
- const targetScale = new Vec3(
- Math.max(0.1, originalScale.x - this.SCALE_REDUCTION), // 最小缩放限制为0.1
- Math.max(0.1, originalScale.y - this.SCALE_REDUCTION),
- originalScale.z
- );
-
- // 创建缩放动画:先缩小,然后回到原始大小
- tween(buttonNode)
- .to(this.ANIMATION_DURATION, { scale: targetScale })
- .to(this.ANIMATION_DURATION, { scale: originalScale })
- .start();
- }
-
- /**
- * 手动添加按钮到管理器
- * @param button 要添加的按钮
- */
- public addButton(button: Button) {
- if (button && this.buttons.indexOf(button) === -1) {
- this.buttons.push(button);
-
- // 为新添加的按钮设置事件
- if (button.node) {
- // 存储按钮的原始缩放值
- this.buttonOriginalScales.set(button.node, button.node.scale.clone());
-
- button.node.on(Button.EventType.CLICK, () => {
- this.playClickAnimation(button.node);
- }, this);
- }
- }
- }
-
- /**
- * 从管理器中移除按钮
- * @param button 要移除的按钮
- */
- public removeButton(button: Button) {
- const index = this.buttons.indexOf(button);
- if (index !== -1) {
- // 移除事件监听
- if (button.node) {
- button.node.off(Button.EventType.CLICK, this.playClickAnimation, this);
- // 清除存储的原始缩放值
- this.buttonOriginalScales.delete(button.node);
- }
-
- this.buttons.splice(index, 1);
- }
- }
-
- /**
- * 清空所有按钮
- */
- public clearAllButtons() {
- this.buttons.forEach(button => {
- if (button && button.node) {
- button.node.off(Button.EventType.CLICK, this.playClickAnimation, this);
- }
- });
-
- // 清空原始缩放值存储
- this.buttonOriginalScales.clear();
- this.buttons = [];
- }
- }
|