Newer
Older
DungeonShooting / DungeonShooting_Godot / src / framework / activity / ActivityInstance.cs
  1.  
  2. using System;
  3. using System.IO;
  4. using Godot;
  5.  
  6. /// <summary>
  7. /// 用于在预制场景中创建 ActivityObject
  8. /// </summary>
  9. [Tool]
  10. public partial class ActivityInstance : Node2D
  11. {
  12. /// <summary>
  13. /// 物体Id
  14. /// </summary>
  15. [Export]
  16. public string Id
  17. {
  18. get => _id;
  19. set
  20. {
  21. _id = value;
  22. _dirty = true;
  23. }
  24. }
  25.  
  26. /// <summary>
  27. /// 默认所在层级
  28. /// </summary>
  29. [Export]
  30. public RoomLayerEnum DefaultLayer { get; set; } = RoomLayerEnum.NormalLayer;
  31.  
  32. /// <summary>
  33. /// 是否显示阴影
  34. /// </summary>
  35. [Export]
  36. public bool ShowShadow
  37. {
  38. get => _showShadow;
  39. set
  40. {
  41. _showShadow = value;
  42. if (_activityObject != null)
  43. {
  44. if (value)
  45. {
  46. _activityObject.ShowShadowSprite();
  47. }
  48. else
  49. {
  50. _activityObject.HideShadowSprite();
  51. }
  52. }
  53. }
  54. }
  55.  
  56. /// <summary>
  57. /// 阴影偏移
  58. /// </summary>
  59. [Export]
  60. public Vector2 ShowOffset
  61. {
  62. get => _showOffset;
  63. set
  64. {
  65. _showOffset = value;
  66. if (_activityObject != null)
  67. {
  68. _activityObject.ShadowOffset = value;
  69. }
  70. }
  71. }
  72.  
  73. /// <summary>
  74. /// 初始海拔高度
  75. /// </summary>
  76. [Export]
  77. public float Altitude
  78. {
  79. get => _altitude;
  80. set
  81. {
  82. _altitude = value;
  83. if (_activityObject != null)
  84. {
  85. _activityObject.Altitude = value;
  86. _activityObject.Collision.Position = _collPos;
  87. _activityObject.UpdateShadowSprite((float)GetProcessDeltaTime());
  88. _activityObject.CalcThrowAnimatedPosition();
  89. }
  90. }
  91. }
  92.  
  93. /// <summary>
  94. /// 是否启用垂直运动模拟
  95. /// </summary>
  96. [Export]
  97. public bool VerticalMotion { get; private set; } = true;
  98.  
  99. /// <summary>
  100. /// 编辑器属性, 物体子碰撞器在编辑器中是否可见
  101. /// </summary>
  102. [Export]
  103. public bool CollisionVisible
  104. {
  105. get => _collisionVisible;
  106. set
  107. {
  108. _collisionVisible = value;
  109. OnChangeCollisionVisible();
  110. }
  111. }
  112.  
  113. private bool _dirty = false;
  114. private bool _collisionVisible = true;
  115. private string _prevId;
  116. private string _id;
  117. private ActivityObject _activityObject;
  118. private Sprite2D _errorSprite;
  119. private bool _showShadow = true;
  120. private Vector2 _showOffset = new Vector2(0, 2);
  121. private float _altitude;
  122.  
  123. private Vector2 _collPos;
  124. private bool _createFlag = false;
  125. private static string _jsonText;
  126.  
  127. public override void _Ready()
  128. {
  129. #if TOOLS
  130. if (!Engine.IsEditorHint())
  131. {
  132. #endif
  133. var world = World.Current;
  134. if (world != null && world.YSortLayer != null && world.NormalLayer != null)
  135. {
  136. DoCreateObject();
  137. }
  138. #if TOOLS
  139. }
  140. #endif
  141. }
  142.  
  143. public override void _Process(double delta)
  144. {
  145. #if TOOLS
  146. if (Engine.IsEditorHint())
  147. {
  148. if (_dirty || (_activityObject != null && _activityObject.GetParent() != this))
  149. {
  150. _dirty = false;
  151. if (_prevId != _id)
  152. {
  153. OnChangeActivityId(_id);
  154. }
  155. else if (string.IsNullOrEmpty(_id))
  156. {
  157. ShowErrorSprite();
  158. }
  159.  
  160. OnChangeCollisionVisible();
  161. }
  162.  
  163. if (_activityObject != null)
  164. {
  165. _activityObject.Collision.Position = _collPos;
  166. _activityObject.UpdateShadowSprite((float)delta);
  167. _activityObject.CalcThrowAnimatedPosition();
  168. }
  169. }
  170. else
  171. {
  172. #endif
  173. var world = World.Current;
  174. if (world != null && world.YSortLayer != null && world.NormalLayer != null)
  175. {
  176. DoCreateObject();
  177. }
  178. #if TOOLS
  179. }
  180. #endif
  181. }
  182.  
  183. public override void _EnterTree()
  184. {
  185. #if TOOLS
  186. if (Engine.IsEditorHint())
  187. {
  188. var children = GetChildren();
  189. foreach (var child in children)
  190. {
  191. child.QueueFree();
  192. }
  193. _dirty = true;
  194. _activityObject = null;
  195. _prevId = null;
  196. }
  197. #endif
  198. }
  199.  
  200. public override void _ExitTree()
  201. {
  202. #if TOOLS
  203. if (Engine.IsEditorHint() && _activityObject != null)
  204. {
  205. _activityObject.QueueFree();
  206. _activityObject = null;
  207. }
  208. #endif
  209. }
  210.  
  211. private void DoCreateObject()
  212. {
  213. if (_createFlag)
  214. {
  215. return;
  216. }
  217.  
  218. _createFlag = true;
  219. var activityObject = ActivityObject.Create(Id);
  220. activityObject.Position = GlobalPosition;
  221. activityObject.Scale = GlobalScale;
  222. activityObject.Rotation = GlobalRotation;
  223. activityObject.Name = Name;
  224. activityObject.Visible = Visible;
  225. activityObject.ShadowOffset = _showOffset;
  226. activityObject.Altitude = _altitude;
  227. activityObject.EnableVerticalMotion = VerticalMotion;
  228. activityObject.PutDown(DefaultLayer, _showShadow);
  229. QueueFree();
  230. }
  231.  
  232. private void OnChangeActivityId(string id)
  233. {
  234. _prevId = id;
  235.  
  236. if (_activityObject != null)
  237. {
  238. _activityObject.QueueFree();
  239. _activityObject = null;
  240. }
  241.  
  242. if (string.IsNullOrEmpty(id))
  243. {
  244. GD.Print("删除物体");
  245. ShowErrorSprite();
  246. return;
  247. }
  248.  
  249. if (_jsonText == null)
  250. {
  251. _jsonText = File.ReadAllText("resource/config/ActivityBase.json");
  252. }
  253. var str = $"\"Id\": \"{id}\",";
  254. var index = _jsonText.IndexOf(str, StringComparison.Ordinal);
  255. if (index > -1)
  256. {
  257. const string s = "\"Prefab\": \"";
  258. var startIndex = _jsonText.IndexOf(s, index, StringComparison.Ordinal);
  259. if (startIndex > -1)
  260. {
  261. var endIndex = _jsonText.IndexOf('"', startIndex + s.Length + 1);
  262. if (endIndex > -1)
  263. {
  264. var prefab = _jsonText.Substring(startIndex + s.Length, endIndex - (startIndex + s.Length));
  265. GD.Print("创建物体: " + id);
  266. var instance = ResourceManager.LoadAndInstantiate<ActivityObject>(prefab);
  267. _activityObject = instance;
  268. _collPos = instance.Collision.Position - instance.AnimatedSprite.Position - instance.AnimatedSprite.Offset;
  269. Debug.Log("_collPos: " + _collPos);
  270. instance.IsCustomShadowSprite = instance.ShadowSprite.Texture != null;
  271. instance.Altitude = _altitude;
  272. instance.ShadowOffset = _showOffset;
  273. if (_showShadow)
  274. {
  275. instance.ShowShadowSprite();
  276. }
  277. AddChild(instance);
  278. HideErrorSprite();
  279. return;
  280. }
  281. }
  282. }
  283. GD.PrintErr($"未找到Id为'{id}'的物体!");
  284. ShowErrorSprite();
  285. }
  286.  
  287. private void OnChangeCollisionVisible()
  288. {
  289. if (_activityObject != null)
  290. {
  291. Utils.EachNode(_activityObject, node =>
  292. {
  293. if (node is CollisionShape2D collisionShape2D)
  294. {
  295. collisionShape2D.Visible = _collisionVisible;
  296. }
  297. else if (node is CollisionPolygon2D collisionPolygon2D)
  298. {
  299. collisionPolygon2D.Visible = _collisionVisible;
  300. }
  301. });
  302. }
  303. }
  304.  
  305. private void ShowErrorSprite()
  306. {
  307. if (_errorSprite == null)
  308. {
  309. _errorSprite = new Sprite2D();
  310. _errorSprite.Texture = ResourceManager.LoadTexture2D(ResourcePath.resource_sprite_ui_commonIcon_Error_mini_png);
  311. AddChild(_errorSprite);
  312. }
  313. }
  314.  
  315. private void HideErrorSprite()
  316. {
  317. if (_errorSprite != null)
  318. {
  319. _errorSprite.QueueFree();
  320. _errorSprite = null;
  321. }
  322. }
  323. }