From 52f1560c4853d0ee67bd6d1294faa8b14e4800a8 Mon Sep 17 00:00:00 2001 From: jonathan Date: Tue, 30 Sep 2025 17:36:28 +0200 Subject: [PATCH] Added basic action animation --- scenes/Babushka_scene_fight_happening.tscn | 32 ++++++++--- .../Common/Fight/ActionAnimationController.cs | 25 +++++++++ .../Fight/ActionAnimationController.cs.uid | 1 + .../Common/Fight/Actions/AllyAttackAction.cs | 14 +++++ .../CSharp/Common/Fight/AllFightersVisual.cs | 7 +++ .../Fight/FightHappeningStateDebugger.cs | 4 ++ scripts/CSharp/Common/Fight/FighterAction.cs | 3 +- scripts/CSharp/Common/Fight/FighterVisual.cs | 53 ++++++++++++++----- 8 files changed, 118 insertions(+), 21 deletions(-) create mode 100644 scripts/CSharp/Common/Fight/ActionAnimationController.cs create mode 100644 scripts/CSharp/Common/Fight/ActionAnimationController.cs.uid diff --git a/scenes/Babushka_scene_fight_happening.tscn b/scenes/Babushka_scene_fight_happening.tscn index 96a3c6f..8749350 100644 --- a/scenes/Babushka_scene_fight_happening.tscn +++ b/scenes/Babushka_scene_fight_happening.tscn @@ -1,7 +1,8 @@ -[gd_scene load_steps=10 format=3 uid="uid://cjshlwk8ajpnp"] +[gd_scene load_steps=11 format=3 uid="uid://cjshlwk8ajpnp"] [ext_resource type="Script" uid="uid://cnhpnn8o0gybd" path="res://scripts/CSharp/Common/Fight/FightHappeningSceneSetup.cs" id="1_fiutj"] [ext_resource type="Script" uid="uid://c76mhhqyk4lgh" path="res://scripts/CSharp/Common/Fight/FightHappening.cs" id="1_gsk03"] +[ext_resource type="Script" uid="uid://dtf4ejct4m682" path="res://scripts/CSharp/Common/Fight/ActionAnimationController.cs" id="2_7kjgs"] [ext_resource type="Script" uid="uid://dwsqst8fhhqlc" path="res://scripts/CSharp/Common/Fight/AllFightersVisual.cs" id="2_lu4y4"] [ext_resource type="PackedScene" uid="uid://bcld43daavmrn" path="res://prefabs/fight/fight_scene_switcher.tscn" id="2_phrlx"] [ext_resource type="PackedScene" uid="uid://7jsxokx67gpq" path="res://prefabs/fight/fighterVisuals/vesna_fighter_visual.tscn" id="4_qo0gi"] @@ -15,6 +16,14 @@ [node name="FightHappening" type="Node" parent="."] script = ExtResource("1_gsk03") +[node name="ActionAnimationController" type="Node" parent="." node_paths=PackedStringArray("_allFightersVisual")] +script = ExtResource("2_7kjgs") +_allFightersVisual = NodePath("../FightVisuals") + +[node name="StateReactionActionAnimation" type="Node" parent="ActionAnimationController"] +script = ExtResource("4_ydj1i") +_fightState = 10 + [node name="Camera2D" type="Camera2D" parent="."] [node name="FightSetup" type="Node2D" parent="."] @@ -159,20 +168,31 @@ text = "This text explains the currently hovered button" script = ExtResource("4_ydj1i") _fightState = 6 -[node name="StateMachineDebugger" type="Node" parent="." node_paths=PackedStringArray("_label")] +[node name="StateMachineDebugger" type="Node" parent="." node_paths=PackedStringArray("_label", "_current")] script = ExtResource("8_tv7cl") _label = NodePath("Label") +_current = NodePath("Current") [node name="Label" type="Label" parent="StateMachineDebugger"] -offset_left = -973.0 -offset_top = -500.0 -offset_right = -523.0 -offset_bottom = 444.0 +offset_left = -982.0 +offset_top = -497.0 +offset_right = -893.0 +offset_bottom = -474.0 +text = "Hello world" + +[node name="Current" type="Label" parent="StateMachineDebugger"] +offset_left = 705.0 +offset_top = -495.0 +offset_right = 794.0 +offset_bottom = -472.0 text = "Hello world" [connection signal="SignalTransitionState" from="FightHappening" to="FightVisuals" method="FightHappeningStateChange"] [connection signal="SignalTransitionState" from="FightHappening" to="ActionSelect/StateReactionInputActionSelect" method="FightHappeningStateTransitioned"] [connection signal="SignalTransitionState" from="FightHappening" to="StateMachineDebugger" method="StateChange"] +[connection signal="SignalTransitionState" from="FightHappening" to="ActionAnimationController/StateReactionActionAnimation" method="FightHappeningStateTransitioned"] +[connection signal="OnStateEntered" from="ActionAnimationController/StateReactionActionAnimation" to="ActionAnimationController" method="StateEnter"] +[connection signal="OnStateExited" from="ActionAnimationController/StateReactionActionAnimation" to="ActionAnimationController" method="StateExit"] [connection signal="pressed" from="ActionSelect/BottomPanel/VBoxContainer/MarginContainer/HBoxContainer/MarginContainer/AttackButton" to="ActionSelect" method="SelectAction" binds= [1]] [connection signal="pressed" from="ActionSelect/BottomPanel/VBoxContainer/MarginContainer/HBoxContainer/MarginContainer2/Summon Button" to="ActionSelect" method="SelectAction" binds= [2]] [connection signal="pressed" from="ActionSelect/BottomPanel/VBoxContainer/MarginContainer/HBoxContainer/MarginContainer3/Talk Button" to="ActionSelect" method="SelectAction" binds= [3]] diff --git a/scripts/CSharp/Common/Fight/ActionAnimationController.cs b/scripts/CSharp/Common/Fight/ActionAnimationController.cs new file mode 100644 index 0000000..04621fa --- /dev/null +++ b/scripts/CSharp/Common/Fight/ActionAnimationController.cs @@ -0,0 +1,25 @@ +using Godot; + +namespace Babushka.scripts.CSharp.Common.Fight; + +public partial class ActionAnimationController : Node +{ + #region Shortcuts + + private FightWorld.FightHappeningData HappeningData => FightWorld.Instance.fightHappeningData ?? throw new NoFightHappeningException(); + + #endregion + + [Export] private AllFightersVisual _allFightersVisual = null!; + + + public void StateEnter() + { + _ = HappeningData.actionStaging!.AnimateAction(_allFightersVisual); + } + + public void StateExit() + { + + } +} \ No newline at end of file diff --git a/scripts/CSharp/Common/Fight/ActionAnimationController.cs.uid b/scripts/CSharp/Common/Fight/ActionAnimationController.cs.uid new file mode 100644 index 0000000..b0741bf --- /dev/null +++ b/scripts/CSharp/Common/Fight/ActionAnimationController.cs.uid @@ -0,0 +1 @@ +uid://dtf4ejct4m682 diff --git a/scripts/CSharp/Common/Fight/Actions/AllyAttackAction.cs b/scripts/CSharp/Common/Fight/Actions/AllyAttackAction.cs index 20760b3..ed1789a 100644 --- a/scripts/CSharp/Common/Fight/Actions/AllyAttackAction.cs +++ b/scripts/CSharp/Common/Fight/Actions/AllyAttackAction.cs @@ -1,4 +1,5 @@ using System; +using System.Threading.Tasks; using Babushka.scripts.CSharp.Common.Fight.ActionDetails; using Babushka.scripts.CSharp.Common.Util; using Godot; @@ -43,4 +44,17 @@ public class AllyAttackAction : FighterAction { targetSelect.GetTarget().AddHealth(-5); } + + public override async Task AnimateAction(AllFightersVisual allFightersVisual) + { + var currentFighter = HappeningData.fighterStack.Current; + var targetFighter = targetSelect.GetTarget(); + + var currentFighterVisual = allFightersVisual.GetVisualForFighter(currentFighter); + var targetFighterVisual = allFightersVisual.GetVisualForFighter(targetFighter); + + await currentFighterVisual.AnimatePosToTarget(targetFighterVisual); + _ = targetFighterVisual.AnimateHit(); + await currentFighterVisual.AnimatePosToBase(); + } } \ No newline at end of file diff --git a/scripts/CSharp/Common/Fight/AllFightersVisual.cs b/scripts/CSharp/Common/Fight/AllFightersVisual.cs index da9a63e..678deee 100644 --- a/scripts/CSharp/Common/Fight/AllFightersVisual.cs +++ b/scripts/CSharp/Common/Fight/AllFightersVisual.cs @@ -122,4 +122,11 @@ public partial class AllFightersVisual : Node } #endregion + + public FighterVisual GetVisualForFighter(FightWorld.Fighter fighter) + { + return _fighterVisuals.TryGetValue(fighter, out var visual) + ? visual + : throw new InvalidOperationException("No visual for this fighter"); + } } \ No newline at end of file diff --git a/scripts/CSharp/Common/Fight/FightHappeningStateDebugger.cs b/scripts/CSharp/Common/Fight/FightHappeningStateDebugger.cs index b9c4a70..3c6bfc1 100644 --- a/scripts/CSharp/Common/Fight/FightHappeningStateDebugger.cs +++ b/scripts/CSharp/Common/Fight/FightHappeningStateDebugger.cs @@ -7,10 +7,13 @@ public partial class FightHappeningStateDebugger : Node { [Export] private Label _label; + [Export] private Label _current; + private FightWorld.FightHappeningData Data => FightWorld.Instance.fightHappeningData!; public void StateChange(FightHappening.FightState from, FightHappening.FightState to) { + _current.Text = $"{to}"; _label.Text += $"State changed from {from} to {to}\n"; switch (to) { @@ -49,5 +52,6 @@ public partial class FightHappeningStateDebugger : Node default: throw new ArgumentOutOfRangeException(nameof(to), to, null); } + } } diff --git a/scripts/CSharp/Common/Fight/FighterAction.cs b/scripts/CSharp/Common/Fight/FighterAction.cs index a156089..789120d 100644 --- a/scripts/CSharp/Common/Fight/FighterAction.cs +++ b/scripts/CSharp/Common/Fight/FighterAction.cs @@ -60,7 +60,8 @@ public abstract class FighterAction /// /// Animates the action. /// - public virtual async Task AnimateAction() + /// + public virtual async Task AnimateAction(AllFightersVisual allFightersVisual) { } diff --git a/scripts/CSharp/Common/Fight/FighterVisual.cs b/scripts/CSharp/Common/Fight/FighterVisual.cs index ec2d6dc..f7da460 100644 --- a/scripts/CSharp/Common/Fight/FighterVisual.cs +++ b/scripts/CSharp/Common/Fight/FighterVisual.cs @@ -1,4 +1,5 @@ using System; +using System.Threading.Tasks; using Babushka.scripts.CSharp.Common.Fight.ActionDetails; using Godot; using Godot.Collections; @@ -67,31 +68,55 @@ public partial class FighterVisual : Node2D } // Animations - public void AttackAnimation(FightAttack attack) + //public void AttackAnimation(FightAttack attack) + //{ + // EmitSignalAttacking(); + // var tween = GetTree().CreateTween(); + // tween.TweenProperty(this, "global_position", attack.target.GlobalPosition, 0.15); + // tween.TweenCallback(Callable.From(() => attack.target?.HitAnimation(attack))); + // tween.TweenProperty(this, "position", new Vector2(0, 0), 0.7) + // .SetTrans(Tween.TransitionType.Cubic).SetEase(Tween.EaseType.Out); + //} + + public async Task AnimatePosToTarget(FighterVisual targetVisual, double duration = 0.15) { - EmitSignalAttacking(); var tween = GetTree().CreateTween(); - tween.TweenProperty(this, "global_position", attack.target.GlobalPosition, 0.15); - tween.TweenCallback(Callable.From(() => attack.target?.HitAnimation(attack))); - tween.TweenProperty(this, "position", new Vector2(0, 0), 0.7) - .SetTrans(Tween.TransitionType.Cubic).SetEase(Tween.EaseType.Out); + tween.TweenProperty(_visualParent, "global_position", targetVisual.GlobalPosition, 0.15); + await ToSignal(tween, "finished"); } - private void HitAnimation(FightAttack attack) + public async Task AnimatePosToBase(double duration = 0.7) { - EmitSignalDamageTaken(); var tween = GetTree().CreateTween(); - tween.TweenProperty(this, "scale", new Vector2(1.4f, 0.6f), 0.15); - tween.TweenProperty(this, "scale", new Vector2(1, 1), 0.4) - .SetTrans(Tween.TransitionType.Cubic).SetEase(Tween.EaseType.Out); + tween.TweenProperty(_visualParent, "position", new Vector2(0, 0), 0.15); + await ToSignal(tween, "finished"); } - public void HealAnimation() + public async Task AnimateHit() { - EmitSignalHealed(); var tween = GetTree().CreateTween(); - tween.TweenProperty(this, "scale", new Vector2(0.6f, 1.4f), 0.15); + tween.TweenProperty(this, "scale", new Vector2(1.4f, 0.6f), 0.15); tween.TweenProperty(this, "scale", new Vector2(1, 1), 0.4) .SetTrans(Tween.TransitionType.Cubic).SetEase(Tween.EaseType.Out); + await ToSignal(tween, "finished"); } + + + //private void HitAnimation(FightAttack attack) + //{ + // EmitSignalDamageTaken(); + // var tween = GetTree().CreateTween(); + // tween.TweenProperty(this, "scale", new Vector2(1.4f, 0.6f), 0.15); + // tween.TweenProperty(this, "scale", new Vector2(1, 1), 0.4) + // .SetTrans(Tween.TransitionType.Cubic).SetEase(Tween.EaseType.Out); + //} + // + //public void HealAnimation() + //{ + // EmitSignalHealed(); + // var tween = GetTree().CreateTween(); + // tween.TweenProperty(this, "scale", new Vector2(0.6f, 1.4f), 0.15); + // tween.TweenProperty(this, "scale", new Vector2(1, 1), 0.4) + // .SetTrans(Tween.TransitionType.Cubic).SetEase(Tween.EaseType.Out); + //} } \ No newline at end of file