NumRaiseLable.ts 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. import { _decorator, Component, Label, math, Node } from 'cc';
  2. const { ccclass, property } = _decorator;
  3. /**
  4. * 调用事例
  5. * this.combatLable.startCounting(data.total);
  6. */
  7. //数字自增长
  8. @ccclass('NumRaiseLable')
  9. export class NumRaiseLable extends Label {
  10. // 动画持续时间(秒)
  11. @property({ tooltip: '数字增长动画持续时间(秒)' })
  12. private _duration: number = 0.5;
  13. @property
  14. public get duration(): number {
  15. return this._duration;
  16. }
  17. public set duration(value: number) {
  18. this._duration = math.clamp(value, 0.1, 5);
  19. }
  20. // 当前显示的数字
  21. private _currentValue: number = 0;
  22. // 目标数字
  23. private _targetValue: number = 0;
  24. // 是否正在播放动画
  25. private _isAnimating: boolean = false;
  26. // 每帧增量
  27. private _incrementPerFrame: number = 0;
  28. /**
  29. * 开始数字增长动画
  30. * @param targetValue 目标数值
  31. * @param duration 可选,动画持续时间(秒),默认使用组件设置的duration
  32. */
  33. public startCounting(targetValue: number, duration?: number) {
  34. if (this._isAnimating) {
  35. this.stopCounting();
  36. }
  37. //使用传入的duration或默认值
  38. const animDuration = duration ?? this._duration;
  39. this._targetValue = targetValue;
  40. this._currentValue = 0;
  41. this._isAnimating = true;
  42. //计算每帧增量(假设60FPS)
  43. this._incrementPerFrame = this._targetValue / (animDuration * 60);
  44. //取消之前的调度
  45. this.unschedule(this.updateNumber);
  46. //开始新的调度
  47. this.schedule(this.updateNumber, 1/60);
  48. }
  49. /**
  50. * 停止数字增长动画
  51. */
  52. public stopCounting() {
  53. this._isAnimating = false;
  54. this.unschedule(this.updateNumber);
  55. this._currentValue = this._targetValue;
  56. this.updateDisplay();
  57. }
  58. /**
  59. * 立即完成动画
  60. */
  61. public completeCounting() {
  62. this.stopCounting();
  63. this._currentValue = this._targetValue;
  64. this.updateDisplay();
  65. }
  66. /**
  67. * 每帧更新数字
  68. */
  69. private updateNumber() {
  70. if (!this._isAnimating) return;
  71. this._currentValue += this._incrementPerFrame;
  72. //确保不超过目标值
  73. if (this._currentValue >= this._targetValue) {
  74. this._currentValue = this._targetValue;
  75. this._isAnimating = false;
  76. this.unschedule(this.updateNumber);
  77. }
  78. this.updateDisplay();
  79. }
  80. /**
  81. * 更新显示文本
  82. */
  83. private updateDisplay() {
  84. this.string = Math.floor(this._currentValue).toString();
  85. }
  86. //组件销毁时清理
  87. public onDestroy() {
  88. this.unschedule(this.updateNumber);
  89. }
  90. }