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