Newer
Older
DungeonShooting / DungeonShooting_Godot / src / game / role / Role.cs
  1. using System.Collections.Generic;
  2. using Godot;
  3.  
  4. /// <summary>
  5. /// 角色基类
  6. /// </summary>
  7. public abstract class Role : ActivityObject
  8. {
  9. /// <summary>
  10. /// 重写的纹理
  11. /// </summary>
  12. public Texture Texture { get; protected set; }
  13.  
  14. /// <summary>
  15. /// 移动速度
  16. /// </summary>
  17. public float MoveSpeed = 150f;
  18.  
  19. /// <summary>
  20. /// 所属阵营
  21. /// </summary>
  22. public CampEnum Camp;
  23.  
  24. /// <summary>
  25. /// 携带的道具包裹
  26. /// </summary>
  27. public List<object> PropsPack { get; } = new List<object>();
  28.  
  29. /// <summary>
  30. /// 角色携带的枪套
  31. /// </summary>
  32. public Holster Holster { get; private set; }
  33.  
  34. /// <summary>
  35. /// 武器挂载点
  36. /// </summary>
  37. public Position2D MountPoint { get; private set; }
  38. /// <summary>
  39. /// 背后武器的挂载点
  40. /// </summary>
  41. public Position2D BackMountPoint { get; private set; }
  42.  
  43. /// <summary>
  44. /// 脸的朝向
  45. /// </summary>
  46. public FaceDirection Face { get => _face; set => SetFace(value); }
  47. private FaceDirection _face;
  48.  
  49. /// <summary>
  50. /// 血量
  51. /// </summary>
  52. public int Hp
  53. {
  54. get => _hp;
  55. protected set
  56. {
  57. int temp = _hp;
  58. _hp = value;
  59. if (temp != _hp) OnChangeHp(_hp);
  60. }
  61. }
  62. private int _hp = 0;
  63.  
  64. /// <summary>
  65. /// 最大血量
  66. /// </summary>
  67. public int MaxHp
  68. {
  69. get => _maxHp;
  70. protected set
  71. {
  72. int temp = _maxHp;
  73. _maxHp = value;
  74. if (temp != _maxHp) OnChangeMaxHp(_maxHp);
  75. }
  76. }
  77. private int _maxHp = 0;
  78. //初始缩放
  79. private Vector2 StartScele;
  80. //所有角色碰撞的道具
  81. private readonly List<ActivityObject> InteractiveItemList = new List<ActivityObject>();
  82.  
  83. private CheckInteractiveResult TempResultData;
  84.  
  85. /// <summary>
  86. /// 可以互动的道具
  87. /// </summary>
  88. protected ActivityObject InteractiveItem { get; private set; }
  89.  
  90. /// <summary>
  91. /// 当血量改变时调用
  92. /// </summary>
  93. protected abstract void OnChangeHp(int hp);
  94. /// <summary>
  95. /// 当最大血量改变时调用
  96. /// </summary>
  97. protected abstract void OnChangeMaxHp(int maxHp);
  98.  
  99. /// <summary>
  100. /// 当可互动的物体改变时调用, result 参数为 null 表示变为不可互动
  101. /// </summary>
  102. /// <param name="result">检测是否可互动时的返回值</param>
  103. protected abstract void ChangeInteractiveItem(CheckInteractiveResult result);
  104.  
  105. public override CheckInteractiveResult CheckInteractive(ActivityObject master)
  106. {
  107. return new CheckInteractiveResult(this);
  108. }
  109.  
  110. public override void Interactive(ActivityObject master)
  111. {
  112. }
  113. public Role() : base("res://prefab/role/Role.tscn")
  114. {
  115. }
  116. public override void _Ready()
  117. {
  118. base._Ready();
  119. StartScele = Scale;
  120. MountPoint = GetNode<Position2D>("MountPoint");
  121. BackMountPoint = GetNode<Position2D>("BackMountPoint");
  122. if (Texture != null)
  123. {
  124. // 更改纹理
  125. ChangeFrameTexture(AnimatorNames.Idle, AnimatedSprite, Texture);
  126. ChangeFrameTexture(AnimatorNames.Run, AnimatedSprite, Texture);
  127. ChangeFrameTexture(AnimatorNames.ReverseRun, AnimatedSprite, Texture);
  128. }
  129.  
  130. Holster = new Holster(this);
  131. Face = FaceDirection.Right;
  132. }
  133.  
  134. public override void _Process(float delta)
  135. {
  136. base._Process(delta);
  137. //检查可互动的道具
  138. bool findFlag = false;
  139. for (int i = 0; i < InteractiveItemList.Count; i++)
  140. {
  141. var item = InteractiveItemList[i];
  142. if (item == null)
  143. {
  144. InteractiveItemList.RemoveAt(i--);
  145. }
  146. else
  147. {
  148. //找到可互动的道具了
  149. if (!findFlag)
  150. {
  151. var result = item.CheckInteractive(this);
  152. if (result.CanInteractive) //可以互动
  153. {
  154. findFlag = true;
  155. if (InteractiveItem != item) //更改互动物体
  156. {
  157. InteractiveItem = item;
  158. ChangeInteractiveItem(result);
  159. }
  160. else if (result.ShowIcon != TempResultData.ShowIcon) //切换状态
  161. {
  162. ChangeInteractiveItem(result);
  163. }
  164. }
  165. TempResultData = result;
  166. }
  167. }
  168. }
  169. //没有可互动的道具
  170. if (!findFlag && InteractiveItem != null)
  171. {
  172. InteractiveItem = null;
  173. ChangeInteractiveItem(null);
  174. }
  175. }
  176.  
  177.  
  178. /// <summary>
  179. /// 拾起一个武器, 并且切换到这个武器
  180. /// </summary>
  181. /// <param name="weapon">武器对象</param>
  182. public void PickUpWeapon(Weapon weapon)
  183. {
  184. if (Holster.PickupWeapon(weapon) != -1)
  185. {
  186. //从可互动队列中移除
  187. InteractiveItemList.Remove(weapon);
  188. }
  189. }
  190.  
  191. /// <summary>
  192. /// 切换到下一个武器
  193. /// </summary>
  194. public void TriggerExchangeNext()
  195. {
  196. Holster.ExchangeNext();
  197. }
  198.  
  199. /// <summary>
  200. /// 切换到上一个武器
  201. /// </summary>
  202. public void ExchangePrev()
  203. {
  204. Holster.ExchangePrev();
  205. }
  206.  
  207. /// <summary>
  208. /// 扔掉当前使用的武器, 切换到上一个武器
  209. /// </summary>
  210. public void TriggerThrowWeapon()
  211. {
  212. var weapon = Holster.RmoveWeapon(Holster.ActiveIndex);
  213. //播放抛出效果
  214. if (weapon != null)
  215. {
  216. weapon.StartThrowWeapon(this);
  217. }
  218. }
  219.  
  220. /// <summary>
  221. /// 返回是否存在可互动的物体
  222. /// </summary>
  223. public bool HasInteractive()
  224. {
  225. return InteractiveItem != null;
  226. }
  227.  
  228. /// <summary>
  229. /// 触发与碰撞的物体互动, 并返回与其互动的物体
  230. /// </summary>
  231. public ActivityObject TriggerInteractive()
  232. {
  233. if (HasInteractive())
  234. {
  235. var item = InteractiveItem;
  236. item.Interactive(this);
  237. return item;
  238. }
  239. return null;
  240. }
  241.  
  242. /// <summary>
  243. /// 触发换弹
  244. /// </summary>
  245. public void TriggerReload()
  246. {
  247. if (Holster.ActiveWeapon != null)
  248. {
  249. Holster.ActiveWeapon._Reload();
  250. }
  251. }
  252.  
  253. /// <summary>
  254. /// 触发攻击
  255. /// </summary>
  256. public void TriggerAttack()
  257. {
  258. if (Holster.ActiveWeapon != null)
  259. {
  260. Holster.ActiveWeapon.Trigger();
  261. }
  262. }
  263.  
  264. /// <summary>
  265. /// 设置脸的朝向
  266. /// </summary>
  267. private void SetFace(FaceDirection face)
  268. {
  269. if (_face != face)
  270. {
  271. _face = face;
  272. if (face == FaceDirection.Right)
  273. {
  274. RotationDegrees = 0;
  275. Scale = StartScele;
  276. }
  277. else
  278. {
  279. RotationDegrees = 180;
  280. Scale = new Vector2(StartScele.x, -StartScele.y);
  281. }
  282. }
  283. }
  284.  
  285. /// <summary>
  286. /// 更改指定动画的纹理
  287. /// </summary>
  288. private void ChangeFrameTexture(string anim, AnimatedSprite animatedSprite, Texture texture)
  289. {
  290. SpriteFrames spriteFrames = animatedSprite.Frames;
  291. if (spriteFrames != null)
  292. {
  293. int count = spriteFrames.GetFrameCount(anim);
  294. for (int i = 0; i < count; i++)
  295. {
  296. AtlasTexture temp = spriteFrames.GetFrame(anim, i) as AtlasTexture;
  297. temp.Atlas = Texture;
  298. }
  299. }
  300. }
  301.  
  302. /// <summary>
  303. /// 连接信号: InteractiveArea.area_entered
  304. /// 与物体碰撞
  305. /// </summary>
  306. private void _OnPropsEnter(Area2D other)
  307. {
  308. ActivityObject propObject = other.AsActivityObject();
  309. if (propObject != null) //道具类型
  310. {
  311. if (!InteractiveItemList.Contains(propObject))
  312. {
  313. InteractiveItemList.Add(propObject);
  314. }
  315. }
  316. }
  317.  
  318. /// <summary>
  319. /// 连接信号: InteractiveArea.area_exited
  320. /// 物体离开碰撞区域
  321. /// </summary>
  322. private void _OnPropsExit(Area2D other)
  323. {
  324. ActivityObject propObject = other.AsActivityObject();
  325. if (propObject != null) //道具类型
  326. {
  327. if (InteractiveItemList.Contains(propObject))
  328. {
  329. InteractiveItemList.Remove(propObject);
  330. }
  331. if (InteractiveItem == propObject)
  332. {
  333. InteractiveItem = null;
  334. ChangeInteractiveItem(null);
  335. }
  336. }
  337. }
  338. }