Newer
Older
DungeonShooting / DungeonShooting_Godot / src / framework / activity / ActivityObject.cs
@小李xl 小李xl on 10 May 2023 36 KB 添加敌人死亡特效
  1.  
  2. using System;
  3. using System.Collections;
  4. using System.Collections.Generic;
  5. using Godot;
  6.  
  7. /// <summary>
  8. /// 房间内活动物体基类, 所有物体都必须继承该类,
  9. /// ActivityObject 使用的时候代码和场景分离的设计模式, 所以创建时必须指定模板场景路径, 这样做的好处是一个模板场景可以用在多个代码类上, 同样一个代码类也可以指定不同的目模板场景,
  10. /// ActivityObject 子类实例化请不要直接使用 new, 而用该在类上标上 [RegisterActivity(id, prefabPath)],
  11. /// ActivityObject 类会自动扫描并注册物体, 然后使用而是使用 ActivityObject.Create(id) 来创建实例
  12. /// </summary>
  13. public abstract partial class ActivityObject : CharacterBody2D, IDestroy
  14. {
  15. /// <summary>
  16. /// 是否是调试模式
  17. /// </summary>
  18. public static bool IsDebug { get; set; }
  19.  
  20. /// <summary>
  21. /// 当前物体类型id, 用于区分是否是同一种物体, 如果不是通过 ActivityObject.Create() 函数创建出来的对象那么 ItemId 为 null
  22. /// </summary>
  23. public string ItemId { get; private set; }
  24.  
  25. /// <summary>
  26. /// 当前物体显示的精灵图像, 节点名称必须叫 "AnimatedSprite2D", 类型为 AnimatedSprite2D
  27. /// </summary>
  28. public AnimatedSprite2D AnimatedSprite { get; private set; }
  29.  
  30. /// <summary>
  31. /// 当前物体显示的阴影图像, 节点名称必须叫 "ShadowSprite", 类型为 Sprite2D
  32. /// </summary>
  33. public Sprite2D ShadowSprite { get; private set; }
  34.  
  35. /// <summary>
  36. /// 当前物体碰撞器节点, 节点名称必须叫 "Collision", 类型为 CollisionShape2D
  37. /// </summary>
  38. public CollisionShape2D Collision { get; private set; }
  39.  
  40. /// <summary>
  41. /// 是否调用过 Destroy() 函数
  42. /// </summary>
  43. public bool IsDestroyed { get; private set; }
  44. /// <summary>
  45. /// 阴影偏移
  46. /// </summary>
  47. public Vector2 ShadowOffset { get; protected set; } = new Vector2(0, 2);
  48. /// <summary>
  49. /// 移动控制器
  50. /// </summary>
  51. public MoveController MoveController { get; private set; }
  52.  
  53. /// <summary>
  54. /// 物体移动基础速率
  55. /// </summary>
  56. public Vector2 BasisVelocity
  57. {
  58. get => MoveController.BasisVelocity;
  59. set => MoveController.BasisVelocity = value;
  60. }
  61.  
  62. /// <summary>
  63. /// 当前物体归属的区域, 如果为 null 代表不属于任何一个区域
  64. /// </summary>
  65. public AffiliationArea Affiliation
  66. {
  67. get => _affiliationArea;
  68. set
  69. {
  70. if (value != _affiliationArea)
  71. {
  72. _affiliationArea = value;
  73. OnAffiliationChange();
  74. }
  75. }
  76. }
  77.  
  78. /// <summary>
  79. /// 是否正在投抛过程中
  80. /// </summary>
  81. public bool IsThrowing => _fallData != null && !_isFallOver;
  82.  
  83. /// <summary>
  84. /// 当前物体的海拔高度, 如果大于0, 则会做自由落体运动, 也就是执行投抛代码
  85. /// </summary>
  86. public float Altitude
  87. {
  88. get => _altitude;
  89. set
  90. {
  91. _altitude = value;
  92. _hasResilienceVerticalSpeed = false;
  93. }
  94. }
  95.  
  96. private float _altitude = 0;
  97.  
  98. /// <summary>
  99. /// 物体纵轴移动速度, 如果设置大于0, 就可以营造向上投抛物体的效果, 该值会随着重力加速度衰减
  100. /// </summary>
  101. public float VerticalSpeed
  102. {
  103. get => _verticalSpeed;
  104. set
  105. {
  106. _verticalSpeed = value;
  107. _hasResilienceVerticalSpeed = false;
  108. }
  109. }
  110.  
  111. private float _verticalSpeed;
  112. /// <summary>
  113. /// 物体投抛时旋转速度, 角度制
  114. /// </summary>
  115. public float ThrowRotationDegreesSpeed { get; set; }
  116.  
  117. /// <summary>
  118. /// 落地之后是否回弹
  119. /// </summary>
  120. public bool Bounce { get; set; } = true;
  121.  
  122. /// <summary>
  123. /// 物体下坠回弹的强度
  124. /// </summary>
  125. public float BounceStrength { get; set; } = 0.5f;
  126.  
  127. /// <summary>
  128. /// 物体下坠回弹后的运动速度衰减量
  129. /// </summary>
  130. public float BounceSpeed { get; set; } = 0.75f;
  131. /// <summary>
  132. /// 投抛状态下物体碰撞器大小, 如果 (x, y) 都小于 0, 则默认使用 AnimatedSprite 的默认动画第一帧的大小
  133. /// </summary>
  134. public Vector2 ThrowCollisionSize { get; set; } = new Vector2(-1, -1);
  135.  
  136. /// <summary>
  137. /// 是否启用垂直方向上的运动模拟, 默认开启, 如果禁用, 那么下落和投抛效果, 同样 Throw() 函数也将失效
  138. /// </summary>
  139. public bool EnableVerticalMotion { get; set; } = true;
  140.  
  141. /// <summary>
  142. /// 是否启用物体更新行为, 默认 true, 如果禁用, 则会停止当前物体的 Process(), PhysicsProcess() 调用, 并且禁用 Collision 节点, 禁用后所有组件也同样被禁用行为
  143. /// </summary>
  144. public bool EnableBehavior
  145. {
  146. get => _enableBehavior;
  147. set
  148. {
  149. if (value != _enableBehavior)
  150. {
  151. _enableBehavior = value;
  152. SetProcess(value);
  153. SetPhysicsProcess(value);
  154. if (value)
  155. {
  156. Collision.Disabled = _enableBehaviorCollisionDisabledFlag;
  157. }
  158. else
  159. {
  160. _enableBehaviorCollisionDisabledFlag = Collision.Disabled;
  161. Collision.Disabled = true;
  162. }
  163. }
  164. }
  165. }
  166.  
  167. /// <summary>
  168. /// 是否启用自定义行为, 默认 true, 如果禁用, 则会停止调用子类重写的 Process(), PhysicsProcess() 函数, 并且当前物体除 MoveController 以外的组件 Process(), PhysicsProcess() 也会停止调用
  169. /// </summary>
  170. public bool EnableCustomBehavior { get; set; } = true;
  171. // --------------------------------------------------------------------------------
  172.  
  173. //组件集合
  174. private List<KeyValuePair<Type, Component>> _components = new List<KeyValuePair<Type, Component>>();
  175. //是否初始化阴影
  176. private bool _initShadow;
  177. //上一帧动画名称
  178. private string _prevAnimation;
  179. //上一帧动画
  180. private int _prevAnimationFrame;
  181.  
  182. //播放 Hit 动画
  183. private bool _playHit;
  184. private float _playHitSchedule;
  185.  
  186. //混色shader材质
  187. private ShaderMaterial _blendShaderMaterial;
  188. //存储投抛该物体时所产生的数据
  189. private ActivityFallData _fallData;
  190. //所在层级
  191. private RoomLayerEnum _currLayer;
  192. //标记字典
  193. private Dictionary<string, object> _signMap;
  194. //开启的协程
  195. private List<CoroutineData> _coroutineList;
  196. //模板实例
  197. private ActivityObjectTemplate _templateInstance;
  198. //物体所在区域
  199. private AffiliationArea _affiliationArea;
  200.  
  201. //是否是第一次下坠
  202. private bool _firstFall = true;
  203. //下坠是否已经结束
  204. private bool _isFallOver = true;
  205.  
  206. //下坠状态碰撞器形状
  207. private RectangleShape2D _throwRectangleShape;
  208.  
  209. //投抛移动速率
  210. private ExternalForce _throwForce;
  211. //落到地上回弹的速度
  212. private float _resilienceVerticalSpeed = 0;
  213. private bool _hasResilienceVerticalSpeed = false;
  214.  
  215. //是否启用物体行为
  216. private bool _enableBehavior = true;
  217. private bool _enableBehaviorCollisionDisabledFlag;
  218.  
  219. // --------------------------------------------------------------------------------
  220. //实例索引
  221. private static long _instanceIndex = 0;
  222.  
  223. //初始化节点
  224. private void _InitNode(string itemId, string scenePath)
  225. {
  226. //加载预制体
  227. var tempPrefab = ResourceManager.Load<PackedScene>(scenePath);
  228. if (tempPrefab == null)
  229. {
  230. throw new Exception("创建 ActivityObject 没有找到指定挂载的预制体: " + scenePath);
  231. }
  232.  
  233. ItemId = itemId;
  234. Name = GetType().Name + (_instanceIndex++);
  235. _templateInstance = tempPrefab.Instantiate<ActivityObjectTemplate>();
  236. //移动子节点
  237. var count = _templateInstance.GetChildCount();
  238. for (int i = 0; i < count; i++)
  239. {
  240. var body = _templateInstance.GetChild(0);
  241. _templateInstance.RemoveChild(body);
  242. AddChild(body);
  243. body.Owner = this;
  244. switch (body.Name)
  245. {
  246. case "AnimatedSprite":
  247. AnimatedSprite = (AnimatedSprite2D)body;
  248. _blendShaderMaterial = AnimatedSprite.Material as ShaderMaterial;
  249. break;
  250. case "ShadowSprite":
  251. ShadowSprite = (Sprite2D)body;
  252. ShadowSprite.Visible = false;
  253. break;
  254. case "Collision":
  255. Collision = (CollisionShape2D)body;
  256. break;
  257. }
  258. }
  259. ZIndex = _templateInstance.z_index;
  260. CollisionLayer = _templateInstance.collision_layer;
  261. CollisionMask = _templateInstance.collision_mask;
  262. Scale = _templateInstance.scale;
  263. Visible = _templateInstance.visible;
  264.  
  265. MotionMode = MotionModeEnum.Floating;
  266.  
  267. MoveController = AddComponent<MoveController>();
  268. //临时处理, 4.0 有bug, 不能销毁模板实例, 不然关闭游戏会报错!!!
  269. //_templateInstance.CallDeferred(Node.MethodName.QueueFree);
  270.  
  271. OnInit();
  272. }
  273.  
  274. /// <summary>
  275. /// 子类重写的 _Ready() 可能会比 _InitNode() 函数调用晚, 所以禁止子类重写, 如需要 _Ready() 类似的功能需重写 OnInit()
  276. /// </summary>
  277. public sealed override void _Ready()
  278. {
  279. }
  280.  
  281. /// <summary>
  282. /// 显示阴影
  283. /// </summary>
  284. public void ShowShadowSprite()
  285. {
  286. if (!_initShadow)
  287. {
  288. _initShadow = true;
  289. ShadowSprite.Material = ResourceManager.BlendMaterial;
  290. }
  291.  
  292. var anim = AnimatedSprite.Animation;
  293. var frame = AnimatedSprite.Frame;
  294. if (_prevAnimation != anim || _prevAnimationFrame != frame)
  295. {
  296. var frames = AnimatedSprite.SpriteFrames;
  297. if (frames.HasAnimation(anim))
  298. {
  299. //切换阴影动画
  300. ShadowSprite.Texture = frames.GetFrameTexture(anim, frame);
  301. }
  302. }
  303.  
  304. _prevAnimation = anim;
  305. _prevAnimationFrame = frame;
  306.  
  307. CalcShadow();
  308. ShadowSprite.Visible = true;
  309. }
  310.  
  311. /// <summary>
  312. /// 隐藏阴影
  313. /// </summary>
  314. public void HideShadowSprite()
  315. {
  316. ShadowSprite.Visible = false;
  317. }
  318.  
  319. /// <summary>
  320. /// 设置默认序列帧动画的第一帧
  321. /// </summary>
  322. public void SetDefaultTexture(Texture2D texture)
  323. {
  324. if (AnimatedSprite.SpriteFrames == null)
  325. {
  326. SpriteFrames spriteFrames = new SpriteFrames();
  327. AnimatedSprite.SpriteFrames = spriteFrames;
  328. spriteFrames.AddFrame("default", texture);
  329. }
  330. else
  331. {
  332. SpriteFrames spriteFrames = AnimatedSprite.SpriteFrames;
  333. spriteFrames.SetFrame("default", 0, texture);
  334. }
  335. AnimatedSprite.Play("default");
  336. }
  337.  
  338. /// <summary>
  339. /// 获取默认序列帧动画的第一帧
  340. /// </summary>
  341. public Texture2D GetDefaultTexture()
  342. {
  343. return AnimatedSprite.SpriteFrames.GetFrameTexture("default", 0);
  344. }
  345. /// <summary>
  346. /// 获取当前序列帧动画的 Texture2D
  347. /// </summary>
  348. public Texture2D GetCurrentTexture()
  349. {
  350. return AnimatedSprite.SpriteFrames.GetFrameTexture(AnimatedSprite.Name, AnimatedSprite.Frame);
  351. }
  352.  
  353. /// <summary>
  354. /// 物体初始化时调用
  355. /// </summary>
  356. public virtual void OnInit()
  357. {
  358. }
  359. /// <summary>
  360. /// 返回是否能与其他ActivityObject互动
  361. /// </summary>
  362. /// <param name="master">触发者</param>
  363. public virtual CheckInteractiveResult CheckInteractive(ActivityObject master)
  364. {
  365. return new CheckInteractiveResult(this);
  366. }
  367.  
  368. /// <summary>
  369. /// 与其它ActivityObject互动时调用, 如果要检测是否能互动请 CheckInteractive() 函数, 如果直接调用该函数那么属于强制互动行为, 例如子弹碰到物体
  370. /// </summary>
  371. /// <param name="master">触发者</param>
  372. public virtual void Interactive(ActivityObject master)
  373. {
  374. }
  375.  
  376. /// <summary>
  377. /// 开始投抛该物体时调用
  378. /// </summary>
  379. protected virtual void OnThrowStart()
  380. {
  381. }
  382. /// <summary>
  383. /// 投抛该物体达到最高点时调用
  384. /// </summary>
  385. protected virtual void OnThrowMaxHeight(float height)
  386. {
  387. }
  388.  
  389. /// <summary>
  390. /// 投抛状态下第一次接触地面时调用, 之后的回弹落地将不会调用该函数
  391. /// </summary>
  392. protected virtual void OnFirstFallToGround()
  393. {
  394. }
  395.  
  396. /// <summary>
  397. /// 投抛状态下每次接触地面时调用
  398. /// </summary>
  399. protected virtual void OnFallToGround()
  400. {
  401. }
  402.  
  403. /// <summary>
  404. /// 投抛结束时调用
  405. /// </summary>
  406. protected virtual void OnThrowOver()
  407. {
  408. }
  409.  
  410. /// <summary>
  411. /// 当前物体销毁时调用, 销毁物体请调用 Destroy() 函数
  412. /// </summary>
  413. protected virtual void OnDestroy()
  414. {
  415. }
  416.  
  417. /// <summary>
  418. /// 每帧调用一次, 物体的 Process() 会在组件的 Process() 之前调用
  419. /// </summary>
  420. protected virtual void Process(float delta)
  421. {
  422. }
  423. /// <summary>
  424. /// 每帧调用一次, ProcessOver() 会在组件的 Process() 之后调用
  425. /// </summary>
  426. protected virtual void ProcessOver(float delta)
  427. {
  428. }
  429. /// <summary>
  430. /// 每物理帧调用一次, 物体的 PhysicsProcess() 会在组件的 PhysicsProcess() 之前调用
  431. /// </summary>
  432. protected virtual void PhysicsProcess(float delta)
  433. {
  434. }
  435. /// <summary>
  436. /// 每物理帧调用一次, PhysicsProcessOver() 会在组件的 PhysicsProcess() 之后调用
  437. /// </summary>
  438. protected virtual void PhysicsProcessOver(float delta)
  439. {
  440. }
  441. /// <summary>
  442. /// 如果开启 debug, 则每帧调用该函数, 可用于绘制文字线段等
  443. /// </summary>
  444. protected virtual void DebugDraw()
  445. {
  446. }
  447.  
  448. /// <summary>
  449. /// 归属区域发生改变
  450. /// </summary>
  451. protected virtual void OnAffiliationChange()
  452. {
  453. }
  454.  
  455. /// <summary>
  456. /// 返回当物体 CollisionLayer 是否能与 mask 层碰撞
  457. /// </summary>
  458. public bool CollisionWithMask(uint mask)
  459. {
  460. return (CollisionLayer & mask) != 0;
  461. }
  462. /// <summary>
  463. /// 拾起一个 node 节点, 也就是将其从场景树中移除
  464. /// </summary>
  465. public void Pickup()
  466. {
  467. var parent = GetParent();
  468. if (parent != null)
  469. {
  470. if (IsThrowing)
  471. {
  472. StopThrow();
  473. }
  474.  
  475. parent.RemoveChild(this);
  476. }
  477. }
  478.  
  479. /// <summary>
  480. /// 将一个节点扔到地上
  481. /// <param name="layer">放入的层</param>
  482. /// <param name="showShadow">是否显示阴影</param>
  483. /// </summary>
  484. public virtual void PutDown(RoomLayerEnum layer, bool showShadow = true)
  485. {
  486. _currLayer = layer;
  487. var parent = GetParent();
  488. var root = GameApplication.Instance.RoomManager.GetRoomLayer(layer);
  489. if (parent != root)
  490. {
  491. if (parent != null)
  492. {
  493. parent.RemoveChild(this);
  494. }
  495.  
  496. this.AddToActivityRoot(layer);
  497. }
  498.  
  499. if (showShadow)
  500. {
  501. if (IsInsideTree())
  502. {
  503. ShowShadowSprite();
  504. }
  505. else
  506. {
  507. //注意需要延时调用
  508. CallDeferred(nameof(ShowShadowSprite));
  509. }
  510. }
  511. else
  512. {
  513. ShadowSprite.Visible = false;
  514. }
  515. }
  516.  
  517. /// <summary>
  518. /// 将一个节点扔到地上
  519. /// </summary>
  520. /// <param name="position">放置的位置</param>
  521. /// <param name="layer">放入的层</param>
  522. /// <param name="showShadow">是否显示阴影</param>
  523. public void PutDown(Vector2 position, RoomLayerEnum layer, bool showShadow = true)
  524. {
  525. PutDown(layer);
  526. Position = position;
  527. }
  528.  
  529. /// <summary>
  530. /// 将该节点投抛出去
  531. /// </summary>
  532. /// <param name="altitude">初始高度</param>
  533. /// <param name="verticalSpeed">纵轴速度</param>
  534. /// <param name="velocity">移动速率</param>
  535. /// <param name="rotate">旋转速度</param>
  536. public void Throw(float altitude, float verticalSpeed, Vector2 velocity, float rotate)
  537. {
  538. var parent = GetParent();
  539. if (parent == null)
  540. {
  541. GameApplication.Instance.RoomManager.YSortLayer.AddChild(this);
  542. }
  543. else if (parent != GameApplication.Instance.RoomManager.YSortLayer)
  544. {
  545. parent.RemoveChild(this);
  546. GameApplication.Instance.RoomManager.YSortLayer.AddChild(this);
  547. }
  548. Altitude = altitude;
  549. VerticalSpeed = verticalSpeed;
  550. ThrowRotationDegreesSpeed = rotate;
  551. if (_throwForce != null)
  552. {
  553. MoveController.RemoveForce(_throwForce);
  554. }
  555.  
  556. _throwForce = new ExternalForce("throw");
  557. _throwForce.Velocity = velocity;
  558. MoveController.AddConstantForce(_throwForce);
  559. }
  560.  
  561. /// <summary>
  562. /// 将该节点投抛出去
  563. /// </summary>
  564. /// <param name="position">初始位置</param>
  565. /// <param name="altitude">初始高度</param>
  566. /// <param name="verticalSpeed">纵轴速度</param>
  567. /// <param name="velocity">移动速率</param>
  568. /// <param name="rotate">旋转速度</param>
  569. public void Throw(Vector2 position, float altitude, float verticalSpeed, Vector2 velocity, float rotate)
  570. {
  571. GlobalPosition = position;
  572. Throw(altitude, verticalSpeed, velocity, rotate);
  573. }
  574.  
  575.  
  576. /// <summary>
  577. /// 强制停止投抛运动
  578. /// </summary>
  579. public void StopThrow()
  580. {
  581. _isFallOver = true;
  582. RestoreCollision();
  583. }
  584.  
  585. /// <summary>
  586. /// 往当前物体上挂载一个组件
  587. /// </summary>
  588. public T AddComponent<T>() where T : Component, new()
  589. {
  590. var component = new T();
  591. _components.Add(new KeyValuePair<Type, Component>(typeof(T), component));
  592. component.ActivityInstance = this;
  593. return component;
  594. }
  595.  
  596. /// <summary>
  597. /// 移除一个组件, 并且销毁
  598. /// </summary>
  599. /// <param name="component">组件对象</param>
  600. public void RemoveComponent(Component component)
  601. {
  602. for (int i = 0; i < _components.Count; i++)
  603. {
  604. if (_components[i].Value == component)
  605. {
  606. _components.RemoveAt(i);
  607. component.Destroy();
  608. return;
  609. }
  610. }
  611. }
  612.  
  613. /// <summary>
  614. /// 根据类型获取一个组件
  615. /// </summary>
  616. public Component GetComponent(Type type)
  617. {
  618. for (int i = 0; i < _components.Count; i++)
  619. {
  620. var temp = _components[i];
  621. if (temp.Key == type)
  622. {
  623. return temp.Value;
  624. }
  625. }
  626.  
  627. return null;
  628. }
  629.  
  630. /// <summary>
  631. /// 根据类型获取一个组件
  632. /// </summary>
  633. public T GetComponent<T>() where T : Component
  634. {
  635. var component = GetComponent(typeof(T));
  636. if (component == null) return null;
  637. return (T)component;
  638. }
  639.  
  640. /// <summary>
  641. /// 设置混色材质的颜色
  642. /// </summary>
  643. public void SetBlendColor(Color color)
  644. {
  645. _blendShaderMaterial.SetShaderParameter("blend", color);
  646. }
  647.  
  648. /// <summary>
  649. /// 获取混色材质的颜色
  650. /// </summary>
  651. public Color GetBlendColor()
  652. {
  653. return _blendShaderMaterial.GetShaderParameter("blend").AsColor();
  654. }
  655. /// <summary>
  656. /// 设置混色材质的强度
  657. /// </summary>
  658. public void SetBlendSchedule(float value)
  659. {
  660. _blendShaderMaterial.SetShaderParameter("schedule", value);
  661. }
  662.  
  663. /// <summary>
  664. /// 获取混色材质的强度
  665. /// </summary>
  666. public float GetBlendSchedule()
  667. {
  668. return _blendShaderMaterial.GetShaderParameter("schedule").AsSingle();
  669. }
  670. /// <summary>
  671. /// 每帧调用一次, 为了防止子类覆盖 _Process(), 给 _Process() 加上了 sealed, 子类需要帧循环函数请重写 Process() 函数
  672. /// </summary>
  673. public sealed override void _Process(double delta)
  674. {
  675. var newDelta = (float)delta;
  676. if (EnableCustomBehavior)
  677. {
  678. Process(newDelta);
  679. }
  680. //更新组件
  681. if (_components.Count > 0)
  682. {
  683. if (EnableCustomBehavior) //启用所有组件
  684. {
  685. var arr = _components.ToArray();
  686. for (int i = 0; i < arr.Length; i++)
  687. {
  688. if (IsDestroyed) return;
  689. var temp = arr[i].Value;
  690. if (temp != null && temp.ActivityInstance == this && temp.Enable)
  691. {
  692. if (!temp.IsReady)
  693. {
  694. temp.Ready();
  695. temp.IsReady = true;
  696. }
  697.  
  698. temp.Process(newDelta);
  699. }
  700. }
  701. }
  702. else //只更新 MoveController 组件
  703. {
  704. if (!MoveController.IsReady)
  705. {
  706. MoveController.Ready();
  707. MoveController.IsReady = true;
  708. }
  709. MoveController.Process(newDelta);
  710. }
  711. }
  712.  
  713. // 下坠判定
  714. if (Altitude > 0 || VerticalSpeed != 0)
  715. {
  716. if (_fallData == null)
  717. {
  718. _fallData = new ActivityFallData();
  719. }
  720. if (_isFallOver) // 没有处于下坠状态, 则进入下坠状态
  721. {
  722. SetFallCollision();
  723.  
  724. _isFallOver = false;
  725. _firstFall = true;
  726. _hasResilienceVerticalSpeed = false;
  727. _resilienceVerticalSpeed = 0;
  728. if (ThrowCollisionSize.X < 0 && ThrowCollisionSize.Y < 0)
  729. {
  730. _throwRectangleShape.Size = GetDefaultTexture().GetSize();
  731. }
  732. else
  733. {
  734. _throwRectangleShape.Size = ThrowCollisionSize;
  735. }
  736.  
  737. Throw();
  738. }
  739. else
  740. {
  741. if (EnableVerticalMotion) //如果启用了纵向运动, 则更新运动
  742. {
  743. GlobalRotationDegrees = GlobalRotationDegrees + ThrowRotationDegreesSpeed * newDelta;
  744.  
  745. var ysp = VerticalSpeed;
  746.  
  747. _altitude += VerticalSpeed * newDelta;
  748. _verticalSpeed -= GameConfig.G * newDelta;
  749.  
  750. //当高度大于16时, 显示在所有物体上
  751. if (Altitude >= 16)
  752. {
  753. AnimatedSprite.ZIndex = 20;
  754. }
  755. else
  756. {
  757. AnimatedSprite.ZIndex = 0;
  758. }
  759. //达到最高点
  760. if (ysp > 0 && ysp * VerticalSpeed < 0)
  761. {
  762. OnThrowMaxHeight(Altitude);
  763. }
  764.  
  765. //落地判断
  766. if (Altitude <= 0)
  767. {
  768. _altitude = 0;
  769.  
  770. //第一次接触地面
  771. if (_firstFall)
  772. {
  773. _firstFall = false;
  774. OnFirstFallToGround();
  775. }
  776.  
  777. MoveController.ScaleAllForce(BounceSpeed);
  778. //如果落地高度不够低, 再抛一次
  779. if (Bounce && (!_hasResilienceVerticalSpeed || _resilienceVerticalSpeed > 1))
  780. {
  781. if (!_hasResilienceVerticalSpeed)
  782. {
  783. _hasResilienceVerticalSpeed = true;
  784. _resilienceVerticalSpeed = -VerticalSpeed * BounceStrength;
  785. }
  786. else
  787. {
  788. _resilienceVerticalSpeed = _resilienceVerticalSpeed * BounceStrength;
  789. }
  790. _verticalSpeed = _resilienceVerticalSpeed;
  791. ThrowRotationDegreesSpeed = ThrowRotationDegreesSpeed * BounceStrength;
  792. _isFallOver = false;
  793.  
  794. OnFallToGround();
  795. }
  796. else //结束
  797. {
  798. _verticalSpeed = 0;
  799.  
  800. if (_throwForce != null)
  801. {
  802. MoveController.RemoveForce(_throwForce);
  803. _throwForce = null;
  804. }
  805. _isFallOver = true;
  806. OnFallToGround();
  807. ThrowOver();
  808. }
  809. }
  810. }
  811.  
  812. //计算精灵位置
  813. CalcThrowAnimatedPosition();
  814. }
  815. }
  816.  
  817. //阴影
  818. if (ShadowSprite.Visible)
  819. {
  820. //更新阴影贴图, 使其和动画一致
  821. var anim = AnimatedSprite.Animation;
  822. var frame = AnimatedSprite.Frame;
  823. if (_prevAnimation != anim || _prevAnimationFrame != frame)
  824. {
  825. //切换阴影动画
  826. ShadowSprite.Texture = AnimatedSprite.SpriteFrames.GetFrameTexture(anim, AnimatedSprite.Frame);
  827. }
  828.  
  829. _prevAnimation = anim;
  830. _prevAnimationFrame = frame;
  831.  
  832. //计算阴影
  833. CalcShadow();
  834. }
  835.  
  836. // Hit 动画
  837. if (_playHit)
  838. {
  839. if (_playHitSchedule < 0.05f)
  840. {
  841. _blendShaderMaterial.SetShaderParameter("schedule", 1);
  842. }
  843. else if (_playHitSchedule < 0.15f)
  844. {
  845. _blendShaderMaterial.SetShaderParameter("schedule", Mathf.Lerp(1, 0, (_playHitSchedule - 0.05f) / 0.1f));
  846. }
  847. if (_playHitSchedule >= 0.15f)
  848. {
  849. _blendShaderMaterial.SetShaderParameter("schedule", 0);
  850. _playHitSchedule = 0;
  851. _playHit = false;
  852. }
  853. else
  854. {
  855. _playHitSchedule += newDelta;
  856. }
  857. }
  858. //协程更新
  859. if (_coroutineList != null)
  860. {
  861. ProxyCoroutineHandler.ProxyUpdateCoroutine(ref _coroutineList, newDelta);
  862. }
  863.  
  864. ProcessOver(newDelta);
  865. //调试绘制
  866. if (IsDebug)
  867. {
  868. QueueRedraw();
  869. }
  870. }
  871.  
  872. /// <summary>
  873. /// 每物理帧调用一次, 为了防止子类覆盖 _PhysicsProcess(), 给 _PhysicsProcess() 加上了 sealed, 子类需要帧循环函数请重写 PhysicsProcess() 函数
  874. /// </summary>
  875. public sealed override void _PhysicsProcess(double delta)
  876. {
  877. var newDelta = (float)delta;
  878. if (EnableCustomBehavior)
  879. {
  880. PhysicsProcess(newDelta);
  881. }
  882. //更新组件
  883. if (_components.Count > 0)
  884. {
  885. if (EnableCustomBehavior) //启用所有组件
  886. {
  887. var arr = _components.ToArray();
  888. for (int i = 0; i < arr.Length; i++)
  889. {
  890. if (IsDestroyed) return;
  891. var temp = arr[i].Value;
  892. if (temp != null && temp.ActivityInstance == this && temp.Enable)
  893. {
  894. if (!temp.IsReady)
  895. {
  896. temp.Ready();
  897. temp.IsReady = true;
  898. }
  899.  
  900. temp.PhysicsProcess(newDelta);
  901. }
  902. }
  903. }
  904. else //只更新 MoveController 组件
  905. {
  906. if (!MoveController.IsReady)
  907. {
  908. MoveController.Ready();
  909. MoveController.IsReady = true;
  910. }
  911. MoveController.PhysicsProcess(newDelta);
  912. }
  913. }
  914.  
  915. PhysicsProcessOver(newDelta);
  916. }
  917.  
  918. /// <summary>
  919. /// 绘制函数, 子类不允许重写, 需要绘制函数请重写 DebugDraw()
  920. /// </summary>
  921. public sealed override void _Draw()
  922. {
  923. if (IsDebug)
  924. {
  925. DebugDraw();
  926. var arr = _components.ToArray();
  927. for (int i = 0; i < arr.Length; i++)
  928. {
  929. if (IsDestroyed) return;
  930. var temp = arr[i].Value;
  931. if (temp != null && temp.ActivityInstance == this && temp.Enable)
  932. {
  933. temp.DebugDraw();
  934. }
  935. }
  936. }
  937. }
  938.  
  939. /// <summary>
  940. /// 重新计算物体阴影的位置和旋转信息, 无论是否显示阴影
  941. /// </summary>
  942. public void CalcShadow()
  943. {
  944. //缩放
  945. ShadowSprite.Scale = AnimatedSprite.Scale;
  946. //阴影角度
  947. ShadowSprite.Rotation = 0;
  948. //阴影位置计算
  949. var pos = AnimatedSprite.GlobalPosition;
  950. ShadowSprite.GlobalPosition = new Vector2(pos.X + ShadowOffset.X, pos.Y + ShadowOffset.Y + Altitude);
  951. }
  952.  
  953. //计算位置
  954. private void CalcThrowAnimatedPosition()
  955. {
  956. if (Scale.Y < 0)
  957. {
  958. AnimatedSprite.GlobalPosition = GlobalPosition + new Vector2(0, -Altitude) - _fallData.OriginSpritePosition.Rotated(Rotation) * Scale.Abs();
  959. }
  960. else
  961. {
  962. AnimatedSprite.GlobalPosition = GlobalPosition + new Vector2(0, -Altitude) + _fallData.OriginSpritePosition.Rotated(Rotation);
  963. }
  964. }
  965.  
  966.  
  967. /// <summary>
  968. /// 销毁物体
  969. /// </summary>
  970. public void Destroy()
  971. {
  972. if (IsDestroyed)
  973. {
  974. return;
  975. }
  976.  
  977. IsDestroyed = true;
  978. QueueFree();
  979. OnDestroy();
  980.  
  981. var arr = _components.ToArray();
  982. for (int i = 0; i < arr.Length; i++)
  983. {
  984. arr[i].Value?.Destroy();
  985. }
  986. if (Affiliation != null)
  987. {
  988. Affiliation.RemoveItem(this);
  989. }
  990. //临时处理, 4.0 有bug, 不能提前销毁模板实例, 不然关闭游戏会报错!!!
  991. _templateInstance.QueueFree();
  992. }
  993.  
  994. /// <summary>
  995. /// 延时销毁
  996. /// </summary>
  997. public void DelayDestroy()
  998. {
  999. CallDeferred(nameof(Destroy));
  1000. }
  1001.  
  1002. /// <summary>
  1003. /// 继承指定物体的运动速率, 该速率可能会有衰减
  1004. /// </summary>
  1005. public void InheritVelocity(ActivityObject other)
  1006. {
  1007. var velocity = other.Velocity;
  1008. if (velocity != Vector2.Zero)
  1009. {
  1010. var force = MoveController.AddConstantForce(velocity * 0.5f, 15);
  1011. force.EnableResistanceInTheAir = false;
  1012. }
  1013. }
  1014.  
  1015. /// <summary>
  1016. /// 触发投抛动作
  1017. /// </summary>
  1018. private void Throw()
  1019. {
  1020. var parent = GetParent();
  1021. //投抛时必须要加入 YSortLayer 节点下
  1022. if (parent == null)
  1023. {
  1024. this.AddToActivityRoot(RoomLayerEnum.YSortLayer);
  1025. }
  1026. else if (parent == GameApplication.Instance.RoomManager.NormalLayer)
  1027. {
  1028. parent.RemoveChild(this);
  1029. this.AddToActivityRoot(RoomLayerEnum.YSortLayer);
  1030. }
  1031.  
  1032. CalcThrowAnimatedPosition();
  1033. //显示阴影
  1034. ShowShadowSprite();
  1035.  
  1036. if (EnableVerticalMotion)
  1037. {
  1038. OnThrowStart();
  1039. }
  1040. }
  1041.  
  1042. /// <summary>
  1043. /// 设置下坠状态下的碰撞器
  1044. /// </summary>
  1045. private void SetFallCollision()
  1046. {
  1047. if (_fallData != null && _fallData.UseOrigin)
  1048. {
  1049. _fallData.OriginShape = Collision.Shape;
  1050. _fallData.OriginPosition = Collision.Position;
  1051. _fallData.OriginRotation = Collision.Rotation;
  1052. _fallData.OriginScale = Collision.Scale;
  1053. _fallData.OriginZIndex = ZIndex;
  1054. _fallData.OriginSpritePosition = AnimatedSprite.Position;
  1055. _fallData.OriginCollisionEnable = Collision.Disabled;
  1056. _fallData.OriginCollisionPosition = Collision.Position;
  1057. _fallData.OriginCollisionRotation = Collision.Rotation;
  1058. _fallData.OriginCollisionScale = Collision.Scale;
  1059. _fallData.OriginCollisionMask = CollisionMask;
  1060. _fallData.OriginCollisionLayer = CollisionLayer;
  1061.  
  1062. if (_throwRectangleShape == null)
  1063. {
  1064. _throwRectangleShape = new RectangleShape2D();
  1065. }
  1066.  
  1067. Collision.Shape = _throwRectangleShape;
  1068. Collision.Position = Vector2.Zero;
  1069. Collision.Rotation = 0;
  1070. Collision.Scale = Vector2.One;
  1071. ZIndex = 0;
  1072. Collision.Disabled = false;
  1073. Collision.Position = Vector2.Zero;
  1074. Collision.Rotation = 0;
  1075. Collision.Scale = Vector2.One;
  1076. CollisionMask = 1;
  1077. CollisionLayer = 0;
  1078. _fallData.UseOrigin = false;
  1079. }
  1080. }
  1081.  
  1082. /// <summary>
  1083. /// 重置碰撞器
  1084. /// </summary>
  1085. private void RestoreCollision()
  1086. {
  1087. if (_fallData != null && !_fallData.UseOrigin)
  1088. {
  1089. Collision.Shape = _fallData.OriginShape;
  1090. Collision.Position = _fallData.OriginPosition;
  1091. Collision.Rotation = _fallData.OriginRotation;
  1092. Collision.Scale = _fallData.OriginScale;
  1093. ZIndex = _fallData.OriginZIndex;
  1094. AnimatedSprite.Position = _fallData.OriginSpritePosition;
  1095. Collision.Disabled = _fallData.OriginCollisionEnable;
  1096. Collision.Position = _fallData.OriginCollisionPosition;
  1097. Collision.Rotation = _fallData.OriginCollisionRotation;
  1098. Collision.Scale = _fallData.OriginCollisionScale;
  1099. CollisionMask = _fallData.OriginCollisionMask;
  1100. CollisionLayer = _fallData.OriginCollisionLayer;
  1101.  
  1102. _fallData.UseOrigin = true;
  1103. }
  1104. }
  1105.  
  1106. /// <summary>
  1107. /// 投抛结束
  1108. /// </summary>
  1109. private void ThrowOver()
  1110. {
  1111. var parent = GetParent();
  1112. var roomLayer = GameApplication.Instance.RoomManager.GetRoomLayer(_currLayer);
  1113. if (parent != roomLayer)
  1114. {
  1115. parent.RemoveChild(this);
  1116. roomLayer.AddChild(this);
  1117. }
  1118. RestoreCollision();
  1119.  
  1120. OnThrowOver();
  1121. }
  1122.  
  1123. /// <summary>
  1124. /// 设置标记, 用于在物体上记录自定义数据
  1125. /// </summary>
  1126. /// <param name="name">标记名称</param>
  1127. /// <param name="v">存入值</param>
  1128. public void SetSign(string name, object v)
  1129. {
  1130. if (_signMap == null)
  1131. {
  1132. _signMap = new Dictionary<string, object>();
  1133. }
  1134.  
  1135. _signMap[name] = v;
  1136. }
  1137.  
  1138. /// <summary>
  1139. /// 返回是否存在指定名称的标记数据
  1140. /// </summary>
  1141. public bool HasSign(string name)
  1142. {
  1143. return _signMap == null ? false : _signMap.ContainsKey(name);
  1144. }
  1145.  
  1146. /// <summary>
  1147. /// 根据名称获取标记值
  1148. /// </summary>
  1149. public object GetSign(string name)
  1150. {
  1151. if (_signMap == null)
  1152. {
  1153. return null;
  1154. }
  1155.  
  1156. _signMap.TryGetValue(name, out var value);
  1157. return value;
  1158. }
  1159.  
  1160. /// <summary>
  1161. /// 根据名称获取标记值
  1162. /// </summary>
  1163. public T GetSign<T>(string name)
  1164. {
  1165. if (_signMap == null)
  1166. {
  1167. return default;
  1168. }
  1169.  
  1170. _signMap.TryGetValue(name, out var value);
  1171. if (value is T v)
  1172. {
  1173. return v;
  1174. }
  1175. return default;
  1176. }
  1177.  
  1178. /// <summary>
  1179. /// 根据名称删除标记
  1180. /// </summary>
  1181. public void RemoveSign(string name)
  1182. {
  1183. if (_signMap != null)
  1184. {
  1185. _signMap.Remove(name);
  1186. }
  1187. }
  1188.  
  1189. /// <summary>
  1190. /// 播放受伤动画, 该动画不与 Animation 节点的动画冲突
  1191. /// </summary>
  1192. public void PlayHitAnimation()
  1193. {
  1194. _playHit = true;
  1195. _playHitSchedule = 0;
  1196. }
  1197.  
  1198. /// <summary>
  1199. /// 开启一个协程, 返回协程 id, 协程是在普通帧执行的, 支持: 协程嵌套, WaitForSeconds, WaitForFixedProcess, Task
  1200. /// </summary>
  1201. public long StartCoroutine(IEnumerator able)
  1202. {
  1203. return ProxyCoroutineHandler.ProxyStartCoroutine(ref _coroutineList, able);
  1204. }
  1205.  
  1206. /// <summary>
  1207. /// 根据协程 id 停止协程
  1208. /// </summary>
  1209. public void StopCoroutine(long coroutineId)
  1210. {
  1211. ProxyCoroutineHandler.ProxyStopCoroutine(ref _coroutineList, coroutineId);
  1212. }
  1213. /// <summary>
  1214. /// 停止所有协程
  1215. /// </summary>
  1216. public void StopAllCoroutine()
  1217. {
  1218. ProxyCoroutineHandler.ProxyStopAllCoroutine(ref _coroutineList);
  1219. }
  1220. }