Newer
Older
DungeonShooting / DungeonShooting_Godot / src / framework / components / MoveController.cs
@小李xl 小李xl on 28 Dec 2022 6 KB 地牢生成功能, 开发中...
  1.  
  2. using System.Collections.Generic;
  3. using Godot;
  4.  
  5. /// <summary>
  6. /// 移动控制器, 物体运动由力来控制, 不同方向的力速度最终会汇总
  7. /// </summary>
  8. public class MoveController : Component
  9. {
  10. private static long _index = 0;
  11.  
  12. /// <summary>
  13. /// 玩家受到的外力的集合
  14. /// </summary>
  15. private readonly List<ExternalForce> _forceList = new List<ExternalForce>();
  16.  
  17. /// <summary>
  18. /// 这个速度就是玩家当前物理帧移动的真实速率, 该速度由物理帧循环更新, 并不会马上更新
  19. /// 该速度就是 BasisVelocity + 外力总和
  20. /// </summary>
  21. public Vector2 Velocity => _velocity;
  22.  
  23. private Vector2 _velocity = Vector2.Zero;
  24.  
  25.  
  26. /// <summary>
  27. /// 玩家的基础移动速率
  28. /// </summary>
  29. public Vector2 BasisVelocity
  30. {
  31. get => _basisVelocity;
  32. set => _basisVelocity = value;
  33. }
  34.  
  35. private Vector2 _basisVelocity = Vector2.Zero;
  36.  
  37. /// <summary>
  38. /// 获取所有外力对象
  39. /// </summary>
  40. public ExternalForce[] GetAllForce()
  41. {
  42. return _forceList.ToArray();
  43. }
  44.  
  45. /// <summary>
  46. /// 快速窗口一个外力, 该外力为匿名外力, 当速率变为 0 时自动销毁
  47. /// </summary>
  48. /// <param name="velocity">外力速率</param>
  49. /// <param name="resistance">阻力大小</param>
  50. public ExternalForce AddForce(Vector2 velocity, float resistance)
  51. {
  52. var force = AddForce("_anonymity_" + _index++);
  53. force.Velocity = velocity;
  54. force.Resistance = resistance;
  55. return force;
  56. }
  57.  
  58. /// <summary>
  59. /// 根据名称添加一个外力, 并返回创建的外力的对象, 如果存在这个名称的外力, 移除之前的外力
  60. /// </summary>
  61. public ExternalForce AddForce(string name)
  62. {
  63. var f = new ExternalForce(name);
  64. AddForce(f);
  65. return f;
  66. }
  67.  
  68. /// <summary>
  69. /// 根据对象添加一个外力力, 如果存在这个名称的外力, 移除之前的外力
  70. /// </summary>
  71. public T AddForce<T>(T force) where T : ExternalForce
  72. {
  73. RemoveForce(force.Name);
  74. _forceList.Add(force);
  75. return force;
  76. }
  77.  
  78. /// <summary>
  79. /// 根据名称移除一个外力
  80. /// </summary>
  81. public void RemoveForce(string name)
  82. {
  83. for (var i = 0; i < _forceList.Count; i++)
  84. {
  85. if (_forceList[i].Name == name)
  86. {
  87. _forceList.RemoveAt(i);
  88. return;
  89. }
  90. }
  91. }
  92.  
  93. /// <summary>
  94. /// 根据名称获取一个外力
  95. /// </summary>
  96. public ExternalForce GetForce(string name)
  97. {
  98. for (var i = 0; i < _forceList.Count; i++)
  99. {
  100. var externalForce = _forceList[i];
  101. if (externalForce.Name == name)
  102. {
  103. return externalForce;
  104. }
  105. }
  106.  
  107. return null;
  108. }
  109.  
  110. /// <summary>
  111. /// 检车是否有当前名称的外力对象
  112. /// </summary>
  113. public bool ContainsForce(string name)
  114. {
  115. for (var i = 0; i < _forceList.Count; i++)
  116. {
  117. var externalForce = _forceList[i];
  118. if (externalForce.Name == name)
  119. {
  120. return true;
  121. }
  122. }
  123.  
  124. return false;
  125. }
  126.  
  127. /// <summary>
  128. /// 根据对象移除一个外力
  129. /// </summary>
  130. public void RemoveForce(ExternalForce force)
  131. {
  132. RemoveForce(force.Name);
  133. }
  134.  
  135. /// <summary>
  136. /// 移除所有外力
  137. /// </summary>
  138. public void ClearForce()
  139. {
  140. _forceList.Clear();
  141. }
  142.  
  143. public override void PhysicsProcess(float delta)
  144. {
  145. if (_basisVelocity == Vector2.Zero && _forceList.Count == 0)
  146. {
  147. return;
  148. }
  149.  
  150. //先调用更新
  151. var externalForces = _forceList.ToArray();
  152. foreach (var fore in externalForces)
  153. {
  154. if (fore.Enable)
  155. fore.PhysicsProcess(delta);
  156. }
  157.  
  158. //外力总和
  159. var finallyEf = new Vector2();
  160. foreach (var fore in externalForces)
  161. {
  162. if (fore.Enable)
  163. finallyEf += fore.Velocity;
  164. }
  165.  
  166. //最终速率
  167. var finallyVelocity = _basisVelocity + finallyEf;
  168.  
  169. if (finallyVelocity != Vector2.Zero)
  170. {
  171. //计算移动
  172. _velocity = ActivityObject.MoveAndSlide(finallyVelocity);
  173. if (_velocity.x == 0f && _basisVelocity.x * finallyVelocity.x > 0)
  174. {
  175. _basisVelocity.x = 0;
  176. }
  177.  
  178. if (_velocity.y == 0f && _basisVelocity.y * finallyVelocity.y > 0)
  179. {
  180. _basisVelocity.y = 0;
  181. }
  182.  
  183. //调整外力速率
  184. if (externalForces.Length > 0)
  185. {
  186. for (var i = 0; i < _forceList.Count; i++)
  187. {
  188. var force = _forceList[i];
  189. if (force.Enable)
  190. {
  191. var velocity = force.Velocity;
  192. force.Velocity = new Vector2(
  193. _velocity.x == 0f && velocity.x * finallyVelocity.x > 0 ? 0 : velocity.x,
  194. _velocity.y == 0f && velocity.y * finallyVelocity.y > 0 ? 0 : velocity.y
  195. );
  196.  
  197. if (force.Resistance != 0)
  198. {
  199. force.Velocity = force.Velocity.MoveToward(Vector2.Zero, force.Resistance * delta);
  200. }
  201.  
  202. if (force.AutoDestroy && force.Velocity == Vector2.Zero)
  203. {
  204. _forceList.RemoveAt(i--);
  205. }
  206. }
  207. }
  208. }
  209. }
  210. else
  211. {
  212. _velocity = finallyEf;
  213. }
  214. }
  215.  
  216. public override void DebugDraw()
  217. {
  218. var globalRotation = GlobalRotation;
  219. ActivityObject.DrawLine(Vector2.Zero, BasisVelocity.Rotated(-globalRotation), Colors.Yellow);
  220. foreach (var force in _forceList)
  221. {
  222. ActivityObject.DrawLine(Vector2.Zero, force.Velocity.Rotated(-globalRotation), Colors.YellowGreen);
  223. }
  224. }
  225. }