unity数字text滚动代码实现 代码缓存_第三章.md 13 KB

SlotNumberManager

管理器

using System.Collections;
using UnityEngine;

namespace SlotGame
{
    /// <summary>
    /// 老虎机数字管理器 - 统一管理所有数字滚动动画
    /// Slot machine number manager - centrally manages all number rolling animations
    /// </summary>
    public class SlotNumberManager : MonoBehaviour
    {
        [Header("数字滚动组件 Number Roll Components")]
        [SerializeField] private NumberRollAnimation scoreDisplay;
        [SerializeField] private NumberRollAnimation balanceDisplay;
        [SerializeField] private NumberRollAnimation jackpotDisplay;
        [SerializeField] private NumberRollAnimation winAmountDisplay;
        [SerializeField] private NumberRollAnimation betAmountDisplay;
        
        [Header("动画时间设置 Animation Timing")]
        [SerializeField] private float scoreRollDuration = 1.5f;
        [SerializeField] private float balanceRollDuration = 1.0f;
        [SerializeField] private float jackpotRollDuration = 0.8f;
        [SerializeField] private float winAmountRollDuration = 2.0f;
        [SerializeField] private float bigWinRollDuration = 4.0f;
        
        [Header("数值设置 Value Settings")]
        [SerializeField] private long currentScore = 0;
        [SerializeField] private long currentBalance = 50000;
        [SerializeField] private long currentJackpot = 3000000;
        [SerializeField] private long currentBetAmount = 100;
        
        [Header("大奖阈值 Big Win Threshold")]
        [SerializeField] private long bigWinThreshold = 100000;
        
        // 事件
        public event System.Action<long> OnScoreChanged;
        public event System.Action<long> OnBalanceChanged;
        public event System.Action<long> OnJackpotChanged;
        public event System.Action<long> OnWinAmountShown;
        public event System.Action<long> OnBigWinTriggered;
        
        #region Unity生命周期
        
        private void Start()
        {
            InitializeDisplays();
            RegisterEvents();
        }
        
        private void OnDestroy()
        {
            UnregisterEvents();
        }
        
        #endregion
        
        #region 初始化
        
        private void InitializeDisplays()
        {
            // 设置初始显示值
            if (scoreDisplay != null)
                scoreDisplay.SetValue(currentScore);
            
            if (balanceDisplay != null)
                balanceDisplay.SetValue(currentBalance);
            
            if (jackpotDisplay != null)
                jackpotDisplay.SetValue(currentJackpot);
            
            if (winAmountDisplay != null)
                winAmountDisplay.SetValue(0);
            
            if (betAmountDisplay != null)
                betAmountDisplay.SetValue(currentBetAmount);
        }
        
        private void RegisterEvents()
        {
            if (scoreDisplay != null)
                scoreDisplay.OnRollComplete += OnScoreRollComplete;
            
            if (balanceDisplay != null)
                balanceDisplay.OnRollComplete += OnBalanceRollComplete;
            
            if (jackpotDisplay != null)
                jackpotDisplay.OnRollComplete += OnJackpotRollComplete;
            
            if (winAmountDisplay != null)
                winAmountDisplay.OnRollComplete += OnWinAmountRollComplete;
        }
        
        private void UnregisterEvents()
        {
            if (scoreDisplay != null)
                scoreDisplay.OnRollComplete -= OnScoreRollComplete;
            
            if (balanceDisplay != null)
                balanceDisplay.OnRollComplete -= OnBalanceRollComplete;
            
            if (jackpotDisplay != null)
                jackpotDisplay.OnRollComplete -= OnJackpotRollComplete;
            
            if (winAmountDisplay != null)
                winAmountDisplay.OnRollComplete -= OnWinAmountRollComplete;
        }
        
        #endregion
        
        #region 分数管理
        
        /// <summary>
        /// 增加分数
        /// </summary>
        public void AddScore(long amount)
        {
            currentScore += amount;
            if (scoreDisplay != null)
            {
                scoreDisplay.RollToValue(currentScore, scoreRollDuration);
            }
            OnScoreChanged?.Invoke(currentScore);
        }
        
        /// <summary>
        /// 设置分数
        /// </summary>
        public void SetScore(long score)
        {
            currentScore = score;
            if (scoreDisplay != null)
            {
                scoreDisplay.SetValue(currentScore);
            }
            OnScoreChanged?.Invoke(currentScore);
        }
        
        #endregion
        
        #region 余额管理
        
        /// <summary>
        /// 增加余额
        /// </summary>
        public void AddBalance(long amount)
        {
            currentBalance += amount;
            if (balanceDisplay != null)
            {
                balanceDisplay.RollToValue(currentBalance, balanceRollDuration);
            }
            OnBalanceChanged?.Invoke(currentBalance);
        }
        
        /// <summary>
        /// 扣除余额(下注)
        /// </summary>
        public bool DeductBalance(long amount)
        {
            if (currentBalance >= amount)
            {
                currentBalance -= amount;
                if (balanceDisplay != null)
                {
                    balanceDisplay.RollToValue(currentBalance, balanceRollDuration);
                }
                OnBalanceChanged?.Invoke(currentBalance);
                return true;
            }
            return false;
        }
        
        /// <summary>
        /// 设置余额
        /// </summary>
        public void SetBalance(long balance)
        {
            currentBalance = balance;
            if (balanceDisplay != null)
            {
                balanceDisplay.SetValue(currentBalance);
            }
            OnBalanceChanged?.Invoke(currentBalance);
        }
        
        #endregion
        
        #region 奖池管理
        
        /// <summary>
        /// 增加奖池
        /// </summary>
        public void AddJackpot(long amount)
        {
            currentJackpot += amount;
            if (jackpotDisplay != null)
            {
                jackpotDisplay.RollToValue(currentJackpot, jackpotRollDuration);
            }
            OnJackpotChanged?.Invoke(currentJackpot);
        }
        
        /// <summary>
        /// 重置奖池(中大奖后)
        /// </summary>
        public void ResetJackpot(long newAmount = 1000000)
        {
            currentJackpot = newAmount;
            if (jackpotDisplay != null)
            {
                jackpotDisplay.RollToValue(currentJackpot, jackpotRollDuration);
            }
            OnJackpotChanged?.Invoke(currentJackpot);
        }
        
        #endregion
        
        #region 中奖显示
        
        /// <summary>
        /// 显示中奖金额
        /// </summary>
        public void ShowWinAmount(long winAmount)
        {
            if (winAmountDisplay != null)
            {
                winAmountDisplay.SetValue(0);
                
                // 根据中奖金额决定动画时长
                float duration = winAmount >= bigWinThreshold ? bigWinRollDuration : winAmountRollDuration;
                winAmountDisplay.RollToValue(winAmount, duration);
                
                // 检查是否是大奖
                if (winAmount >= bigWinThreshold)
                {
                    OnBigWinTriggered?.Invoke(winAmount);
                }
            }
            
            OnWinAmountShown?.Invoke(winAmount);
        }
        
        /// <summary>
        /// 隐藏中奖金额显示
        /// </summary>
        public void HideWinAmount()
        {
            if (winAmountDisplay != null)
            {
                winAmountDisplay.SetValue(0);
            }
        }
        
        #endregion
        
        #region 下注金额
        
        /// <summary>
        /// 设置下注金额
        /// </summary>
        public void SetBetAmount(long betAmount)
        {
            currentBetAmount = betAmount;
            if (betAmountDisplay != null)
            {
                betAmountDisplay.SetValue(currentBetAmount);
            }
        }
        
        /// <summary>
        /// 更新下注金额(带动画)
        /// </summary>
        public void UpdateBetAmount(long betAmount)
        {
            currentBetAmount = betAmount;
            if (betAmountDisplay != null)
            {
                betAmountDisplay.RollToValue(currentBetAmount, 0.5f);
            }
        }
        
        #endregion
        
        #region 游戏流程
        
        /// <summary>
        /// 开始游戏(扣除下注金额)
        /// </summary>
        public bool StartGame()
        {
            return DeductBalance(currentBetAmount);
        }
        
        /// <summary>
        /// 处理游戏结果
        /// </summary>
        public void ProcessGameResult(long winAmount, bool addToScore = true)
        {
            if (winAmount > 0)
            {
                // 显示中奖金额
                ShowWinAmount(winAmount);
                
                // 启动协程处理后续动画
                StartCoroutine(ProcessWinSequence(winAmount, addToScore));
            }
        }
        
        private IEnumerator ProcessWinSequence(long winAmount, bool addToScore)
        {
            // 等待中奖金额动画
            float waitTime = winAmount >= bigWinThreshold ? bigWinRollDuration : winAmountRollDuration;
            yield return new WaitForSeconds(waitTime + 0.5f);
            
            // 同时更新余额和分数
            if (addToScore)
            {
                AddScore(winAmount);
            }
            AddBalance(winAmount);
            
            // 延迟后隐藏中奖显示
            yield return new WaitForSeconds(2f);
            HideWinAmount();
        }
        
        /// <summary>
        /// 中大奖流程
        /// </summary>
        public void ProcessJackpotWin()
        {
            long jackpotWin = currentJackpot;
            
            // 显示大奖金额
            ShowWinAmount(jackpotWin);
            
            // 重置奖池
            ResetJackpot();
            
            // 处理大奖结果
            StartCoroutine(ProcessJackpotSequence(jackpotWin));
        }
        
        private IEnumerator ProcessJackpotSequence(long jackpotAmount)
        {
            // 等待大奖动画
            yield return new WaitForSeconds(bigWinRollDuration + 1f);
            
            // 更新余额和分数
            AddScore(jackpotAmount);
            AddBalance(jackpotAmount);
            
            // 延迟后隐藏显示
            yield return new WaitForSeconds(3f);
            HideWinAmount();
        }
        
        #endregion
        
        #region 事件回调
        
        private void OnScoreRollComplete(long value)
        {
            Debug.Log($"Score roll completed: {value}");
        }
        
        private void OnBalanceRollComplete(long value)
        {
            Debug.Log($"Balance roll completed: {value}");
        }
        
        private void OnJackpotRollComplete(long value)
        {
            Debug.Log($"Jackpot roll completed: {value}");
        }
        
        private void OnWinAmountRollComplete(long value)
        {
            Debug.Log($"Win amount roll completed: {value}");
        }
        
        #endregion
        
        #region 属性访问器
        
        public long CurrentScore => currentScore;
        public long CurrentBalance => currentBalance;
        public long CurrentJackpot => currentJackpot;
        public long CurrentBetAmount => currentBetAmount;
        
        public bool CanAffordBet => currentBalance >= currentBetAmount;
        
        #endregion
        
        #region 调试方法
        
        [ContextMenu("Test Small Win")]
        private void TestSmallWin()
        {
            ProcessGameResult(5000);
        }
        
        [ContextMenu("Test Big Win")]
        private void TestBigWin()
        {
            ProcessGameResult(150000);
        }
        
        [ContextMenu("Test Jackpot Win")]
        private void TestJackpotWin()
        {
            ProcessJackpotWin();
        }
        
        [ContextMenu("Add Balance 10000")]
        private void TestAddBalance()
        {
            AddBalance(10000);
        }
        
        [ContextMenu("Increase Jackpot")]
        private void TestIncreaseJackpot()
        {
            AddJackpot(50000);
        }
        
        #endregion
    }
}