using Godot; using System; using System.Threading; using System.Threading.Tasks; using Cirno.Scripts; using GTweens.Builders; using GTweens.Easings; using GTweens.Extensions; using GTweens.Tweens; using GTweensGodot.Extensions; public partial class CheckpointAnimation : Node2D, IActivable { [Export] public AnimatedSprite2D Sprite { get; private set; } [Export] public Label Label { get; private set; } [Export] public AudioStreamPlayer2D Sound { get; private set; } [Export] public StringName ClosedAnimationName { get; private set; } = "Closed"; [Export] public StringName OpenAnimationName { get; private set; } = "Open"; [Export] public Vector2 LabelStartPosition { get; private set; } = new Vector2(0, 0); [Export] public Vector2 LabelEndPosition { get; private set; } = new Vector2(0, 16); [Export] public float LabelAnimationTime { get; private set; } = 0.5f; [Export] public float DoorCloseTime { get; private set; } = 1.5f; private GTween _tween; private CancellationTokenSource _cts; public override void _Ready() { Sprite.Play(ClosedAnimationName); Label.Hide(); } public bool Activate(ActivationType activationType = ActivationType.Toggle) { // Cancel previous token _cts?.Cancel(); _cts?.Dispose(); // Create new token source _cts = new CancellationTokenSource(); // Start new animation with the new token _ = AnimateAsync(_cts.Token); return true; } private async Task AnimateAsync(CancellationToken cancellationToken) { try { //_tween?.Complete(); if (_tween != null) { await _tween.AwaitCompleteOrKill(cancellationToken); } Sound.Play(); Label.Show(); Label.SetPosition(LabelStartPosition); Sprite.Play(OpenAnimationName); //Sprite.Play(ClosedAnimationName); _tween = GTweenSequenceBuilder.New() // .AppendCallback(() => // { // Sprite.Play(OpenAnimationName); // Label.SetPosition(LabelStartPosition); // Label.Show(); // }) // .AppendCallback(() => Sprite.Play(OpenAnimationName)) // .AppendCallback(() => Label.SetPosition(LabelStartPosition)) // .AppendCallback(() => Label.Show()) .Append(Label.TweenPositionY(LabelEndPosition.Y, LabelAnimationTime)) .AppendTime(DoorCloseTime) .AppendCallback(() => Label.Hide()) .AppendCallback(() => Sprite.Play(ClosedAnimationName)) .Build(); _tween.SetEasing(Easing.OutBounce); await _tween.PlayAsync(cancellationToken); } catch (OperationCanceledException) { GD.Print("Animation was cancelled."); // Optional cleanup here } catch (Exception e) { GD.PrintErr($"Unexpected error during animation: {e}"); throw; } } }