using System; using Godot; namespace Milimoe.GodotGame; public partial class AnimatedRichTextLabel : RichTextLabel { [Export] public float CharactersPerSecond { get; set; } = 20; // 每秒显示的字符数 public NovelController NovelController { get; set; } = null; // 是否在小说控制器中 public bool IsAnimationRunning = false; // 动画是否正在运行 private string _fullText; // 完整的文本内容 private float _elapsedTime = 0; // 经过的时间 private int _visibleCharacters = 0; // 当前显示的字符数 private Timer _timer; public override void _Ready() { _timer = GetNode("Timer"); _timer.Timeout += OnTimerTimeout; _fullText = Text; // 保存完整的文本内容 Text = ""; // 清空 RichTextLabel 的初始文本 VisibleCharacters = 0; // 确保初始状态下不显示任何字符 } public void StartAnimation() { _elapsedTime = 0; _visibleCharacters = 0; Text = _fullText; // 恢复完整的文本内容 VisibleCharacters = 0; // 确保从头开始显示 IsAnimationRunning = true; _timer.Start(); // 启动 Timer } public void SkipAnimation() { if (IsAnimationRunning) { VisibleCharacters = _fullText.Length; // 直接显示所有字符 StopAnimation(); } } private void StopAnimation() { if (IsAnimationRunning) { _timer.Stop(); IsAnimationRunning = false; NovelController.TextAnimationHasFinished(); } } public override void _Process(double delta) { if (!IsAnimationRunning) return; if (_timer.IsStopped()) return; _elapsedTime += (float)delta; int targetVisibleCharacters = (int)(_elapsedTime * CharactersPerSecond); if (targetVisibleCharacters > _visibleCharacters) { _visibleCharacters = Math.Min(targetVisibleCharacters, _fullText.Length); VisibleCharacters = _visibleCharacters; } if (_visibleCharacters >= _fullText.Length) { StopAnimation(); } } private void OnTimerTimeout() { // 这里可以添加一些逻辑,例如在动画结束后触发一个信号 // 或者执行其他操作 } public new void SetText(string text) { _fullText = text; Text = ""; VisibleCharacters = 0; IsAnimationRunning = false; } }