Newer
Older
DungeonShooting / DungeonShooting_Godot / src / framework / MoveController.cs
  1.  
  2. using System.Collections.Generic;
  3. using Godot;
  4.  
  5. /// <summary>
  6. /// 移动控制器, 物体运动由力来控制, 不同方向的力速度最终会汇总
  7. /// </summary>
  8. public class MoveController : Component
  9. {
  10. /// <summary>
  11. /// 玩家受到的外力的集合
  12. /// </summary>
  13. private readonly List<ExternalForce> _forceList = new List<ExternalForce>();
  14.  
  15. /// <summary>
  16. /// 这个速度就是玩家当前物理帧移动的真实速率, 该速度由物理帧循环更新, 并不会马上更新
  17. /// 该速度就是 BasisVelocity + 外力总和
  18. /// </summary>
  19. public Vector2 Velocity => _velocity;
  20.  
  21. private Vector2 _velocity = Vector2.Zero;
  22.  
  23.  
  24. /// <summary>
  25. /// 玩家的基础移动速率
  26. /// </summary>
  27. public Vector2 BasisVelocity
  28. {
  29. get => _basisVelocity;
  30. set => _basisVelocity = value;
  31. }
  32.  
  33. private Vector2 _basisVelocity = Vector2.Zero;
  34.  
  35. /// <summary>
  36. /// 获取所有外力对象
  37. /// </summary>
  38. public ExternalForce[] GetAllForce()
  39. {
  40. return _forceList.ToArray();
  41. }
  42.  
  43. /// <summary>
  44. /// 根据名称添加一个外力, 并返回创建的外力的对象, 如果存在这个名称的外力, 移除之前的外力
  45. /// </summary>
  46. public ExternalForce AddForce(string name)
  47. {
  48. var f = new ExternalForce(name);
  49. AddForce(f);
  50. return f;
  51. }
  52.  
  53. /// <summary>
  54. /// 根据对象添加一个外力力, 如果存在这个名称的外力, 移除之前的外力
  55. /// </summary>
  56. public T AddForce<T>(T force) where T : ExternalForce
  57. {
  58. RemoveForce(force.Name);
  59. _forceList.Add(force);
  60. return force;
  61. }
  62.  
  63. /// <summary>
  64. /// 根据名称移除一个外力
  65. /// </summary>
  66. public void RemoveForce(string name)
  67. {
  68. for (var i = 0; i < _forceList.Count; i++)
  69. {
  70. if (_forceList[i].Name == name)
  71. {
  72. _forceList.RemoveAt(i);
  73. return;
  74. }
  75. }
  76. }
  77.  
  78. /// <summary>
  79. /// 根据名称获取一个外力
  80. /// </summary>
  81. public ExternalForce GetForce(string name)
  82. {
  83. for (var i = 0; i < _forceList.Count; i++)
  84. {
  85. var externalForce = _forceList[i];
  86. if (externalForce.Name == name)
  87. {
  88. return externalForce;
  89. }
  90. }
  91.  
  92. return null;
  93. }
  94.  
  95. /// <summary>
  96. /// 检车是否有当前名称的外力对象
  97. /// </summary>
  98. public bool ContainsForce(string name)
  99. {
  100. for (var i = 0; i < _forceList.Count; i++)
  101. {
  102. var externalForce = _forceList[i];
  103. if (externalForce.Name == name)
  104. {
  105. return true;
  106. }
  107. }
  108.  
  109. return false;
  110. }
  111.  
  112. /// <summary>
  113. /// 根据对象移除一个外力
  114. /// </summary>
  115. public void RemoveForce(ExternalForce force)
  116. {
  117. RemoveForce(force.Name);
  118. }
  119.  
  120. /// <summary>
  121. /// 移除所有外力
  122. /// </summary>
  123. public void ClearForce()
  124. {
  125. _forceList.Clear();
  126. }
  127.  
  128. public override void PhysicsProcess(float delta)
  129. {
  130. if (_basisVelocity == Vector2.Zero && _forceList.Count == 0)
  131. {
  132. return;
  133. }
  134.  
  135. //先调用更新
  136. var externalForces = _forceList.ToArray();
  137. foreach (var fore in externalForces)
  138. {
  139. if (fore.Enable)
  140. fore.PhysicsProcess(delta);
  141. }
  142.  
  143. //外力总和
  144. var finallyEf = new Vector2();
  145. foreach (var fore in externalForces)
  146. {
  147. if (fore.Enable)
  148. finallyEf += fore.Velocity;
  149. }
  150.  
  151. //最终速率
  152. var finallyVelocity = _basisVelocity + finallyEf;
  153.  
  154. if (finallyVelocity != Vector2.Zero)
  155. {
  156. //计算移动
  157. _velocity = ActivityObject.MoveAndSlide(finallyVelocity);
  158.  
  159. //调整外力速率
  160. if (externalForces.Length > 0)
  161. {
  162. //x轴外力
  163. var scaleX = finallyEf.x == 0f ? 0 : Mathf.Abs((_velocity.x - _basisVelocity.x) / finallyEf.x);
  164. //y轴外力
  165. var scaleY = finallyEf.y == 0f ? 0 : Mathf.Abs((_velocity.y - _basisVelocity.y) / finallyEf.y);
  166. foreach (var force in _forceList)
  167. {
  168. if (force.Enable)
  169. {
  170. var velocity = force.Velocity;
  171. force.Velocity = new Vector2(velocity.x * scaleX, velocity.y * scaleY);
  172. }
  173. }
  174. }
  175. }
  176. else
  177. {
  178. _velocity = finallyEf;
  179. }
  180. }
  181. }