Newer
Older
DungeonShooting / DungeonShooting_Godot / src / game / item / ThrowNode.cs
@小李xl 小李xl on 18 Oct 2022 7 KB 重构throwNode, 目前还有点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,
  152. float ySpeed, float rotate, Node2D mount, Sprite shadowTarget)
  153. {
  154. StartThrow(size, start, startHeight, direction, xSpeed, ySpeed, rotate, mount);
  155. ShadowTarget = shadowTarget;
  156. if (shadowTarget != null)
  157. {
  158. if (ShadowSprite == null)
  159. {
  160. //阴影
  161. ShadowSprite = new Sprite();
  162. ShadowSprite.Name = "Shadow";
  163. ShadowSprite.ZIndex = -5;
  164. ShadowSprite.Material = ResourceManager.ShadowMaterial;
  165. AddChild(ShadowSprite);
  166. }
  167.  
  168. inversionX = mount.Scale.y < 0 ? true : false;
  169. if (inversionX)
  170. {
  171. ShadowSprite.Scale = shadowTarget.Scale * new Vector2(1, -1);
  172. }
  173. else
  174. {
  175. ShadowSprite.Scale = shadowTarget.Scale;
  176. }
  177.  
  178. ShadowSprite.Texture = shadowTarget.Texture;
  179. }
  180. else if (ShadowSprite != null)
  181. {
  182. ShadowSprite.Texture = null;
  183. }
  184. }
  185.  
  186. /// <summary>
  187. /// 停止投抛运动
  188. /// </summary>
  189. public Node2D StopThrow()
  190. {
  191. var mount = Mount;
  192. var parent = GetParent();
  193. if (parent != null && mount != null)
  194. {
  195. var gp = mount.GlobalPosition;
  196. var gr = mount.GlobalRotation;
  197. IsOver = true;
  198. Mount = null;
  199. RemoveChild(mount);
  200. parent.AddChild(mount);
  201. mount.GlobalPosition = gp;
  202. mount.GlobalRotation = gr;
  203. }
  204. QueueFree();
  205. return mount;
  206. }
  207.  
  208. /// <summary>
  209. /// 达到最高点时调用
  210. /// </summary>
  211. protected virtual void OnMaxHeight(float height)
  212. {
  213.  
  214. }
  215.  
  216. /// <summary>
  217. /// 结束的调用
  218. /// </summary>
  219. protected virtual void OnOver()
  220. {
  221. GetParent().RemoveChild(this);
  222. RoomManager.Current.ObjectRoot.AddChild(this);
  223. if (CollisionShape != null)
  224. {
  225. CollisionShape.Disabled = true;
  226. }
  227. }
  228.  
  229. public override void _Process(float delta)
  230. {
  231. if (!IsOver)
  232. {
  233. if (Mount == null)
  234. {
  235. QueueFree();
  236. return;
  237. }
  238. MoveAndSlide(new Vector2(XSpeed, 0).Rotated(Direction * Mathf.Pi / 180));
  239. Mount.Position = new Vector2(0, Mount.Position.y - YSpeed * delta);
  240. var rotate = Mount.GlobalRotationDegrees + RotateSpeed * delta;
  241. Mount.GlobalRotationDegrees = rotate;
  242. if (ShadowSprite != null)
  243. {
  244. ShadowSprite.GlobalRotationDegrees = rotate;
  245. // ShadowSprite.GlobalRotationDegrees = rotate + (inversionX ? 180 : 0);
  246. ShadowSprite.GlobalPosition = ShadowTarget.GlobalPosition + new Vector2(0, 1 - Mount.Position.y);
  247. }
  248. var ysp = YSpeed;
  249. YSpeed -= GameConfig.G * delta;
  250. //达到最高点
  251. if (ysp * YSpeed < 0)
  252. {
  253. OnMaxHeight(-Mount.Position.y);
  254. }
  255. //落地判断
  256. if (Mount.Position.y >= 0)
  257. {
  258. Mount.Position = new Vector2(0, 0);
  259. IsOver = true;
  260. OnOver();
  261. }
  262. }
  263. }
  264.  
  265. }