From e7c1814d9822f8ddc48afca17d74c6f4f539756d Mon Sep 17 00:00:00 2001 From: Marco Date: Fri, 21 Mar 2025 15:16:50 +0100 Subject: [PATCH] Enemy FSM Animation --- .../PromoSample/Promo_Sample.aseprite | 3 ++ ExternalMaterial/PromoSample/Promo_Sample.png | 3 ++ .../PromoSample/Promo_Sample.png.import | 34 ++++++++++++++ Scenes/Actors/FairyGuard_New.tscn | 2 + Scenes/Actors/Fairy_FSM.tscn | 44 +++++++++++++++++-- Scenes/test.tscn | 18 +++++++- .../Actors/PlayerAnimationProvider.cs | 1 + Scripts/Components/FSM/Enemy/Alert.cs | 2 + .../Components/FSM/Enemy/AnimationModule.cs | 44 +++++++++++++++++++ .../FSM/Enemy/AnimationModule.cs.uid | 1 + Scripts/Components/FSM/Enemy/Shooting.cs | 3 +- Scripts/Tools.cs | 12 +++++ 12 files changed, 161 insertions(+), 6 deletions(-) create mode 100644 ExternalMaterial/PromoSample/Promo_Sample.aseprite create mode 100644 ExternalMaterial/PromoSample/Promo_Sample.png create mode 100644 ExternalMaterial/PromoSample/Promo_Sample.png.import create mode 100644 Scripts/Components/FSM/Enemy/AnimationModule.cs create mode 100644 Scripts/Components/FSM/Enemy/AnimationModule.cs.uid diff --git a/ExternalMaterial/PromoSample/Promo_Sample.aseprite b/ExternalMaterial/PromoSample/Promo_Sample.aseprite new file mode 100644 index 00000000..ec0c8201 --- /dev/null +++ b/ExternalMaterial/PromoSample/Promo_Sample.aseprite @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:09d5a5a1a80986ac9f3ac54613a4c5ed35d3a8c843864713b25200e1a0516584 +size 2292600 diff --git a/ExternalMaterial/PromoSample/Promo_Sample.png b/ExternalMaterial/PromoSample/Promo_Sample.png new file mode 100644 index 00000000..8a19f0a4 --- /dev/null +++ b/ExternalMaterial/PromoSample/Promo_Sample.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b82758a36d5e43b5cd2df4dfda915127839f0574a28e7592ac362ea2ddfa8701 +size 42719 diff --git a/ExternalMaterial/PromoSample/Promo_Sample.png.import b/ExternalMaterial/PromoSample/Promo_Sample.png.import new file mode 100644 index 00000000..a305008a --- /dev/null +++ b/ExternalMaterial/PromoSample/Promo_Sample.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://du8c4d3lm8f3c" +path="res://.godot/imported/Promo_Sample.png-fa44b56771bdcf367b2dd7f5f495a60e.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://ExternalMaterial/PromoSample/Promo_Sample.png" +dest_files=["res://.godot/imported/Promo_Sample.png-fa44b56771bdcf367b2dd7f5f495a60e.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/Scenes/Actors/FairyGuard_New.tscn b/Scenes/Actors/FairyGuard_New.tscn index 8825560b..13de0b30 100644 --- a/Scenes/Actors/FairyGuard_New.tscn +++ b/Scenes/Actors/FairyGuard_New.tscn @@ -111,6 +111,7 @@ script = ExtResource("3_tum7w") script = ExtResource("4_3noop") [node name="CollisionShape2D" type="CollisionShape2D" parent="."] +visible = false shape = SubResource("CircleShape2D_2b36v") [node name="AnimationHandler" type="Node2D" parent="." node_paths=PackedStringArray("_animatedSprite")] @@ -153,6 +154,7 @@ _maxResource = 3.0 WeaponData = ExtResource("11_kuimj") [node name="DamageReceiver" type="Node2D" parent="." node_paths=PackedStringArray("HealthProvider")] +visible = false script = ExtResource("12_fu5g7") HealthProvider = NodePath("../HealthProvider") BulletGroup = 2 diff --git a/Scenes/Actors/Fairy_FSM.tscn b/Scenes/Actors/Fairy_FSM.tscn index df8affd5..3e2d3043 100644 --- a/Scenes/Actors/Fairy_FSM.tscn +++ b/Scenes/Actors/Fairy_FSM.tscn @@ -1,4 +1,4 @@ -[gd_scene load_steps=22 format=3 uid="uid://clieeuln36a7a"] +[gd_scene load_steps=26 format=3 uid="uid://clieeuln36a7a"] [ext_resource type="Script" uid="uid://dn6dbog1s2818" path="res://Scripts/Components/FSM/Enemy/EnemyStateMachine.cs" id="1_27djw"] [ext_resource type="SpriteFrames" uid="uid://bcc5mlwwnkvri" path="res://Resources/Sprites/Fairy.tres" id="1_ho0th"] @@ -18,6 +18,9 @@ [ext_resource type="PackedScene" uid="uid://cj63k0dmk7tl1" path="res://Scenes/Weapons/enemy_weapon_base.tscn" id="15_ydpwc"] [ext_resource type="Resource" uid="uid://csdlihliv4cr8" path="res://Resources/Weapons/EnemyWeapon_simple.tres" id="16_pi7ab"] [ext_resource type="Script" uid="uid://dhsqsajq537qn" path="res://Scripts/Components/FSM/Enemy/EnemyAlarmModule.cs" id="18_4n750"] +[ext_resource type="Script" uid="uid://bo5sgbv1t8ril" path="res://Scripts/Components/Actors/PlayerAnimationProvider.cs" id="19_km3yo"] +[ext_resource type="Material" uid="uid://dnvwgyt2tbqmr" path="res://Resources/Materials/Player_Blink_Teleport_Material.tres" id="20_8kl2e"] +[ext_resource type="Script" uid="uid://dncdgq843sj2f" path="res://Scripts/Components/FSM/Enemy/AnimationModule.cs" id="21_8kl2e"] [sub_resource type="CircleShape2D" id="CircleShape2D_pnkma"] @@ -27,6 +30,15 @@ radius = 29.0 [sub_resource type="CircleShape2D" id="CircleShape2D_6x22m"] radius = 5.0 +[sub_resource type="ParticleProcessMaterial" id="ParticleProcessMaterial_poxpj"] +particle_flag_disable_z = true +emission_shape = 2 +emission_sphere_radius = 16.0 +orbit_velocity_min = -1.0 +orbit_velocity_max = 1.098 +gravity = Vector3(0, 0, 0) +color = Color(0.0392157, 0.380392, 1, 1) + [node name="FairyFsm" type="CharacterBody2D" node_paths=PackedStringArray("EnemyFSM")] collision_layer = 16 collision_mask = 33 @@ -50,21 +62,23 @@ script = ExtResource("4_kjmts") StorageModule = NodePath("../../Storage") PlayerDetection = NodePath("../../PlayerDetection") DamageReceiver = NodePath("../../DamageReceiver") -_moduleNodes = [NodePath("../../AlarmModule")] +_moduleNodes = [NodePath("../../AlarmModule"), NodePath("../../AnimationModule")] -[node name="Alert" type="Node2D" parent="StateMachine" node_paths=PackedStringArray("StorageModule", "PlayerDetection", "DamageReceiver", "NavigationModule")] +[node name="Alert" type="Node2D" parent="StateMachine" node_paths=PackedStringArray("StorageModule", "PlayerDetection", "DamageReceiver", "NavigationModule", "_moduleNodes")] script = ExtResource("5_f112g") StorageModule = NodePath("../../Storage") PlayerDetection = NodePath("../../PlayerDetection") DamageReceiver = NodePath("../../DamageReceiver") NavigationModule = NodePath("../../NavigationModule") +_moduleNodes = [NodePath("../../AnimationModule")] -[node name="Shooting" type="Node2D" parent="StateMachine" node_paths=PackedStringArray("StorageModule", "PlayerDetection", "DamageReceiver", "EquippedWeapon")] +[node name="Shooting" type="Node2D" parent="StateMachine" node_paths=PackedStringArray("StorageModule", "PlayerDetection", "DamageReceiver", "EquippedWeapon", "_moduleNodes")] script = ExtResource("7_br0mr") StorageModule = NodePath("../../Storage") PlayerDetection = NodePath("../../PlayerDetection") DamageReceiver = NodePath("../../DamageReceiver") EquippedWeapon = NodePath("../../EnemyWeapon") +_moduleNodes = [NodePath("../../AnimationModule")] [node name="Dead" type="Node2D" parent="StateMachine"] script = ExtResource("8_pi7ab") @@ -122,6 +136,28 @@ WeaponData = ExtResource("16_pi7ab") script = ExtResource("18_4n750") PlayerDetection = NodePath("../PlayerDetection") +[node name="AnimationProvider" type="Node2D" parent="." node_paths=PackedStringArray("_animatedSprite", "_shieldParticles")] +script = ExtResource("19_km3yo") +_animatedSprite = NodePath("../AnimatedSprite2D") +_shieldParticles = NodePath("ShieldParticles") +WalkRightAnimationName = &"right" +WalkLeftAnimationName = &"left" +WalkDownAnimationName = &"down" +WalkUpAnimationName = &"up" +BlinkMaterial = ExtResource("20_8kl2e") + +[node name="ShieldParticles" type="GPUParticles2D" parent="AnimationProvider"] +emitting = false +amount = 32 +lifetime = 0.4 +one_shot = true +process_material = SubResource("ParticleProcessMaterial_poxpj") + +[node name="AnimationModule" type="Node2D" parent="." node_paths=PackedStringArray("AnimationProvider", "StorageModule")] +script = ExtResource("21_8kl2e") +AnimationProvider = NodePath("../AnimationProvider") +StorageModule = NodePath("../Storage") + [connection signal="area_entered" from="PlayerDetection" to="PlayerDetection" method="_on_area_entered"] [connection signal="area_exited" from="PlayerDetection" to="PlayerDetection" method="_on_area_exited"] [connection signal="area_entered" from="DamageReceiver" to="DamageReceiver" method="_on_damage_hitbox_area_entered"] diff --git a/Scenes/test.tscn b/Scenes/test.tscn index 1a918db9..0e57b140 100644 --- a/Scenes/test.tscn +++ b/Scenes/test.tscn @@ -1,4 +1,4 @@ -[gd_scene load_steps=140 format=4 uid="uid://bv451a8wgty4u"] +[gd_scene load_steps=141 format=4 uid="uid://bv451a8wgty4u"] [ext_resource type="Script" uid="uid://doxmbokehw8ci" path="res://Scripts/GameManager.cs" id="1_8tmoj"] [ext_resource type="PackedScene" uid="uid://c4pr2707hbeph" path="res://Scenes/Actors/fsm_player.tscn" id="2_ksslq"] @@ -111,6 +111,7 @@ [ext_resource type="PackedScene" uid="uid://1yxieu8ekvkm" path="res://Scenes/Items/Heart_Extend_Pickup.tscn" id="99_xwjvv"] [ext_resource type="PackedScene" uid="uid://8yggb3ay3hr0" path="res://Scenes/Items/Yellow_Keycard.tscn" id="101_l476f"] [ext_resource type="PackedScene" uid="uid://ey71mxa5ocpn" path="res://Scenes/Items/Shield_Extend_Pickup.tscn" id="103_0bqta"] +[ext_resource type="PackedScene" uid="uid://clieeuln36a7a" path="res://Scenes/Actors/Fairy_FSM.tscn" id="104_0bqta"] [ext_resource type="PackedScene" uid="uid://ue3i2qyhhtbg" path="res://Scenes/Interactable/control_pad_yellow_keycard.tscn" id="109_j6vrf"] [sub_resource type="Resource" id="Resource_6sau4"] @@ -793,6 +794,9 @@ position = Vector2(-1016, 152) [node name="Camera" parent="Parallax2D/Factory Tilemaps/LevelProps" instance=ExtResource("16_clqjt")] position = Vector2(-1207, -58) +[node name="Camera2" parent="Parallax2D/Factory Tilemaps/LevelProps" instance=ExtResource("16_clqjt")] +position = Vector2(-1912, 12) + [node name="ControlPad6" parent="Parallax2D/Factory Tilemaps/LevelProps" node_paths=PackedStringArray("Target") instance=ExtResource("12_hfkf1")] position = Vector2(-1462, -60) Target = NodePath("../HorizontalDoor4") @@ -1264,6 +1268,18 @@ position = Vector2(-1646, 38) [node name="ShieldExtendPickup2" parent="Parallax2D/Factory Tilemaps/LevelProps" instance=ExtResource("103_0bqta")] position = Vector2(-1097.18, -108.733) +[node name="FairyFsm" parent="Parallax2D/Factory Tilemaps/LevelProps" instance=ExtResource("104_0bqta")] +position = Vector2(-1829, 49) + +[node name="FairyFsm2" parent="Parallax2D/Factory Tilemaps/LevelProps" instance=ExtResource("104_0bqta")] +position = Vector2(-1911, 69) + +[node name="FairyFsm3" parent="Parallax2D/Factory Tilemaps/LevelProps" instance=ExtResource("104_0bqta")] +position = Vector2(-1964, -47) + +[node name="FairyFsm4" parent="Parallax2D/Factory Tilemaps/LevelProps" instance=ExtResource("104_0bqta")] +position = Vector2(-1497, -17) + [node name="PlayerParent" type="Node2D" parent="Parallax2D/Factory Tilemaps"] [node name="BeamShadows" type="TileMapLayer" parent="Parallax2D/Factory Tilemaps"] diff --git a/Scripts/Components/Actors/PlayerAnimationProvider.cs b/Scripts/Components/Actors/PlayerAnimationProvider.cs index b52e3a89..4dd18cf2 100644 --- a/Scripts/Components/Actors/PlayerAnimationProvider.cs +++ b/Scripts/Components/Actors/PlayerAnimationProvider.cs @@ -149,6 +149,7 @@ public partial class PlayerAnimationProvider : Node2D public void PlayDeathAnimation() { + if (_deathParticles is null) return; this.CreateSibling(_deathParticles, this.GlobalPosition); _animatedSprite.Visible = false; } diff --git a/Scripts/Components/FSM/Enemy/Alert.cs b/Scripts/Components/FSM/Enemy/Alert.cs index 13e683ab..83b66238 100644 --- a/Scripts/Components/FSM/Enemy/Alert.cs +++ b/Scripts/Components/FSM/Enemy/Alert.cs @@ -98,6 +98,8 @@ public partial class Alert : EnemyStateBase } NavigationModule.Move(); + + StorageModule.FacingDirection = MainObject.Velocity.SnapToCardinal().Normalized(); } private void MoveTowardsPosition(Vector2 position) diff --git a/Scripts/Components/FSM/Enemy/AnimationModule.cs b/Scripts/Components/FSM/Enemy/AnimationModule.cs new file mode 100644 index 00000000..d0ade049 --- /dev/null +++ b/Scripts/Components/FSM/Enemy/AnimationModule.cs @@ -0,0 +1,44 @@ +using Cirno.Scripts.Enums; +using Godot; + +namespace Cirno.Scripts.Components.FSM.Enemy; + +public partial class AnimationModule : ModuleBase +{ + private IStateMachine _machine; + + [Export] public PlayerAnimationProvider AnimationProvider { get; set; } + + [Export] public EnemyStorageModule StorageModule { get; set; } + + public override void EnterState(EnemyState state) + { + AnimationProvider.SetAnimation(StorageModule.FacingDirection); + AnimationProvider.SetAnimation(Vector2.Zero); + } + + public override void ExitState(EnemyState state) + { + AnimationProvider.SetAnimation(Vector2.Zero); + } + + public override void Init(IStateMachine machine) + { + _machine = machine; + } + + public override void Process(double delta) + { + AnimationProvider.SetAnimation(StorageModule.FacingDirection); + + if (_machine.MainObject.Velocity == Vector2.Zero) + { + AnimationProvider.SetAnimation(Vector2.Zero); + } + } + + public override void PhysicsProcess(double delta) + { + + } +} \ No newline at end of file diff --git a/Scripts/Components/FSM/Enemy/AnimationModule.cs.uid b/Scripts/Components/FSM/Enemy/AnimationModule.cs.uid new file mode 100644 index 00000000..f8178f54 --- /dev/null +++ b/Scripts/Components/FSM/Enemy/AnimationModule.cs.uid @@ -0,0 +1 @@ +uid://dncdgq843sj2f diff --git a/Scripts/Components/FSM/Enemy/Shooting.cs b/Scripts/Components/FSM/Enemy/Shooting.cs index d10c680b..694cd8cd 100644 --- a/Scripts/Components/FSM/Enemy/Shooting.cs +++ b/Scripts/Components/FSM/Enemy/Shooting.cs @@ -95,7 +95,8 @@ public partial class Shooting : EnemyStateBase // Shoot at the player's last known position EquippedWeapon.ShootDirection = direction; - StorageModule.FacingDirection = direction; + //StorageModule.FacingDirection = direction; + StorageModule.FacingDirection = direction.SnapToCardinal().Normalized(); EquippedWeapon.Shoot(); } diff --git a/Scripts/Tools.cs b/Scripts/Tools.cs index ad6e13a1..5a00c1c2 100644 --- a/Scripts/Tools.cs +++ b/Scripts/Tools.cs @@ -89,4 +89,16 @@ public static class Tools return angles[Mathf.PosMod((int)(direction.X + 4), 8)].Normalized(); } + + public static Vector2 SnapToCardinal(this Vector2 input) + { + if (Mathf.Abs(input.X) > Mathf.Abs(input.Y)) + { + return new Vector2(Mathf.Sign(input.X), 0); // Left or Right + } + else + { + return new Vector2(0, Mathf.Sign(input.Y)); // Up or Down + } + } }