Newer
Older
DungeonShooting / DungeonShooting_Godot / src / camera / MainCamera.cs
  1. using System.Collections.Generic;
  2. using Godot;
  3.  
  4. public class MainCamera : Camera2D
  5. {
  6. /// <summary>
  7. /// 当前场景的相机对象
  8. /// </summary>
  9. public static MainCamera Main { get; private set; }
  10.  
  11. /// <summary>
  12. /// 恢复系数
  13. /// </summary>
  14. [Export]
  15. public float RecoveryCoefficient = 100f;
  16. /// <summary>
  17. /// 抖动开关
  18. /// </summary>
  19. public bool Enable { get; set; } = true;
  20.  
  21. private long _index = 0;
  22. private Vector2 _prossesDistance = Vector2.Zero;
  23. private Vector2 _prossesDirectiona = Vector2.Zero;
  24. private readonly Dictionary<long, Vector2> _shakeMap = new Dictionary<long, Vector2>();
  25.  
  26. public override void _Ready()
  27. {
  28. Main = this;
  29. }
  30. public override void _PhysicsProcess(float delta)
  31. {
  32. _Shake(delta);
  33. }
  34.  
  35. /// <summary>
  36. /// 设置帧抖动, 结束后自动清零, 需要每一帧调用
  37. /// </summary>
  38. /// <param name="value">抖动的力度</param>
  39. public void ProssesShake(Vector2 value)
  40. {
  41. if (value.Length() > _prossesDistance.Length())
  42. {
  43. _prossesDistance = value;
  44. }
  45. }
  46.  
  47. public void ProssesDirectionalShake(Vector2 value)
  48. {
  49. _prossesDirectiona += value;
  50. }
  51.  
  52. /// <summary>
  53. /// 创建一个抖动, 并设置抖动时间
  54. /// </summary>
  55. /// <param name="value">抖动力度</param>
  56. /// <param name="time">抖动生效时间</param>
  57. public async void CreateShake(Vector2 value, float time)
  58. {
  59. if (time > 0)
  60. {
  61. long tempIndex = _index++;
  62. SceneTreeTimer sceneTreeTimer = GetTree().CreateTimer(time);
  63. _shakeMap[tempIndex] = value;
  64. await ToSignal(sceneTreeTimer, "timeout");
  65. _shakeMap.Remove(tempIndex);
  66. }
  67. }
  68.  
  69. //抖动调用
  70. private void _Shake(float delta)
  71. {
  72. if (Enable)
  73. {
  74. var _distance = _CalculateDistance();
  75. Offset += new Vector2(
  76. (float)GD.RandRange(-_distance.x, _distance.x) - Offset.x,
  77. (float)GD.RandRange(-_distance.y, _distance.y) - Offset.y
  78. );
  79. Offset += _prossesDirectiona;
  80. _prossesDistance = Vector2.Zero;
  81. _prossesDirectiona = Vector2.Zero;
  82. }
  83. else
  84. {
  85. Offset = Offset.LinearInterpolate(Vector2.Zero, RecoveryCoefficient * delta);
  86. }
  87. }
  88.  
  89. //计算相机需要抖动的值
  90. private Vector2 _CalculateDistance()
  91. {
  92. Vector2 temp = Vector2.Zero;
  93. float length = 0;
  94. foreach (var item in _shakeMap)
  95. {
  96. var value = item.Value;
  97. float tempLenght = value.Length();
  98. if (tempLenght > length)
  99. {
  100. length = tempLenght;
  101. temp = value;
  102. }
  103. }
  104. return _prossesDistance.Length() > length ? _prossesDistance : temp;
  105. }
  106.  
  107. }