Newer
Older
DungeonShooting / DungeonShooting_Godot / src / effect / ThrowNode.cs
@小李xl 小李xl on 12 Aug 2022 7 KB 修复与武器互动存在的bug
  1. using Godot;
  2.  
  3. /// <summary>
  4. /// 模拟抛出的物体, 使用时将对象挂载到该节点上即可
  5. /// </summary>
  6. public class ThrowNode : KinematicBody2D
  7. {
  8. /// <summary>
  9. /// 是否已经结束
  10. /// </summary>
  11. public bool IsOver { get; protected set; } = true;
  12. /// <summary>
  13. /// 物体大小
  14. /// </summary>
  15. public Vector2 Size { get; protected set; }
  16. /// <summary>
  17. /// 起始坐标
  18. /// </summary>
  19. public Vector2 StartPosition { get; protected set; }
  20. /// <summary>
  21. /// 移动方向, 0 - 360
  22. /// </summary>
  23. public float Direction { get; protected set; }
  24. /// <summary>
  25. /// x速度, 也就是水平速度
  26. /// </summary>
  27. public float XSpeed { get; protected set; }
  28. /// <summary>
  29. /// y轴速度, 也就是竖直速度
  30. /// </summary>
  31. public float YSpeed { get; protected set; }
  32. /// <summary>
  33. /// 初始x轴组队
  34. /// </summary>
  35. public float StartXSpeed { get; protected set; }
  36. /// <summary>
  37. /// 初始y轴速度
  38. /// </summary>
  39. public float StartYSpeed { get; protected set; }
  40. /// <summary>
  41. /// 旋转速度
  42. /// </summary>
  43. public float RotateSpeed { get; protected set; }
  44. /// <summary>
  45. /// 挂载的对象
  46. /// </summary>
  47. public Node2D Mount { get; protected set; }
  48. /// <summary>
  49. /// 碰撞组件
  50. /// </summary>
  51. public CollisionShape2D CollisionShape { get; protected set; }
  52. /// <summary>
  53. /// 绘制阴影的精灵
  54. /// </summary>
  55. public Sprite ShadowSprite { get; protected set; }
  56.  
  57. protected Sprite ShadowTarget { get; set; }
  58.  
  59. private bool inversionX = false;
  60.  
  61. public ThrowNode()
  62. {
  63. Name = "ThrowNode";
  64. }
  65.  
  66. public override void _Ready()
  67. {
  68. //只与墙壁碰撞
  69. CollisionMask = 1;
  70. CollisionLayer = 0;
  71. //创建碰撞器
  72. if (Size != Vector2.Zero)
  73. {
  74. CollisionShape = new CollisionShape2D();
  75. CollisionShape.Name = "Collision";
  76. var shape = new RectangleShape2D();
  77. shape.Extents = Size * 0.5f;
  78. CollisionShape.Shape = shape;
  79. AddChild(CollisionShape);
  80. }
  81. }
  82.  
  83. /// <summary>
  84. /// 初始化该抛物线对象的基础数据
  85. /// </summary>
  86. /// <param name="size">抛射的物体所占大小, 用于碰撞检测</param>
  87. /// <param name="start">起始点</param>
  88. /// <param name="startHeight">起始高度</param>
  89. /// <param name="direction">角度, 0 - 360</param>
  90. /// <param name="xSpeed">横轴速度</param>
  91. /// <param name="ySpeed">纵轴速度</param>
  92. /// <param name="rotate">旋转速度</param>
  93. /// <param name="mount">需要挂载的节点</param>
  94. /// <param name="texutre">抛射的节点显示的纹理, 用于渲染阴影用</param>
  95. public virtual void StartThrow(Vector2 size, Vector2 start, float startHeight, float direction, float xSpeed, float ySpeed, float rotate, Node2D mount)
  96. {
  97. if (CollisionShape != null)
  98. {
  99. CollisionShape.Disabled = false;
  100. }
  101.  
  102. IsOver = false;
  103. Size = size;
  104. GlobalPosition = StartPosition = start;
  105. Direction = direction;
  106. XSpeed = xSpeed;
  107. YSpeed = ySpeed;
  108. StartXSpeed = xSpeed;
  109. StartYSpeed = ySpeed;
  110. RotateSpeed = rotate;
  111.  
  112. if (mount != null)
  113. {
  114. Mount = mount;
  115. var mountParent = mount.GetParent();
  116. if (mountParent == null)
  117. {
  118. AddChild(mount);
  119. }
  120. else if (mountParent != this)
  121. {
  122. mountParent.RemoveChild(mount);
  123. AddChild(mount);
  124. }
  125. mount.Position = new Vector2(0, -startHeight);
  126. }
  127. var parent = GetParent();
  128. if (parent == null)
  129. {
  130. RoomManager.Current.SortRoot.AddChild(this);
  131. }
  132. else if (parent == RoomManager.Current.SortRoot)
  133. {
  134. parent.RemoveChild(this);
  135. RoomManager.Current.SortRoot.AddChild(this);
  136. }
  137. }
  138.  
  139. /// <summary>
  140. /// 初始化该抛物线对象的基础数据, 并且渲染阴影
  141. /// </summary>
  142. /// <param name="size">抛射的物体所占大小, 用于碰撞检测</param>
  143. /// <param name="start">起始点</param>
  144. /// <param name="startHeight">起始高度</param>
  145. /// <param name="direction">角度, 0 - 360</param>
  146. /// <param name="xSpeed">横轴速度</param>
  147. /// <param name="ySpeed">纵轴速度</param>
  148. /// <param name="rotate">旋转速度</param>
  149. /// <param name="mount">需要挂载的节点</param>
  150. /// <param name="shadowTarget">抛射的节点显示的纹理, 用于渲染阴影用</param>
  151. public virtual void StartThrow(Vector2 size, Vector2 start, float startHeight, float direction, float xSpeed, float ySpeed, float rotate, Node2D mount, Sprite shadowTarget)
  152. {
  153. StartThrow(size, start, startHeight, direction, xSpeed, ySpeed, rotate, mount);
  154. ShadowTarget = shadowTarget;
  155. if (shadowTarget != null)
  156. {
  157. if (ShadowSprite == null)
  158. {
  159. //阴影
  160. ShadowSprite = new Sprite();
  161. ShadowSprite.Name = "Shadow";
  162. ShadowSprite.ZIndex = -5;
  163. ShadowSprite.Material = ResourceManager.ShadowMaterial;
  164. AddChild(ShadowSprite);
  165. }
  166. inversionX = mount.Scale.y < 0 ? true : false;
  167. if (inversionX)
  168. {
  169. ShadowSprite.Scale = shadowTarget.Scale * new Vector2(1, -1);
  170. }
  171. else
  172. {
  173. ShadowSprite.Scale = shadowTarget.Scale;
  174. }
  175. ShadowSprite.Texture = shadowTarget.Texture;
  176. }
  177. else if (ShadowSprite != null)
  178. {
  179. ShadowSprite.Texture = null;
  180. }
  181. }
  182.  
  183. /// <summary>
  184. /// 停止投抛运动
  185. /// </summary>
  186. public Node2D StopThrow()
  187. {
  188. var mount = Mount;
  189. var parent = GetParent();
  190. if (parent != null && mount != null)
  191. {
  192. var gp = mount.GlobalPosition;
  193. var gr = mount.GlobalRotation;
  194. IsOver = true;
  195. Mount = null;
  196. RemoveChild(mount);
  197. parent.AddChild(mount);
  198. mount.GlobalPosition = gp;
  199. mount.GlobalRotation = gr;
  200. }
  201. QueueFree();
  202. return mount;
  203. }
  204.  
  205. /// <summary>
  206. /// 达到最高点时调用
  207. /// </summary>
  208. protected virtual void OnMaxHeight(float height)
  209. {
  210.  
  211. }
  212.  
  213. /// <summary>
  214. /// 结束的调用
  215. /// </summary>
  216. protected virtual void OnOver()
  217. {
  218. GetParent().RemoveChild(this);
  219. RoomManager.Current.ObjectRoot.AddChild(this);
  220. if (CollisionShape != null)
  221. {
  222. CollisionShape.Disabled = true;
  223. }
  224. }
  225.  
  226. public override void _Process(float delta)
  227. {
  228. if (!IsOver)
  229. {
  230. if (Mount == null)
  231. {
  232. QueueFree();
  233. return;
  234. }
  235. MoveAndSlide(new Vector2(XSpeed, 0).Rotated(Direction * Mathf.Pi / 180));
  236. Mount.Position = new Vector2(0, Mount.Position.y - YSpeed * delta);
  237. var rotate = Mount.GlobalRotationDegrees + RotateSpeed * delta;
  238. Mount.GlobalRotationDegrees = rotate;
  239. if (ShadowSprite != null)
  240. {
  241. ShadowSprite.GlobalRotationDegrees = rotate;
  242. // ShadowSprite.GlobalRotationDegrees = rotate + (inversionX ? 180 : 0);
  243. ShadowSprite.GlobalPosition = ShadowTarget.GlobalPosition + new Vector2(0, 1 - Mount.Position.y);
  244. }
  245. var ysp = YSpeed;
  246. YSpeed -= GameConfig.G * delta;
  247. //达到最高点
  248. if (ysp * YSpeed < 0)
  249. {
  250. OnMaxHeight(-Mount.Position.y);
  251. }
  252. //落地判断
  253. if (Mount.Position.y >= 0)
  254. {
  255. Mount.Position = new Vector2(0, 0);
  256. IsOver = true;
  257. OnOver();
  258. }
  259. }
  260. }
  261.  
  262. }