cirnogodot/Scripts/Misc/CheckpointAnimation.cs
2025-06-18 11:33:27 +02:00

107 lines
No EOL
3.2 KiB
C#

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;
}
public void Toggle()
{
this.Activate();
}
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;
}
}
}