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 { private originalPosition: Vec3 = new Vec3(); private isAnimating: boolean = false; private currentDuration: number = 2.0; // 默认显示时长(秒) onLoad() { // 保存初始位置 this.originalPosition = this.node.position.clone(); // 监听Toast事件 this.setupEventListeners(); // 初始化位置到屏幕左边外侧 this.resetToInitialPosition(); } private setupEventListeners() { EventBus.getInstance().on(GameEvents.SHOW_TOAST, this.onShowToast, this); EventBus.getInstance().on(GameEvents.HIDE_TOAST, this.onHideToast, this); } private onShowToast(data: { message: string, duration?: number }) { if (this.isAnimating) { return; } // 设置显示时长 this.currentDuration = data.duration || 2.0; // 设置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(this.currentDuration) .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() { // 移除事件监听 EventBus.getInstance().off(GameEvents.SHOW_TOAST, this.onShowToast, this); EventBus.getInstance().off(GameEvents.HIDE_TOAST, this.onHideToast, this); } }