import { _decorator, Component, Node, UITransform, Label, tween, Vec3, find } from 'cc'; import EventBus, { GameEvents } from '../Core/EventBus'; const { ccclass, property } = _decorator; @ccclass('ToastAni') export class ToastAni extends Component { @property({ displayName: "Toast类型", tooltip: "选择Toast的类型:wave表示波次提示,resource表示资源不足提示" }) public toastType: string = 'wave'; // 'wave' 或 'resource' private originalPosition: Vec3 = new Vec3(); private isAnimating: boolean = false; private currentDuration: number = 0; // 默认显示时长(秒) onLoad() { // 保存初始位置 this.originalPosition = this.node.position.clone(); // 监听Toast事件 this.setupEventListeners(); // 初始化位置到屏幕左边外侧 this.resetToInitialPosition(); } private setupEventListeners() { const eventBus = EventBus.getInstance(); if (this.toastType === 'wave') { // 波次提示Toast监听原有事件 eventBus.on(GameEvents.SHOW_TOAST, this.onShowToast, this); eventBus.on(GameEvents.HIDE_TOAST, this.onHideToast, this); } else if (this.toastType === 'resource') { // 资源不足Toast监听新事件 eventBus.on(GameEvents.SHOW_RESOURCE_TOAST, this.onShowToast, this); eventBus.on(GameEvents.HIDE_RESOURCE_TOAST, this.onHideToast, this); } } private onShowToast(data: { message: string, duration?: number }) { if (this.isAnimating) { return; } // 设置Toast文本 this.setToastMessage(data.message); // 播放滑入动画 this.playSlideInAnimation(); } private onHideToast() { if (!this.isAnimating) { this.playSlideOutAnimation(); } } private setToastMessage(message: string) { const labelNode = this.node.getChildByName('label'); if (labelNode) { const label = labelNode.getComponent(Label); if (label) { label.string = message; } } } private resetToInitialPosition() { // 重置到原始位置(屏幕外侧的起始位置) this.node.setPosition(this.originalPosition); } private playSlideInAnimation() { if (this.isAnimating) { return; } this.isAnimating = true; // 确保从起始位置开始 this.resetToInitialPosition(); // 滑入到屏幕中央位置显示 const targetPosition = new Vec3(0, this.originalPosition.y, this.originalPosition.z); tween(this.node) .to(0.5, { position: targetPosition }, { easing: 'sineOut' }) .delay(0.5) .call(() => { this.playSlideOutAnimation(); }) .start(); } private playSlideOutAnimation() { if (!this.isAnimating) { return; } // 获取Canvas尺寸来计算屏幕边界 const canvas = find('Canvas'); if (canvas) { const canvasTransform = canvas.getComponent(UITransform); if (canvasTransform) { const canvasWidth = canvasTransform.contentSize.width; // 获取Toast节点的宽度 const toastTransform = this.node.getComponent(UITransform); const toastWidth = toastTransform ? toastTransform.contentSize.width : 200; // 滑出到屏幕右边外侧消失 const rightPosition = new Vec3(canvasWidth / 2 + toastWidth / 2 + 50, this.node.position.y, this.node.position.z); tween(this.node) .to(0.5, { position: rightPosition }, { easing: 'sineIn' }) .call(() => { // 动画完成后立即重置到初始位置 this.resetToInitialPosition(); this.isAnimating = false; }) .start(); } } } onDestroy() { // 移除事件监听 const eventBus = EventBus.getInstance(); if (this.toastType === 'wave') { // 移除波次提示Toast事件监听 eventBus.off(GameEvents.SHOW_TOAST, this.onShowToast, this); eventBus.off(GameEvents.HIDE_TOAST, this.onHideToast, this); } else if (this.toastType === 'resource') { // 移除资源不足Toast事件监听 eventBus.off(GameEvents.SHOW_RESOURCE_TOAST, this.onShowToast, this); eventBus.off(GameEvents.HIDE_RESOURCE_TOAST, this.onHideToast, this); } } }