Newer
Older
DungeonShooting / DungeonShooting_Godot / src / framework / activity / components / MoveController.cs
  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 => ActivityInstance.Velocity;
  22.  
  23. /// <summary>
  24. /// 物体的基础移动速率
  25. /// </summary>
  26. public Vector2 BasisVelocity
  27. {
  28. get => _basisVelocity;
  29. set => _basisVelocity = value;
  30. }
  31.  
  32. private Vector2 _basisVelocity = Vector2.Zero;
  33.  
  34. /// <summary>
  35. /// 缩放所有力对象, 包括基础速率
  36. /// </summary>
  37. public void ScaleAllForce(float scale)
  38. {
  39. foreach (var externalForce in _forceList)
  40. {
  41. externalForce.Velocity *= scale;
  42. }
  43.  
  44. BasisVelocity *= scale;
  45. }
  46. /// <summary>
  47. /// 设置所有力对象, 包括基础速率
  48. /// </summary>
  49. public void SetAllForce(Vector2 value)
  50. {
  51. foreach (var externalForce in _forceList)
  52. {
  53. externalForce.Velocity = value;
  54. }
  55.  
  56. BasisVelocity = value;
  57. }
  58. /// <summary>
  59. /// 获取所有外力对象
  60. /// </summary>
  61. public ExternalForce[] GetAllForce()
  62. {
  63. return _forceList.ToArray();
  64. }
  65.  
  66. /// <summary>
  67. /// 获取所有外力的数量
  68. /// </summary>
  69. public int GetForceCount()
  70. {
  71. return _forceList.Count;
  72. }
  73.  
  74. /// <summary>
  75. /// 快速创建一个外力, 该外力为匿名外力, 当速率变为 0 时自动销毁
  76. /// </summary>
  77. /// <param name="velocity">外力速率</param>
  78. /// <param name="resistance">阻力大小</param>
  79. public ExternalForce AddConstantForce(Vector2 velocity, float resistance)
  80. {
  81. var force = AddConstantForce("_anonymity_" + _index++);
  82. force.Velocity = velocity;
  83. force.Resistance = resistance;
  84. return force;
  85. }
  86. /// <summary>
  87. /// 快速创建一个外力, 该外力为匿名外力, 当速率变为 0 时自动销毁
  88. /// </summary>
  89. /// <param name="velocity">外力速率</param>
  90. public ExternalForce AddConstantForce(Vector2 velocity)
  91. {
  92. var force = AddConstantForce("_anonymity_" + _index++);
  93. force.Velocity = velocity;
  94. return force;
  95. }
  96.  
  97.  
  98. /// <summary>
  99. /// 根据名称添加一个外力, 并返回创建的外力的对象, 如果存在这个名称的外力, 移除之前的外力, 当速率变为 0 时不会自动销毁
  100. /// </summary>
  101. public ExternalForce AddConstantForce(string name)
  102. {
  103. var f = new ExternalForce(name);
  104. f.AutoDestroy = false;
  105. AddConstantForce(f);
  106. return f;
  107. }
  108.  
  109. /// <summary>
  110. /// 根据对象添加一个外力力, 如果存在这个名称的外力, 移除之前的外力
  111. /// </summary>
  112. public T AddConstantForce<T>(T force) where T : ExternalForce
  113. {
  114. RemoveForce(force.Name);
  115. _forceList.Add(force);
  116. return force;
  117. }
  118.  
  119. /// <summary>
  120. /// 根据名称移除一个外力
  121. /// </summary>
  122. public void RemoveForce(string name)
  123. {
  124. for (var i = 0; i < _forceList.Count; i++)
  125. {
  126. if (_forceList[i].Name == name)
  127. {
  128. _forceList.RemoveAt(i);
  129. return;
  130. }
  131. }
  132. }
  133.  
  134. /// <summary>
  135. /// 根据名称获取一个外力
  136. /// </summary>
  137. public ExternalForce GetForce(string name)
  138. {
  139. for (var i = 0; i < _forceList.Count; i++)
  140. {
  141. var externalForce = _forceList[i];
  142. if (externalForce.Name == name)
  143. {
  144. return externalForce;
  145. }
  146. }
  147.  
  148. return null;
  149. }
  150.  
  151. /// <summary>
  152. /// 检车是否有当前名称的外力对象
  153. /// </summary>
  154. public bool ContainsForce(string name)
  155. {
  156. for (var i = 0; i < _forceList.Count; i++)
  157. {
  158. var externalForce = _forceList[i];
  159. if (externalForce.Name == name)
  160. {
  161. return true;
  162. }
  163. }
  164.  
  165. return false;
  166. }
  167.  
  168. /// <summary>
  169. /// 根据对象移除一个外力
  170. /// </summary>
  171. public void RemoveForce(ExternalForce force)
  172. {
  173. RemoveForce(force.Name);
  174. }
  175.  
  176. /// <summary>
  177. /// 移除所有外力
  178. /// </summary>
  179. public void ClearForce()
  180. {
  181. _forceList.Clear();
  182. }
  183.  
  184. public override void PhysicsProcess(float delta)
  185. {
  186. if (_basisVelocity == Vector2.Zero && _forceList.Count == 0)
  187. {
  188. return;
  189. }
  190.  
  191. //先调用更新
  192. var externalForces = _forceList.ToArray();
  193. for (var i = 0; i < externalForces.Length; i++)
  194. {
  195. var force = externalForces[i];
  196. if (force.Enable)
  197. {
  198. force.PhysicsProcess(delta);
  199. //自动销毁
  200. if (force.AutoDestroy && force.Velocity == Vector2.Zero)
  201. {
  202. _forceList.Remove(force);
  203. externalForces[i] = null;
  204. }
  205. }
  206. }
  207.  
  208. //外力总和
  209. var finallyEf = new Vector2();
  210. foreach (var force in externalForces)
  211. {
  212. if (force != null && force.Enable)
  213. finallyEf += force.Velocity;
  214. }
  215.  
  216. //最终速率
  217. var finallyVelocity = _basisVelocity + finallyEf;
  218.  
  219. if (finallyVelocity != Vector2.Zero)
  220. {
  221. //计算移动
  222. ActivityInstance.Velocity = finallyVelocity;
  223. ActivityInstance.MoveAndSlide();
  224. //新速度
  225. var newVelocity = ActivityInstance.Velocity;
  226. if (newVelocity.X == 0f && _basisVelocity.X * finallyVelocity.X > 0)
  227. {
  228. _basisVelocity.X = 0;
  229. }
  230.  
  231. if (newVelocity.Y == 0f && _basisVelocity.Y * finallyVelocity.Y > 0)
  232. {
  233. _basisVelocity.Y = 0;
  234. }
  235. //是否撞到物体
  236. var collision = ActivityInstance.GetLastSlideCollision();
  237. if (collision != null) //执行反弹操作
  238. {
  239. var no = collision.GetNormal().Rotated(Mathf.Pi * 0.5f);
  240. newVelocity = (finallyVelocity - _basisVelocity).Reflect(no);
  241. var length = _forceList.Count;
  242. var v = newVelocity / (length / ActivityInstance.BounceStrength);
  243. for (var i = 0; i < _forceList.Count; i++)
  244. {
  245. _forceList[i].Velocity = v;
  246. }
  247. }
  248. else //没有撞到物体
  249. {
  250. //调整外力速率
  251. for (var i = 0; i < _forceList.Count; i++)
  252. {
  253. var force = _forceList[i];
  254. if (force.Enable)
  255. {
  256. var velocity = force.Velocity;
  257. force.Velocity = new Vector2(
  258. newVelocity.X == 0f && velocity.X * finallyVelocity.X > 0 ? 0 : velocity.X,
  259. newVelocity.Y == 0f && velocity.Y * finallyVelocity.Y > 0 ? 0 : velocity.Y
  260. );
  261.  
  262. //力速度衰减
  263. if (force.Resistance != 0 && (force.EnableResistanceInTheAir || !ActivityInstance.IsThrowing))
  264. {
  265. force.Velocity = force.Velocity.MoveToward(Vector2.Zero, force.Resistance * delta);
  266. }
  267.  
  268. //自动销毁
  269. if (force.AutoDestroy && force.Velocity == Vector2.Zero)
  270. {
  271. _forceList.RemoveAt(i--);
  272. }
  273. }
  274. }
  275. }
  276. }
  277. else
  278. {
  279. ActivityInstance.Velocity = Vector2.Zero;
  280. }
  281. }
  282.  
  283. public override void DebugDraw()
  284. {
  285. //绘制力大小和方向
  286. if (ActivityInstance is Bullet) //不绘制子弹的力
  287. {
  288. return;
  289. }
  290. var globalRotation = GlobalRotation;
  291. var flag = ActivityInstance.Scale.Y < 0;
  292. if (flag)
  293. {
  294. ActivityInstance.DrawLine(Vector2.Zero, (BasisVelocity * new Vector2(1, -1)).Rotated(-globalRotation),
  295. Colors.Yellow);
  296. }
  297. else
  298. {
  299. ActivityInstance.DrawLine(Vector2.Zero, BasisVelocity.Rotated(-globalRotation), Colors.Yellow);
  300. }
  301.  
  302. foreach (var force in _forceList)
  303. {
  304. if (flag)
  305. {
  306. ActivityInstance.DrawLine(Vector2.Zero, (force.Velocity * new Vector2(1, -1)).Rotated(globalRotation),
  307. Colors.YellowGreen);
  308. }
  309. else
  310. {
  311. ActivityInstance.DrawLine(Vector2.Zero, force.Velocity.Rotated(-globalRotation), Colors.YellowGreen);
  312. }
  313. }
  314. }
  315. }