diff --git a/DungeonShooting_Godot/resource/effects/Hit.tres b/DungeonShooting_Godot/resource/effects/Hit.tres new file mode 100644 index 0000000..542a423 --- /dev/null +++ b/DungeonShooting_Godot/resource/effects/Hit.tres @@ -0,0 +1,15 @@ +[gd_resource type="SpriteFrames" load_steps=6 format=2] + +[ext_resource path="res://resource/sprite/effect/hit/hit2.png" type="Texture" id=1] +[ext_resource path="res://resource/sprite/effect/hit/hit4.png" type="Texture" id=2] +[ext_resource path="res://resource/sprite/effect/hit/hit0.png" type="Texture" id=3] +[ext_resource path="res://resource/sprite/effect/hit/hit3.png" type="Texture" id=4] +[ext_resource path="res://resource/sprite/effect/hit/hit1.png" type="Texture" id=5] + +[resource] +animations = [ { +"frames": [ ExtResource( 3 ), ExtResource( 5 ), ExtResource( 1 ), ExtResource( 4 ), ExtResource( 2 ) ], +"loop": true, +"name": "Hit", +"speed": 20.0 +} ] diff --git a/DungeonShooting_Godot/src/game/effect/SpecialEffect.cs b/DungeonShooting_Godot/src/game/effect/SpecialEffect.cs deleted file mode 100644 index caa20ec..0000000 --- a/DungeonShooting_Godot/src/game/effect/SpecialEffect.cs +++ /dev/null @@ -1,10 +0,0 @@ - -using Godot; - -/// -/// 基础特效播放类, 用于播放序列帧动画特效, 播完就回收 -/// -public class SpecialEffect : AnimatedSprite -{ - -} \ No newline at end of file diff --git a/DungeonShooting_Godot/src/game/item/weapon/bullet/Bullet.cs b/DungeonShooting_Godot/src/game/item/weapon/bullet/Bullet.cs index cfdffde..048e65d 100644 --- a/DungeonShooting_Godot/src/game/item/weapon/bullet/Bullet.cs +++ b/DungeonShooting_Godot/src/game/item/weapon/bullet/Bullet.cs @@ -13,7 +13,7 @@ CollisionArea.Connect("body_entered", this, nameof(_BodyEntered)); Collision.Disabled = true; - + MaxDistance = maxDistance; Position = position; Rotation = rotation; @@ -21,7 +21,7 @@ } public Area2D CollisionArea { get; } - + // 最大飞行距离 private float MaxDistance; @@ -59,10 +59,13 @@ } //播放受击动画 - Node2D hit = ResourceManager.Load(ResourcePath.prefab_effect_Hit_tscn).Instance(); - hit.RotationDegrees = Utils.RandRangeInt(0, 360); - hit.GlobalPosition = GlobalPosition; - GameApplication.Instance.Room.GetRoot(true).AddChild(hit); + // Node2D hit = ResourceManager.Load(ResourcePath.prefab_effect_Hit_tscn).Instance(); + // hit.RotationDegrees = Utils.RandRangeInt(0, 360); + // hit.GlobalPosition = GlobalPosition; + // GameApplication.Instance.Room.GetRoot(true).AddChild(hit); + + SpecialEffectManager.Play(ResourcePath.resource_effects_Hit_tres, "Hit", GlobalPosition, + Mathf.Deg2Rad(Utils.RandRangeInt(0, 360)), Vector2.One, new Vector2(1, 11), 0); Destroy(); } diff --git a/DungeonShooting_Godot/src/game/manager/ResourcePath.cs b/DungeonShooting_Godot/src/game/manager/ResourcePath.cs index ad18b1b..02d93ff 100644 --- a/DungeonShooting_Godot/src/game/manager/ResourcePath.cs +++ b/DungeonShooting_Godot/src/game/manager/ResourcePath.cs @@ -25,6 +25,7 @@ public const string prefab_weapon_Weapon_tscn = "res://prefab/weapon/Weapon.tscn"; public const string prefab_weapon_bullet_Bullet_tscn = "res://prefab/weapon/bullet/Bullet.tscn"; public const string prefab_weapon_shell_ShellCase_tscn = "res://prefab/weapon/shell/ShellCase.tscn"; + public const string resource_effects_Hit_tres = "res://resource/effects/Hit.tres"; public const string resource_font_cn_font_12_tres = "res://resource/font/cn_font_12.tres"; public const string resource_font_cn_font_18_tres = "res://resource/font/cn_font_18.tres"; public const string resource_font_cn_font_35_tres = "res://resource/font/cn_font_35.tres"; diff --git a/DungeonShooting_Godot/src/game/manager/SpecialEffectManager.cs b/DungeonShooting_Godot/src/game/manager/SpecialEffectManager.cs index 4ba9920..f71a6a7 100644 --- a/DungeonShooting_Godot/src/game/manager/SpecialEffectManager.cs +++ b/DungeonShooting_Godot/src/game/manager/SpecialEffectManager.cs @@ -1,4 +1,5 @@  +using System.Collections.Generic; using Godot; /// @@ -6,18 +7,92 @@ /// public static class SpecialEffectManager { + + private static Stack _specialEffectStack = new Stack(); + + /// + /// 基础特效播放类, 用于播放序列帧动画特效, 播完就回收 + /// + private class SpecialEffect : AnimatedSprite + { + //记录循环次数 + public int LoopCount; + + private int currLoopCount = 0; + public override void _Ready() + { + Connect("animation_finished", this, nameof(OnAnimationFinished)); + } + + //动画结束 + private void OnAnimationFinished() + { + currLoopCount++; + if (currLoopCount >= LoopCount) + { + Over(); + } + } + + private void Over() + { + currLoopCount = 0; + RecycleSpecialEffect(this); + } + } + /// /// 在场景指定位置播放一个特效 /// /// 特效SpriteFrames资源路径 + /// 动画名称 /// 坐标 - /// 旋转角度 + /// 旋转角度, 弧度制 /// 缩放 + /// 图像偏移 /// 层级 /// 播放速度 /// 循环次数, 到达该次数特效停止播放 - public static void Play(string path, Vector2 pos, float rotation, Vector2 scale, int zIndex, float speed = 1, int loopCount = 1) + public static void Play(string path, string animName, Vector2 pos, float rotation, Vector2 scale, Vector2 offset, int zIndex, float speed = 1, int loopCount = 1) { + var spriteFrames = ResourceManager.Load(path); + var specialEffect = GetSpecialEffect(); + specialEffect.GlobalPosition = pos; + specialEffect.Rotation = rotation; + specialEffect.Scale = scale; + specialEffect.ZIndex = zIndex; + specialEffect.Offset = offset; + specialEffect.SpeedScale = speed; + specialEffect.LoopCount = loopCount; + specialEffect.Frames = spriteFrames; + specialEffect.Play(animName); + GameApplication.Instance.Room.GetRoot(true).AddChild(specialEffect); + } + + private static SpecialEffect GetSpecialEffect() + { + if (_specialEffectStack.Count > 0) + { + return _specialEffectStack.Pop(); + } + + return new SpecialEffect(); + } + + /// + /// 回收2D音频播放节点 + /// + private static void RecycleSpecialEffect(SpecialEffect inst) + { + var parent = inst.GetParent(); + if (parent != null) + { + parent.RemoveChild(inst); + } + + inst.Playing = false; + inst.Frames = null; + _specialEffectStack.Push(inst); } } \ No newline at end of file