Newer
Older
DungeonShooting / DungeonShooting_Godot / src / game / effects / Trail.cs
@小李xl 小李xl on 29 Jan 2024 2 KB 制作0010武器完成
  1. using Godot;
  2.  
  3. /// <summary>
  4. /// 拖尾效果
  5. /// </summary>
  6. public partial class Trail : Line2D, IPoolItem
  7. {
  8. /// <summary>
  9. /// 拖尾效果固定更新帧率
  10. /// </summary>
  11. public const int TrailUpdateFrame = 20;
  12. /// <summary>
  13. /// 拖尾最大点数
  14. /// </summary>
  15. public int MaxLength { get; set; } = 20;
  16. /// <summary>
  17. /// 拖尾绑定的物体
  18. /// </summary>
  19. public Node2D Target { get; private set; }
  20.  
  21. public bool IsDestroyed { get; private set; }
  22. public bool IsRecycled { get; set; }
  23. public string Logotype { get; set; }
  24.  
  25. private double _time = 0;
  26. private IPoolItem _targetPoolItem;
  27.  
  28. /// <summary>
  29. /// 设置拖尾跟随的物体
  30. /// </summary>
  31. public void SetTarget(Node2D target)
  32. {
  33. Target = target;
  34. if (target is IPoolItem poolItem)
  35. {
  36. _targetPoolItem = poolItem;
  37. }
  38. else
  39. {
  40. _targetPoolItem = null;
  41. }
  42.  
  43. if (target != null)
  44. {
  45. ClearPoints();
  46. }
  47.  
  48. _time = 1f / TrailUpdateFrame;
  49. }
  50.  
  51. public void SetColor(Color color)
  52. {
  53. Gradient.SetColor(0, color);
  54. color.A = 0;
  55. Gradient.SetColor(1, color);
  56. }
  57.  
  58. public override void _Process(double delta)
  59. {
  60. if (_targetPoolItem != null && _targetPoolItem.IsRecycled) //目标物体被回收
  61. {
  62. SetTarget(null);
  63. }
  64. _time += delta;
  65. var v = 1f / TrailUpdateFrame;
  66. if (_time >= v) //执行更新点
  67. {
  68. _time %= v;
  69.  
  70. var pointCount = GetPointCount();
  71. if (Target != null) //没有被回收
  72. {
  73. AddPoint(Target.GlobalPosition, 0);
  74. if (pointCount > MaxLength)
  75. {
  76. RemovePoint(pointCount);
  77. }
  78. }
  79. else //被回收了,
  80. {
  81. if (pointCount > 0)
  82. {
  83. RemovePoint(pointCount - 1);
  84. }
  85.  
  86. if (pointCount <= 1) //没有点了, 执行回收
  87. {
  88. ObjectPool.Reclaim(this);
  89. }
  90. }
  91. }
  92. else if (Target != null && GetPointCount() >= 2) //没有被回收, 更新第一个点
  93. {
  94. SetPointPosition(0, Target.GlobalPosition);
  95. }
  96. }
  97.  
  98. public void Destroy()
  99. {
  100. if (IsDestroyed)
  101. {
  102. return;
  103. }
  104.  
  105. IsDestroyed = true;
  106. QueueFree();
  107. }
  108. public void OnReclaim()
  109. {
  110. GetParent().CallDeferred(Node.MethodName.RemoveChild, this);
  111. Target = null;
  112. _targetPoolItem = null;
  113. }
  114.  
  115. public void OnLeavePool()
  116. {
  117. ClearPoints();
  118. _time = 0;
  119. ZIndex = 0;
  120. }
  121. }