Newer
Older
DungeonShooting / DungeonShooting_Godot / src / framework / activity / ActivityObject.cs
@小李xl 小李xl on 20 Dec 2023 52 KB 小修改
  1.  
  2. using System;
  3. using System.Collections;
  4. using System.Collections.Generic;
  5. using Config;
  6. using Godot;
  7.  
  8. /// <summary>
  9. /// 房间内活动物体基类, 所有物体都必须继承该类,<br/>
  10. /// 该类提供基础物体运动模拟, 互动接口, 自定义组件, 协程等功能<br/>
  11. /// ActivityObject 子类实例化请不要直接使用 new, 而用该在类上标上 [Tool], 并在 ActivityObject.xlsx 配置文件中注册物体, 导出配置表后使用 ActivityObject.Create(id) 来创建实例.<br/>
  12. /// </summary>
  13. [Tool]
  14. public partial class ActivityObject : CharacterBody2D, IDestroy, ICoroutine
  15. {
  16. /// <summary>
  17. /// 是否是调试模式
  18. /// </summary>
  19. public static bool IsDebug { get; set; }
  20.  
  21. /// <summary>
  22. /// 实例唯一 Id
  23. /// </summary>
  24. public long Id { get; set; }
  25. /// <summary>
  26. /// 当前物体对应的配置数据, 如果不是通过 ActivityObject.Create() 函数创建出来的对象那么 ItemConfig 为 null
  27. /// </summary>
  28. public ExcelConfig.ActivityBase ActivityBase { get; private set; }
  29.  
  30. /// <summary>
  31. /// 是否是静态物体, 如果为true, 则会禁用移动处理
  32. /// </summary>
  33. public bool IsStatic
  34. {
  35. get => MoveController != null ? !MoveController.Enable : true;
  36. set
  37. {
  38. if (MoveController != null)
  39. {
  40. MoveController.Enable = !value;
  41. }
  42. }
  43. }
  44.  
  45. /// <summary>
  46. /// 是否显示阴影
  47. /// </summary>
  48. public bool IsShowShadow { get; private set; }
  49. /// <summary>
  50. /// 当前物体显示的阴影图像, 节点名称必须叫 "ShadowSprite", 类型为 Sprite2D
  51. /// </summary>
  52. [Export, ExportFillNode]
  53. public Sprite2D ShadowSprite { get; set; }
  54. /// <summary>
  55. /// 当前物体显示的精灵图像, 节点名称必须叫 "AnimatedSprite2D", 类型为 AnimatedSprite2D
  56. /// </summary>
  57. [Export, ExportFillNode]
  58. public AnimatedSprite2D AnimatedSprite { get; set; }
  59.  
  60. /// <summary>
  61. /// 当前物体碰撞器节点, 节点名称必须叫 "Collision", 类型为 CollisionShape2D
  62. /// </summary>
  63. [Export, ExportFillNode]
  64. public CollisionShape2D Collision { get; set; }
  65.  
  66. /// <summary>
  67. /// 是否调用过 Destroy() 函数
  68. /// </summary>
  69. public bool IsDestroyed { get; private set; }
  70. /// <summary>
  71. /// 阴影偏移
  72. /// </summary>
  73. [Export]
  74. public Vector2 ShadowOffset { get; protected set; } = new Vector2(0, 2);
  75. /// <summary>
  76. /// 移动控制器
  77. /// </summary>
  78. public MoveController MoveController { get; private set; }
  79.  
  80. /// <summary>
  81. /// 物体移动基础速率
  82. /// </summary>
  83. public Vector2 BasisVelocity
  84. {
  85. get
  86. {
  87. if (MoveController != null)
  88. {
  89. return MoveController.BasisVelocity;
  90. }
  91.  
  92. return Vector2.Zero;
  93. }
  94. set
  95. {
  96. if (MoveController != null)
  97. {
  98. MoveController.BasisVelocity = value;
  99. }
  100. }
  101. }
  102.  
  103. /// <summary>
  104. /// 当前物体归属的区域, 如果为 null 代表不属于任何一个区域
  105. /// </summary>
  106. public AffiliationArea AffiliationArea
  107. {
  108. get => _affiliationArea;
  109. set
  110. {
  111. if (value != _affiliationArea)
  112. {
  113. var prev = _affiliationArea;
  114. _affiliationArea = value;
  115. if (!IsDestroyed)
  116. {
  117. OnAffiliationChange(prev);
  118. }
  119. }
  120. }
  121. }
  122.  
  123. /// <summary>
  124. /// 是否正在投抛过程中
  125. /// </summary>
  126. public bool IsThrowing => VerticalSpeed != 0 && !_isFallOver;
  127.  
  128. /// <summary>
  129. /// 当前物体的海拔高度, 如果大于0, 则会做自由落体运动, 也就是执行投抛逻辑
  130. /// </summary>
  131. public float Altitude
  132. {
  133. get => _altitude;
  134. set
  135. {
  136. _altitude = value;
  137. _hasResilienceVerticalSpeed = false;
  138. }
  139. }
  140.  
  141. private float _altitude = 0;
  142.  
  143. /// <summary>
  144. /// 物体纵轴移动速度, 如果设置大于0, 就可以营造向上投抛物体的效果, 该值会随着重力加速度衰减
  145. /// </summary>
  146. public float VerticalSpeed
  147. {
  148. get => _verticalSpeed;
  149. set
  150. {
  151. _verticalSpeed = value;
  152. _hasResilienceVerticalSpeed = false;
  153. }
  154. }
  155.  
  156. private float _verticalSpeed;
  157.  
  158. /// <summary>
  159. /// 投抛状态下物体碰撞器大小, 如果 (x, y) 都小于 0, 则默认使用 AnimatedSprite 的默认动画第一帧的大小
  160. /// </summary>
  161. [Export]
  162. public Vector2 ThrowCollisionSize { get; set; } = new Vector2(-1, -1);
  163.  
  164. /// <summary>
  165. /// 是否启用垂直方向上的运动模拟, 默认开启, 如果禁用, 那么下落和投抛效果, 同样 Throw() 函数也将失效
  166. /// </summary>
  167. public bool EnableVerticalMotion { get; set; } = true;
  168. /// <summary>
  169. /// 是否启用物体更新行为, 默认 true, 如果禁用, 则会停止当前物体的 Process(), PhysicsProcess() 调用, 并且禁用 Collision 节点, 禁用后所有组件也同样被禁用行为
  170. /// </summary>
  171. public bool EnableBehavior
  172. {
  173. get => _enableBehavior;
  174. set
  175. {
  176. if (value != _enableBehavior)
  177. {
  178. _enableBehavior = value;
  179. SetProcess(value);
  180. SetPhysicsProcess(value);
  181. if (value)
  182. {
  183. Collision.Disabled = _enableBehaviorCollisionDisabledFlag;
  184. }
  185. else
  186. {
  187. _enableBehaviorCollisionDisabledFlag = Collision.Disabled;
  188. Collision.Disabled = true;
  189. }
  190. }
  191. }
  192. }
  193.  
  194. /// <summary>
  195. /// 是否启用自定义行为, 默认 true, 如果禁用, 则会停止调用子类重写的 Process(), PhysicsProcess() 函数, 并且当前物体除 MoveController 以外的组件 Process(), PhysicsProcess() 也会停止调用
  196. /// </summary>
  197. public bool EnableCustomBehavior { get; set; } = true;
  198. /// <summary>
  199. /// 物体材质数据
  200. /// </summary>
  201. public ExcelConfig.ActivityMaterial ActivityMaterial { get; private set; }
  202. /// <summary>
  203. /// 所在的 World 对象
  204. /// </summary>
  205. public World World { get; private set; }
  206.  
  207. /// <summary>
  208. /// 是否开启描边
  209. /// </summary>
  210. public bool ShowOutline
  211. {
  212. get => _blendShaderMaterial == null ? false : _blendShaderMaterial.GetShaderParameter(ShaderParamNames.ShowOutline).AsBool();
  213. set
  214. {
  215. _blendShaderMaterial?.SetShaderParameter(ShaderParamNames.ShowOutline, value);
  216. _shadowBlendShaderMaterial?.SetShaderParameter(ShaderParamNames.ShowOutline, value);
  217. }
  218. }
  219.  
  220. /// <summary>
  221. /// 描边颜色
  222. /// </summary>
  223. public Color OutlineColor
  224. {
  225. get => _blendShaderMaterial == null ? Colors.Black : _blendShaderMaterial.GetShaderParameter(ShaderParamNames.OutlineColor).AsColor();
  226. set => _blendShaderMaterial?.SetShaderParameter(ShaderParamNames.OutlineColor, value);
  227. }
  228.  
  229. /// <summary>
  230. /// 灰度
  231. /// </summary>
  232. public float Grey
  233. {
  234. get => _blendShaderMaterial == null ? 0 : _blendShaderMaterial.GetShaderParameter(ShaderParamNames.Grey).AsSingle();
  235. set => _blendShaderMaterial?.SetShaderParameter(ShaderParamNames.Grey, value);
  236. }
  237. /// <summary>
  238. /// 是否是自定义阴影纹理
  239. /// </summary>
  240. public bool IsCustomShadowSprite { get; private set; }
  241.  
  242. /// <summary>
  243. /// 记录绘制液体的笔刷上一次绘制的位置<br/>
  244. /// 每次调用 DrawLiquid() 后都会记录这一次绘制的位置, 记录这个位置用作执行补间操作, 但是一旦停止绘制了, 需要手动清理记录的位置, 也就是将 BrushPrevPosition 置为 null
  245. /// </summary>
  246. public Vector2I? BrushPrevPosition { get; set; }
  247. // --------------------------------------------------------------------------------
  248.  
  249. //是否正在调用组件 Update 函数
  250. private bool _updatingComp = false;
  251. //组件集合
  252. private readonly List<KeyValuePair<Type, Component>> _components = new List<KeyValuePair<Type, Component>>();
  253. //修改的组件集合, value 为 true 表示添加组件, false 表示移除组件
  254. private readonly List<KeyValuePair<Component, bool>> _changeComponents = new List<KeyValuePair<Component, bool>>();
  255. //上一帧动画名称
  256. private StringName _prevAnimation;
  257. //上一帧动画
  258. private int _prevAnimationFrame;
  259.  
  260. //播放 Hit 动画
  261. private bool _playHit;
  262. private float _playHitSchedule;
  263.  
  264. //混色shader材质
  265. private ShaderMaterial _blendShaderMaterial;
  266. private ShaderMaterial _shadowBlendShaderMaterial;
  267. //存储投抛该物体时所产生的数据
  268. private readonly ActivityFallData _fallData = new ActivityFallData();
  269. //所在层级
  270. private RoomLayerEnum _currLayer;
  271. //标记字典
  272. private Dictionary<string, object> _signMap;
  273. //开启的协程
  274. private List<CoroutineData> _coroutineList;
  275.  
  276. //物体所在区域
  277. private AffiliationArea _affiliationArea;
  278.  
  279. //是否是第一次下坠
  280. private bool _firstFall = true;
  281. //下坠是否已经结束
  282. private bool _isFallOver = true;
  283.  
  284. //下坠状态碰撞器形状
  285. private RectangleShape2D _throwRectangleShape;
  286.  
  287. //投抛移动速率
  288. private ExternalForce _throwForce;
  289. //落到地上回弹的速度
  290. private float _resilienceVerticalSpeed = 0;
  291. private bool _hasResilienceVerticalSpeed = false;
  292.  
  293. //是否启用物体行为
  294. private bool _enableBehavior = true;
  295. private bool _enableBehaviorCollisionDisabledFlag;
  296.  
  297. private bool _processingBecomesStaticImage = false;
  298.  
  299. //击退外力
  300. private ExternalForce _repelForce;
  301.  
  302. // --------------------------------------------------------------------------------
  303. //实例索引
  304. private static long _instanceIndex = 0;
  305. //冻结显示的Sprite
  306. private FreezeSprite _freezeSprite;
  307.  
  308. //初始化节点
  309. private void _InitNode(ExcelConfig.ActivityBase config, World world)
  310. {
  311. #if TOOLS
  312. if (!Engine.IsEditorHint())
  313. {
  314. if (GetType().GetCustomAttributes(typeof(ToolAttribute), false).Length == 0)
  315. {
  316. throw new Exception($"ActivityObject子类'{GetType().FullName}'没有加[Tool]标记!");
  317. }
  318. }
  319. #endif
  320. if (config.Material == null)
  321. {
  322. ActivityMaterial = ExcelConfig.ActivityMaterial_List[0];
  323. }
  324. else
  325. {
  326. ActivityMaterial = config.Material;
  327. }
  328.  
  329. //GravityScale 为 0 时关闭重力
  330. if (ActivityMaterial.GravityScale == 0)
  331. {
  332. EnableVerticalMotion = false;
  333. }
  334. World = world;
  335. ActivityBase = config;
  336. #if TOOLS
  337. Name = GetType().Name + (_instanceIndex++);
  338. #endif
  339. Id = _instanceIndex;
  340. _blendShaderMaterial = AnimatedSprite.Material as ShaderMaterial;
  341. IsCustomShadowSprite = ShadowSprite.Texture != null;
  342. if (!IsCustomShadowSprite) //没有自定义阴影纹理
  343. {
  344. _shadowBlendShaderMaterial = ShadowSprite.Material as ShaderMaterial;
  345. if (_shadowBlendShaderMaterial != null && _blendShaderMaterial != null)
  346. {
  347. var value = _blendShaderMaterial.GetShaderParameter(ShaderParamNames.ShowOutline);
  348. _shadowBlendShaderMaterial.SetShaderParameter(ShaderParamNames.ShowOutline, value);
  349. }
  350. ShadowSprite.Visible = false;
  351. }
  352.  
  353. MotionMode = MotionModeEnum.Floating;
  354. MoveController = AddComponent<MoveController>();
  355. IsStatic = config.IsStatic;
  356. OnInit();
  357. }
  358.  
  359. /// <summary>
  360. /// 子类重写的 _Ready() 可能会比 _InitNode() 函数调用晚, 所以禁止子类重写, 如需要 _Ready() 类似的功能需重写 OnInit()
  361. /// </summary>
  362. public sealed override void _Ready()
  363. {
  364.  
  365. }
  366. /// <summary>
  367. /// 子类需要重写 _EnterTree() 函数, 请重写 EnterTree()
  368. /// </summary>
  369. public sealed override void _EnterTree()
  370. {
  371. #if TOOLS
  372. // 在工具模式下创建的 template 节点自动创建对应的必要子节点
  373. if (Engine.IsEditorHint())
  374. {
  375. _InitNodeInEditor();
  376. return;
  377. }
  378. #endif
  379. EnterTree();
  380. }
  381. /// <summary>
  382. /// 子类需要重写 _ExitTree() 函数, 请重写 ExitTree()
  383. /// </summary>
  384. public sealed override void _ExitTree()
  385. {
  386. #if TOOLS
  387. // 在工具模式下创建的 template 节点自动创建对应的必要子节点
  388. if (Engine.IsEditorHint())
  389. {
  390. return;
  391. }
  392. #endif
  393. ExitTree();
  394. }
  395.  
  396. /// <summary>
  397. /// 显示并更新阴影
  398. /// </summary>
  399. public void ShowShadowSprite()
  400. {
  401. if (!IsCustomShadowSprite)
  402. {
  403. var anim = AnimatedSprite.Animation;
  404. var frame = AnimatedSprite.Frame;
  405. if (_prevAnimation != anim || _prevAnimationFrame != frame)
  406. {
  407. var frames = AnimatedSprite.SpriteFrames;
  408. if (frames != null && frames.HasAnimation(anim))
  409. {
  410. //切换阴影动画
  411. ShadowSprite.Texture = frames.GetFrameTexture(anim, frame);
  412. }
  413. }
  414.  
  415. _prevAnimation = anim;
  416. _prevAnimationFrame = frame;
  417. }
  418.  
  419. IsShowShadow = true;
  420. CalcShadowTransform();
  421. ShadowSprite.Visible = true;
  422. }
  423.  
  424. /// <summary>
  425. /// 隐藏阴影
  426. /// </summary>
  427. public void HideShadowSprite()
  428. {
  429. ShadowSprite.Visible = false;
  430. IsShowShadow = false;
  431. }
  432.  
  433. /// <summary>
  434. /// 设置默认序列帧动画的第一帧
  435. /// </summary>
  436. public void SetDefaultTexture(Texture2D texture)
  437. {
  438. if (AnimatedSprite.SpriteFrames == null)
  439. {
  440. SpriteFrames spriteFrames = new SpriteFrames();
  441. AnimatedSprite.SpriteFrames = spriteFrames;
  442. spriteFrames.AddFrame("default", texture);
  443. }
  444. else
  445. {
  446. SpriteFrames spriteFrames = AnimatedSprite.SpriteFrames;
  447. spriteFrames.SetFrame("default", 0, texture);
  448. }
  449. AnimatedSprite.Play("default");
  450. }
  451.  
  452. /// <summary>
  453. /// 获取默认序列帧动画的第一帧
  454. /// </summary>
  455. public Texture2D GetDefaultTexture()
  456. {
  457. return AnimatedSprite.SpriteFrames.GetFrameTexture("default", 0);
  458. }
  459. /// <summary>
  460. /// 获取当前序列帧动画的 Texture2D
  461. /// </summary>
  462. public Texture2D GetCurrentTexture()
  463. {
  464. var spriteFrames = AnimatedSprite.SpriteFrames;
  465. if (spriteFrames == null)
  466. {
  467. return null;
  468. }
  469. return spriteFrames.GetFrameTexture(AnimatedSprite.Animation, AnimatedSprite.Frame);
  470. }
  471.  
  472. /// <summary>
  473. /// 物体初始化时调用
  474. /// </summary>
  475. public virtual void OnInit()
  476. {
  477. }
  478. /// <summary>
  479. /// 进入场景树时调用
  480. /// </summary>
  481. public virtual void EnterTree()
  482. {
  483. }
  484.  
  485. /// <summary>
  486. /// 离开场景树时调用
  487. /// </summary>
  488. public virtual void ExitTree()
  489. {
  490. }
  491. /// <summary>
  492. /// 返回是否能与其他ActivityObject互动
  493. /// </summary>
  494. /// <param name="master">触发者</param>
  495. public virtual CheckInteractiveResult CheckInteractive(ActivityObject master)
  496. {
  497. return new CheckInteractiveResult(this);
  498. }
  499.  
  500. /// <summary>
  501. /// 与其它ActivityObject互动时调用, 如果要检测是否能互动请 CheckInteractive() 函数, 如果直接调用该函数那么属于强制互动行为, 例如子弹碰到物体
  502. /// </summary>
  503. /// <param name="master">触发者</param>
  504. public virtual void Interactive(ActivityObject master)
  505. {
  506. }
  507.  
  508. /// <summary>
  509. /// 开始投抛该物体时调用
  510. /// </summary>
  511. protected virtual void OnThrowStart()
  512. {
  513. }
  514. /// <summary>
  515. /// 投抛该物体达到最高点时调用
  516. /// </summary>
  517. protected virtual void OnThrowMaxHeight(float height)
  518. {
  519. }
  520.  
  521. /// <summary>
  522. /// 投抛状态下第一次接触地面时调用, 之后的回弹落地将不会调用该函数
  523. /// </summary>
  524. protected virtual void OnFirstFallToGround()
  525. {
  526. }
  527.  
  528. /// <summary>
  529. /// 投抛状态下每次接触地面时调用
  530. /// </summary>
  531. protected virtual void OnFallToGround()
  532. {
  533. }
  534.  
  535. /// <summary>
  536. /// 投抛结束时调用
  537. /// </summary>
  538. protected virtual void OnThrowOver()
  539. {
  540. }
  541.  
  542. /// <summary>
  543. /// 当前物体销毁时调用, 销毁物体请调用 Destroy() 函数
  544. /// </summary>
  545. protected virtual void OnDestroy()
  546. {
  547. }
  548.  
  549. /// <summary>
  550. /// 每帧调用一次, 物体的 Process() 会在组件的 Process() 之前调用
  551. /// </summary>
  552. protected virtual void Process(float delta)
  553. {
  554. }
  555. /// <summary>
  556. /// 每物理帧调用一次, 物体的 PhysicsProcess() 会在组件的 PhysicsProcess() 之前调用
  557. /// </summary>
  558. protected virtual void PhysicsProcess(float delta)
  559. {
  560. }
  561. /// <summary>
  562. /// 如果开启 debug, 则每帧调用该函数, 可用于绘制文字线段等
  563. /// </summary>
  564. protected virtual void DebugDraw()
  565. {
  566. }
  567.  
  568. /// <summary>
  569. /// 归属区域发生改变
  570. /// </summary>
  571. /// <param name="prevArea">上一个区域, 注意可能为空</param>
  572. protected virtual void OnAffiliationChange(AffiliationArea prevArea)
  573. {
  574. }
  575.  
  576. /// <summary>
  577. /// 移动并碰撞到物体时调用该函数, 参数为碰撞数据, 该函数由 MoveController 调用
  578. /// </summary>
  579. public virtual void OnMoveCollision(KinematicCollision2D collision)
  580. {
  581. }
  582.  
  583. /// <summary>
  584. /// 撞到墙壁反弹时调用该函数, 参数为反弹的角度, 弧度制, 该函数由 MoveController 调用
  585. /// </summary>
  586. public virtual void OnBounce(float rotation)
  587. {
  588. }
  589.  
  590. /// <summary>
  591. /// 返回当物体 CollisionLayer 是否能与 mask 层碰撞
  592. /// </summary>
  593. public bool CollisionWithMask(uint mask)
  594. {
  595. return (CollisionLayer & mask) != 0;
  596. }
  597. /// <summary>
  598. /// 拾起一个 node 节点, 也就是将其从场景树中移除
  599. /// </summary>
  600. public void Pickup()
  601. {
  602. var parent = GetParent();
  603. if (parent != null)
  604. {
  605. if (IsThrowing)
  606. {
  607. StopThrow();
  608. }
  609.  
  610. parent.RemoveChild(this);
  611. }
  612. }
  613.  
  614. /// <summary>
  615. /// 将一个节点扔到地上
  616. /// <param name="layer">放入的层</param>
  617. /// <param name="showShadow">是否显示阴影</param>
  618. /// </summary>
  619. public virtual void PutDown(RoomLayerEnum layer, bool showShadow = true)
  620. {
  621. _currLayer = layer;
  622. var parent = GetParent();
  623. var root = GameApplication.Instance.World.GetRoomLayer(layer);
  624. if (parent != root)
  625. {
  626. if (parent != null)
  627. {
  628. Reparent(root);
  629. }
  630. else
  631. {
  632. root.AddChild(this);
  633. }
  634. }
  635.  
  636. if (showShadow)
  637. {
  638. if (IsInsideTree())
  639. {
  640. ShowShadowSprite();
  641. }
  642. else
  643. {
  644. //注意需要延时调用
  645. CallDeferred(nameof(ShowShadowSprite));
  646. CalcShadowTransform();
  647. }
  648. }
  649. else
  650. {
  651. ShadowSprite.Visible = false;
  652. }
  653. }
  654.  
  655. /// <summary>
  656. /// 将一个节点扔到地上
  657. /// </summary>
  658. /// <param name="position">放置的位置</param>
  659. /// <param name="layer">放入的层</param>
  660. /// <param name="showShadow">是否显示阴影</param>
  661. public void PutDown(Vector2 position, RoomLayerEnum layer, bool showShadow = true)
  662. {
  663. PutDown(layer);
  664. Position = position;
  665. }
  666.  
  667. /// <summary>
  668. /// 将该节点投抛出去
  669. /// </summary>
  670. /// <param name="altitude">初始高度</param>
  671. /// <param name="verticalSpeed">纵轴速度</param>
  672. /// <param name="velocity">移动速率</param>
  673. /// <param name="rotateSpeed">旋转速度</param>
  674. public void Throw(float altitude, float verticalSpeed, Vector2 velocity, float rotateSpeed)
  675. {
  676. var parent = GetParent();
  677. if (parent == null)
  678. {
  679. GameApplication.Instance.World.YSortLayer.AddChild(this);
  680. }
  681. else if (parent != GameApplication.Instance.World.YSortLayer)
  682. {
  683. parent.RemoveChild(this);
  684. GameApplication.Instance.World.YSortLayer.AddChild(this);
  685. }
  686. Altitude = altitude;
  687. //Position = Position + new Vector2(0, altitude);
  688. VerticalSpeed = verticalSpeed;
  689. //ThrowRotationDegreesSpeed = rotateSpeed;
  690. if (_throwForce != null)
  691. {
  692. MoveController.RemoveForce(_throwForce);
  693. }
  694.  
  695. _throwForce = new ExternalForce(ForceNames.Throw);
  696. _throwForce.Velocity = velocity;
  697. _throwForce.RotationSpeed = Mathf.DegToRad(rotateSpeed);
  698. MoveController.AddForce(_throwForce);
  699.  
  700. InitThrowData();
  701. }
  702.  
  703. /// <summary>
  704. /// 将该节点投抛出去
  705. /// </summary>
  706. /// <param name="position">初始位置</param>
  707. /// <param name="altitude">初始高度</param>
  708. /// <param name="verticalSpeed">纵轴速度</param>
  709. /// <param name="velocity">移动速率</param>
  710. /// <param name="rotateSpeed">旋转速度</param>
  711. public void Throw(Vector2 position, float altitude, float verticalSpeed, Vector2 velocity, float rotateSpeed)
  712. {
  713. GlobalPosition = position;
  714. Throw(altitude, verticalSpeed, velocity, rotateSpeed);
  715. }
  716.  
  717.  
  718. /// <summary>
  719. /// 强制停止投抛运动
  720. /// </summary>
  721. public void StopThrow()
  722. {
  723. _isFallOver = true;
  724. RestoreCollision();
  725. }
  726.  
  727. /// <summary>
  728. /// 往当前物体上挂载一个组件
  729. /// </summary>
  730. public T AddComponent<T>() where T : Component, new()
  731. {
  732. var component = new T();
  733. if (_updatingComp)
  734. {
  735. _changeComponents.Add(new KeyValuePair<Component, bool>(component, true));
  736. }
  737. else
  738. {
  739. _components.Add(new KeyValuePair<Type, Component>(typeof(T), component));
  740. }
  741.  
  742. component.Master = this;
  743. component.Ready();
  744. component.OnEnable();
  745. return component;
  746. }
  747.  
  748. /// <summary>
  749. /// 往当前物体上挂载一个组件
  750. /// </summary>
  751. public Component AddComponent(Type type)
  752. {
  753. var component = (Component)Activator.CreateInstance(type);
  754. if (_updatingComp)
  755. {
  756. _changeComponents.Add(new KeyValuePair<Component, bool>(component, true));
  757. }
  758. else
  759. {
  760. _components.Add(new KeyValuePair<Type, Component>(type, component));
  761. }
  762. component.Master = this;
  763. component.Ready();
  764. component.OnEnable();
  765. return component;
  766. }
  767.  
  768. /// <summary>
  769. /// 移除一个组件, 并且销毁
  770. /// </summary>
  771. /// <param name="component">组件对象</param>
  772. public void RemoveComponent(Component component)
  773. {
  774. if (component.IsDestroyed)
  775. {
  776. return;
  777. }
  778.  
  779. if (_updatingComp)
  780. {
  781. _changeComponents.Add(new KeyValuePair<Component, bool>(component, false));
  782. component.Destroy();
  783. }
  784. else
  785. {
  786. for (var i = 0; i < _components.Count; i++)
  787. {
  788. if (_components[i].Value == component)
  789. {
  790. _components.RemoveAt(i);
  791. component.Destroy();
  792. return;
  793. }
  794. }
  795. }
  796. }
  797.  
  798. /// <summary>
  799. /// 根据类型获取一个组件
  800. /// </summary>
  801. public Component GetComponent(Type type)
  802. {
  803. for (int i = 0; i < _components.Count; i++)
  804. {
  805. var temp = _components[i];
  806. if (temp.Key.IsAssignableTo(type))
  807. {
  808. return temp.Value;
  809. }
  810. }
  811.  
  812. if (_updatingComp)
  813. {
  814. for (var i = 0; i < _changeComponents.Count; i++)
  815. {
  816. var temp = _components[i];
  817. if (temp.Value.GetType().IsAssignableTo(type))
  818. {
  819. return temp.Value;
  820. }
  821. }
  822. }
  823.  
  824. return null;
  825. }
  826.  
  827. /// <summary>
  828. /// 根据类型获取一个组件
  829. /// </summary>
  830. public T GetComponent<T>() where T : Component
  831. {
  832. for (int i = 0; i < _components.Count; i++)
  833. {
  834. var temp = _components[i];
  835. if (temp.Value is T component)
  836. {
  837. return component;
  838. }
  839. }
  840.  
  841. if (_updatingComp)
  842. {
  843. for (var i = 0; i < _changeComponents.Count; i++)
  844. {
  845. var temp = _components[i];
  846. if (temp.Value is T component)
  847. {
  848. return component;
  849. }
  850. }
  851. }
  852.  
  853. return null;
  854. }
  855.  
  856. /// <summary>
  857. /// 根据类型获取所有相同类型的组件
  858. /// </summary>
  859. public Component[] GetComponents(Type type)
  860. {
  861. var list = new List<Component>();
  862. for (int i = 0; i < _components.Count; i++)
  863. {
  864. var temp = _components[i];
  865. if (temp.Key.IsAssignableTo(type))
  866. {
  867. list.Add(temp.Value);
  868. }
  869. }
  870.  
  871. if (_updatingComp)
  872. {
  873. for (var i = 0; i < _changeComponents.Count; i++)
  874. {
  875. var temp = _components[i];
  876. if (temp.Value.GetType().IsAssignableTo(type))
  877. {
  878. list.Add(temp.Value);
  879. }
  880. }
  881. }
  882.  
  883. return list.ToArray();
  884. }
  885. /// <summary>
  886. /// 根据类型获取所有相同类型的组件
  887. /// </summary>
  888. public T[] GetComponents<T>() where T : Component
  889. {
  890. var list = new List<T>();
  891. for (int i = 0; i < _components.Count; i++)
  892. {
  893. var temp = _components[i];
  894. if (temp.Value is T component)
  895. {
  896. list.Add(component);
  897. }
  898. }
  899.  
  900. if (_updatingComp)
  901. {
  902. for (var i = 0; i < _changeComponents.Count; i++)
  903. {
  904. var temp = _components[i];
  905. if (temp.Value is T component)
  906. {
  907. list.Add(component);
  908. }
  909. }
  910. }
  911.  
  912. return list.ToArray();
  913. }
  914. /// <summary>
  915. /// 设置混色材质的颜色
  916. /// </summary>
  917. public void SetBlendColor(Color color)
  918. {
  919. _blendShaderMaterial?.SetShaderParameter("blend", color);
  920. }
  921.  
  922. /// <summary>
  923. /// 获取混色材质的颜色
  924. /// </summary>
  925. public Color GetBlendColor()
  926. {
  927. if (_blendShaderMaterial == null)
  928. {
  929. return Colors.White;
  930. }
  931. return _blendShaderMaterial.GetShaderParameter("blend").AsColor();
  932. }
  933. /// <summary>
  934. /// 设置混色材质的强度
  935. /// </summary>
  936. public void SetBlendSchedule(float value)
  937. {
  938. _blendShaderMaterial?.SetShaderParameter("schedule", value);
  939. }
  940.  
  941. /// <summary>
  942. /// 获取混色材质的强度
  943. /// </summary>
  944. public float GetBlendSchedule()
  945. {
  946. if (_blendShaderMaterial == null)
  947. {
  948. return default;
  949. }
  950. return _blendShaderMaterial.GetShaderParameter("schedule").AsSingle();
  951. }
  952.  
  953. /// <summary>
  954. /// 设置混色颜色
  955. /// </summary>
  956. public void SetBlendModulate(Color color)
  957. {
  958. _blendShaderMaterial?.SetShaderParameter("modulate", color);
  959. _shadowBlendShaderMaterial?.SetShaderParameter("modulate", color);
  960. }
  961. /// <summary>
  962. /// 获取混色颜色
  963. /// </summary>
  964. public Color SetBlendModulate()
  965. {
  966. if (_blendShaderMaterial == null)
  967. {
  968. return Colors.White;
  969. }
  970. return _blendShaderMaterial.GetShaderParameter("modulate").AsColor();
  971. }
  972. /// <summary>
  973. /// 每帧调用一次, 为了防止子类覆盖 _Process(), 给 _Process() 加上了 sealed, 子类需要帧循环函数请重写 Process() 函数
  974. /// </summary>
  975. public sealed override void _Process(double delta)
  976. {
  977. #if TOOLS
  978. if (Engine.IsEditorHint())
  979. {
  980. return;
  981. }
  982. #endif
  983. var newDelta = (float)delta;
  984. if (EnableCustomBehavior)
  985. {
  986. Process(newDelta);
  987. }
  988. //更新组件
  989. if (_components.Count > 0)
  990. {
  991. _updatingComp = true;
  992. if (EnableCustomBehavior) //启用所有组件
  993. {
  994. for (int i = 0; i < _components.Count; i++)
  995. {
  996. if (IsDestroyed) return;
  997. var temp = _components[i].Value;
  998. if (temp != null && temp.Enable)
  999. {
  1000. temp.Process(newDelta);
  1001. }
  1002. }
  1003. }
  1004. else //只更新 MoveController 组件
  1005. {
  1006. if (MoveController.Enable)
  1007. {
  1008. MoveController.Process(newDelta);
  1009. }
  1010. }
  1011. _updatingComp = false;
  1012. if (_changeComponents.Count > 0)
  1013. {
  1014. RefreshComponent();
  1015. }
  1016. }
  1017.  
  1018. // 更新下坠处理逻辑
  1019. UpdateFall(newDelta);
  1020.  
  1021. //阴影
  1022. UpdateShadowSprite(newDelta);
  1023. // Hit 动画
  1024. if (_playHit)
  1025. {
  1026. if (_playHitSchedule < 0.05f)
  1027. {
  1028. _blendShaderMaterial?.SetShaderParameter("schedule", 1);
  1029. }
  1030. else if (_playHitSchedule < 0.15f)
  1031. {
  1032. _blendShaderMaterial?.SetShaderParameter("schedule", Mathf.Lerp(1, 0, (_playHitSchedule - 0.05f) / 0.1f));
  1033. }
  1034. if (_playHitSchedule >= 0.15f)
  1035. {
  1036. _blendShaderMaterial?.SetShaderParameter("schedule", 0);
  1037. _playHitSchedule = 0;
  1038. _playHit = false;
  1039. }
  1040. else
  1041. {
  1042. _playHitSchedule += newDelta;
  1043. }
  1044. }
  1045. //协程更新
  1046. ProxyCoroutineHandler.ProxyUpdateCoroutine(ref _coroutineList, newDelta);
  1047. //调试绘制
  1048. if (IsDebug)
  1049. {
  1050. QueueRedraw();
  1051. }
  1052. }
  1053.  
  1054. /// <summary>
  1055. /// 更新下坠处理逻辑
  1056. /// </summary>
  1057. public void UpdateFall(float delta)
  1058. {
  1059. // 下坠判定
  1060. if (Altitude > 0 || VerticalSpeed != 0)
  1061. {
  1062. if (_isFallOver) // 没有处于下坠状态, 则进入下坠状态
  1063. {
  1064. InitThrowData();
  1065. }
  1066. else
  1067. {
  1068. if (EnableVerticalMotion) //如果启用了纵向运动, 则更新运动
  1069. {
  1070. //GlobalRotationDegrees = GlobalRotationDegrees + ThrowRotationDegreesSpeed * newDelta;
  1071.  
  1072. var ysp = VerticalSpeed;
  1073.  
  1074. _altitude += VerticalSpeed * delta;
  1075. _verticalSpeed -= GameConfig.G * ActivityMaterial.GravityScale * delta;
  1076.  
  1077. //当高度大于16时, 显示在所有物体上, 并且关闭碰撞
  1078. if (Altitude >= 16)
  1079. {
  1080. AnimatedSprite.ZIndex = 20;
  1081. }
  1082. else
  1083. {
  1084. AnimatedSprite.ZIndex = 0;
  1085. }
  1086. //动态开关碰撞器
  1087. if (ActivityMaterial.DynamicCollision)
  1088. {
  1089. Collision.Disabled = Altitude >= 16;
  1090. }
  1091. //达到最高点
  1092. if (ysp > 0 && ysp * VerticalSpeed < 0)
  1093. {
  1094. OnThrowMaxHeight(Altitude);
  1095. }
  1096.  
  1097. //落地判断
  1098. if (Altitude <= 0)
  1099. {
  1100. _altitude = 0;
  1101.  
  1102. //第一次接触地面
  1103. if (_firstFall)
  1104. {
  1105. _firstFall = false;
  1106. OnFirstFallToGround();
  1107. }
  1108.  
  1109. if (_throwForce != null)
  1110. {
  1111. //缩放移动速度
  1112. //MoveController.ScaleAllForce(BounceSpeed);
  1113. _throwForce.Velocity *= ActivityMaterial.FallBounceSpeed;
  1114. //缩放旋转速度
  1115. //MoveController.ScaleAllRotationSpeed(BounceStrength);
  1116. _throwForce.RotationSpeed *= ActivityMaterial.FallBounceRotation;
  1117. }
  1118. //如果落地高度不够低, 再抛一次
  1119. if (ActivityMaterial.Bounce && (!_hasResilienceVerticalSpeed || _resilienceVerticalSpeed > 5))
  1120. {
  1121. if (!_hasResilienceVerticalSpeed)
  1122. {
  1123. _hasResilienceVerticalSpeed = true;
  1124. _resilienceVerticalSpeed = -VerticalSpeed * ActivityMaterial.FallBounceStrength;
  1125. }
  1126. else
  1127. {
  1128. if (_resilienceVerticalSpeed < 25)
  1129. {
  1130. _resilienceVerticalSpeed = _resilienceVerticalSpeed * ActivityMaterial.FallBounceStrength * 0.4f;
  1131. }
  1132. else
  1133. {
  1134. _resilienceVerticalSpeed = _resilienceVerticalSpeed * ActivityMaterial.FallBounceStrength;
  1135. }
  1136. }
  1137. _verticalSpeed = _resilienceVerticalSpeed;
  1138. _isFallOver = false;
  1139.  
  1140. OnFallToGround();
  1141. }
  1142. else //结束
  1143. {
  1144. _verticalSpeed = 0;
  1145.  
  1146. if (_throwForce != null)
  1147. {
  1148. MoveController.RemoveForce(_throwForce);
  1149. _throwForce = null;
  1150. }
  1151. _isFallOver = true;
  1152. OnFallToGround();
  1153. ThrowOver();
  1154. }
  1155. }
  1156. }
  1157.  
  1158. //计算精灵位置
  1159. CalcThrowAnimatedPosition();
  1160. }
  1161. }
  1162.  
  1163. }
  1164.  
  1165. /// <summary>
  1166. /// 更新阴影逻辑
  1167. /// </summary>
  1168. public void UpdateShadowSprite(float delta)
  1169. {
  1170. // 阴影
  1171. if (ShadowSprite.Visible)
  1172. {
  1173. if (!IsCustomShadowSprite)
  1174. {
  1175. //更新阴影贴图, 使其和动画一致
  1176. var anim = AnimatedSprite.Animation;
  1177. var frame = AnimatedSprite.Frame;
  1178. if (_prevAnimation != anim || _prevAnimationFrame != frame)
  1179. {
  1180. //切换阴影动画
  1181. ShadowSprite.Texture = AnimatedSprite.SpriteFrames.GetFrameTexture(anim, AnimatedSprite.Frame);
  1182. }
  1183.  
  1184. _prevAnimation = anim;
  1185. _prevAnimationFrame = frame;
  1186. }
  1187.  
  1188. if (_freezeSprite == null || !_freezeSprite.IsFrozen)
  1189. {
  1190. //计算阴影
  1191. CalcShadowTransform();
  1192. }
  1193. }
  1194.  
  1195. }
  1196. /// <summary>
  1197. /// 每物理帧调用一次, 为了防止子类覆盖 _PhysicsProcess(), 给 _PhysicsProcess() 加上了 sealed, 子类需要帧循环函数请重写 PhysicsProcess() 函数
  1198. /// </summary>
  1199. public sealed override void _PhysicsProcess(double delta)
  1200. {
  1201. #if TOOLS
  1202. if (Engine.IsEditorHint())
  1203. {
  1204. return;
  1205. }
  1206. #endif
  1207. var newDelta = (float)delta;
  1208. if (EnableCustomBehavior)
  1209. {
  1210. PhysicsProcess(newDelta);
  1211. }
  1212. //更新组件
  1213. if (_components.Count > 0)
  1214. {
  1215. _updatingComp = true;
  1216. if (EnableCustomBehavior) //启用所有组件
  1217. {
  1218. for (int i = 0; i < _components.Count; i++)
  1219. {
  1220. if (IsDestroyed) return;
  1221. var temp = _components[i].Value;
  1222. if (temp != null && temp.Enable)
  1223. {
  1224. temp.PhysicsProcess(newDelta);
  1225. }
  1226. }
  1227. }
  1228. else //只更新 MoveController 组件
  1229. {
  1230. if (MoveController.Enable)
  1231. {
  1232. MoveController.PhysicsProcess(newDelta);
  1233. }
  1234. }
  1235. _updatingComp = false;
  1236.  
  1237. if (_changeComponents.Count > 0)
  1238. {
  1239. RefreshComponent();
  1240. }
  1241. }
  1242. }
  1243.  
  1244. //更新新增/移除的组件
  1245. private void RefreshComponent()
  1246. {
  1247. for (var i = 0; i < _changeComponents.Count; i++)
  1248. {
  1249. var item = _changeComponents[i];
  1250. if (item.Value) //添加组件
  1251. {
  1252. _components.Add(new KeyValuePair<Type, Component>(item.Key.GetType(), item.Key));
  1253. }
  1254. else //移除组件
  1255. {
  1256. for (var j = 0; j < _components.Count; j++)
  1257. {
  1258. if (_components[i].Value == item.Key)
  1259. {
  1260. _components.RemoveAt(i);
  1261. break;
  1262. }
  1263. }
  1264. }
  1265. }
  1266. }
  1267.  
  1268. /// <summary>
  1269. /// 绘制函数, 子类不允许重写, 需要绘制函数请重写 DebugDraw()
  1270. /// </summary>
  1271. public sealed override void _Draw()
  1272. {
  1273. #if TOOLS
  1274. if (Engine.IsEditorHint())
  1275. {
  1276. return;
  1277. }
  1278. #endif
  1279. if (IsDebug)
  1280. {
  1281. DebugDraw();
  1282. if (_components.Count > 0)
  1283. {
  1284. var arr = _components.ToArray();
  1285. for (int i = 0; i < arr.Length; i++)
  1286. {
  1287. if (IsDestroyed) return;
  1288. var temp = arr[i].Value;
  1289. if (temp != null && temp.Master == this && temp.Enable)
  1290. {
  1291. temp.DebugDraw();
  1292. }
  1293. }
  1294. }
  1295. }
  1296. }
  1297.  
  1298. /// <summary>
  1299. /// 重新计算物体阴影的位置和旋转信息, 无论是否显示阴影
  1300. /// </summary>
  1301. public void CalcShadowTransform()
  1302. {
  1303. //偏移
  1304. if (!IsCustomShadowSprite)
  1305. {
  1306. ShadowSprite.Offset = AnimatedSprite.Offset;
  1307. }
  1308.  
  1309. //缩放
  1310. ShadowSprite.Scale = AnimatedSprite.Scale;
  1311. //阴影角度
  1312. ShadowSprite.Rotation = 0;
  1313. //阴影位置计算
  1314. var pos = AnimatedSprite.GlobalPosition;
  1315. ShadowSprite.GlobalPosition = new Vector2(pos.X + ShadowOffset.X, pos.Y + ShadowOffset.Y + Altitude);
  1316. }
  1317.  
  1318. //计算位置
  1319. private void CalcThrowAnimatedPosition()
  1320. {
  1321. if (Scale.Y < 0)
  1322. {
  1323. var pos = new Vector2(_fallData.OriginSpritePosition.X, -_fallData.OriginSpritePosition.Y);
  1324. AnimatedSprite.GlobalPosition = GlobalPosition + new Vector2(0, -Altitude) - pos.Rotated(Rotation + Mathf.Pi);
  1325. }
  1326. else
  1327. {
  1328. AnimatedSprite.GlobalPosition = GlobalPosition + new Vector2(0, -Altitude) + _fallData.OriginSpritePosition.Rotated(Rotation);
  1329. }
  1330. }
  1331.  
  1332.  
  1333. /// <summary>
  1334. /// 销毁物体
  1335. /// </summary>
  1336. public void Destroy()
  1337. {
  1338. if (IsDestroyed)
  1339. {
  1340. return;
  1341. }
  1342.  
  1343. IsDestroyed = true;
  1344. if (AffiliationArea != null)
  1345. {
  1346. AffiliationArea.RemoveItem(this);
  1347. }
  1348. QueueFree();
  1349. OnDestroy();
  1350.  
  1351. if (_freezeSprite != null)
  1352. {
  1353. _freezeSprite.Destroy();
  1354. }
  1355. var arr = _components.ToArray();
  1356. for (var i = 0; i < arr.Length; i++)
  1357. {
  1358. arr[i].Value?.Destroy();
  1359. }
  1360.  
  1361. _components.Clear();
  1362. }
  1363.  
  1364. /// <summary>
  1365. /// 延时销毁
  1366. /// </summary>
  1367. public void DelayDestroy()
  1368. {
  1369. CallDeferred(nameof(Destroy));
  1370. }
  1371.  
  1372. /// <summary>
  1373. /// 继承指定物体的运动速率
  1374. /// </summary>
  1375. /// <param name="other">目标对象</param>
  1376. /// <param name="scale">继承的速率缩放</param>
  1377. public void InheritVelocity(ActivityObject other, float scale = 0.5f)
  1378. {
  1379. MoveController.AddVelocity(other.Velocity * scale);
  1380. }
  1381.  
  1382. /// <summary>
  1383. /// 触发投抛动作
  1384. /// </summary>
  1385. private void Throw()
  1386. {
  1387. var parent = GetParent();
  1388. //投抛时必须要加入 YSortLayer 节点下
  1389. if (parent == null)
  1390. {
  1391. this.AddToActivityRoot(RoomLayerEnum.YSortLayer);
  1392. }
  1393. else if (parent == GameApplication.Instance.World.NormalLayer)
  1394. {
  1395. parent.RemoveChild(this);
  1396. this.AddToActivityRoot(RoomLayerEnum.YSortLayer);
  1397. }
  1398.  
  1399. CalcThrowAnimatedPosition();
  1400. //显示阴影
  1401. ShowShadowSprite();
  1402.  
  1403. if (EnableVerticalMotion)
  1404. {
  1405. OnThrowStart();
  1406. }
  1407. }
  1408.  
  1409. /// <summary>
  1410. /// 设置下坠状态下的碰撞器
  1411. /// </summary>
  1412. private void SetFallCollision()
  1413. {
  1414. if (_fallData != null && _fallData.UseOrigin)
  1415. {
  1416. _fallData.OriginShape = Collision.Shape;
  1417. _fallData.OriginPosition = Collision.Position;
  1418. _fallData.OriginRotation = Collision.Rotation;
  1419. _fallData.OriginScale = Collision.Scale;
  1420. _fallData.OriginZIndex = ZIndex;
  1421. _fallData.OriginSpritePosition = AnimatedSprite.Position;
  1422. _fallData.OriginCollisionEnable = Collision.Disabled;
  1423. _fallData.OriginCollisionPosition = Collision.Position;
  1424. _fallData.OriginCollisionRotation = Collision.Rotation;
  1425. _fallData.OriginCollisionScale = Collision.Scale;
  1426. _fallData.OriginCollisionMask = CollisionMask;
  1427. _fallData.OriginCollisionLayer = CollisionLayer;
  1428.  
  1429. if (_throwRectangleShape == null)
  1430. {
  1431. _throwRectangleShape = new RectangleShape2D();
  1432. }
  1433. Collision.Shape = _throwRectangleShape;
  1434. Collision.Position = Vector2.Zero;
  1435. Collision.Rotation = 0;
  1436. Collision.Scale = Vector2.One;
  1437. ZIndex = 0;
  1438. Collision.Disabled = false;
  1439. Collision.Position = Vector2.Zero;
  1440. Collision.Rotation = 0;
  1441. Collision.Scale = Vector2.One;
  1442. CollisionMask = 1;
  1443. CollisionLayer = _fallData.OriginCollisionLayer | PhysicsLayer.Throwing;
  1444. _fallData.UseOrigin = false;
  1445. }
  1446. }
  1447.  
  1448. /// <summary>
  1449. /// 重置碰撞器
  1450. /// </summary>
  1451. private void RestoreCollision()
  1452. {
  1453. if (_fallData != null && !_fallData.UseOrigin)
  1454. {
  1455. Collision.Shape = _fallData.OriginShape;
  1456. Collision.Position = _fallData.OriginPosition;
  1457. Collision.Rotation = _fallData.OriginRotation;
  1458. Collision.Scale = _fallData.OriginScale;
  1459. ZIndex = _fallData.OriginZIndex;
  1460. AnimatedSprite.Position = _fallData.OriginSpritePosition;
  1461. Collision.Disabled = _fallData.OriginCollisionEnable;
  1462. Collision.Position = _fallData.OriginCollisionPosition;
  1463. Collision.Rotation = _fallData.OriginCollisionRotation;
  1464. Collision.Scale = _fallData.OriginCollisionScale;
  1465. CollisionMask = _fallData.OriginCollisionMask;
  1466. CollisionLayer = _fallData.OriginCollisionLayer;
  1467.  
  1468. _fallData.UseOrigin = true;
  1469. }
  1470. }
  1471.  
  1472. /// <summary>
  1473. /// 投抛结束
  1474. /// </summary>
  1475. private void ThrowOver()
  1476. {
  1477. var parent = GetParent();
  1478. var roomLayer = GameApplication.Instance.World.GetRoomLayer(_currLayer);
  1479. if (parent != roomLayer)
  1480. {
  1481. parent.RemoveChild(this);
  1482. roomLayer.AddChild(this);
  1483. }
  1484. RestoreCollision();
  1485.  
  1486. OnThrowOver();
  1487. }
  1488.  
  1489. //初始化投抛状态数据
  1490. private void InitThrowData()
  1491. {
  1492. SetFallCollision();
  1493.  
  1494. _isFallOver = false;
  1495. _firstFall = true;
  1496. _hasResilienceVerticalSpeed = false;
  1497. _resilienceVerticalSpeed = 0;
  1498. if (ThrowCollisionSize.X < 0 && ThrowCollisionSize.Y < 0)
  1499. {
  1500. _throwRectangleShape.Size = GetDefaultTexture().GetSize();
  1501. }
  1502. else
  1503. {
  1504. _throwRectangleShape.Size = ThrowCollisionSize;
  1505. }
  1506.  
  1507. Throw();
  1508. }
  1509.  
  1510. /// <summary>
  1511. /// 设置标记, 用于在物体上记录自定义数据
  1512. /// </summary>
  1513. /// <param name="name">标记名称</param>
  1514. /// <param name="v">存入值</param>
  1515. public void SetSign(string name, object v)
  1516. {
  1517. if (_signMap == null)
  1518. {
  1519. _signMap = new Dictionary<string, object>();
  1520. }
  1521.  
  1522. _signMap[name] = v;
  1523. }
  1524.  
  1525. /// <summary>
  1526. /// 返回是否存在指定名称的标记数据
  1527. /// </summary>
  1528. public bool HasSign(string name)
  1529. {
  1530. return _signMap == null ? false : _signMap.ContainsKey(name);
  1531. }
  1532.  
  1533. /// <summary>
  1534. /// 根据名称获取标记值
  1535. /// </summary>
  1536. public object GetSign(string name)
  1537. {
  1538. if (_signMap == null)
  1539. {
  1540. return null;
  1541. }
  1542.  
  1543. _signMap.TryGetValue(name, out var value);
  1544. return value;
  1545. }
  1546.  
  1547. /// <summary>
  1548. /// 根据名称获取标记值
  1549. /// </summary>
  1550. public T GetSign<T>(string name)
  1551. {
  1552. if (_signMap == null)
  1553. {
  1554. return default;
  1555. }
  1556.  
  1557. _signMap.TryGetValue(name, out var value);
  1558. if (value is T v)
  1559. {
  1560. return v;
  1561. }
  1562. return default;
  1563. }
  1564.  
  1565. /// <summary>
  1566. /// 根据名称删除标记
  1567. /// </summary>
  1568. public void RemoveSign(string name)
  1569. {
  1570. if (_signMap != null)
  1571. {
  1572. _signMap.Remove(name);
  1573. }
  1574. }
  1575.  
  1576. /// <summary>
  1577. /// 播放受伤动画, 该动画不与 Animation 节点的动画冲突
  1578. /// </summary>
  1579. public void PlayHitAnimation()
  1580. {
  1581. _playHit = true;
  1582. _playHitSchedule = 0;
  1583. }
  1584.  
  1585. /// <summary>
  1586. /// 获取当前摩擦力
  1587. /// </summary>
  1588. public float GetCurrentFriction()
  1589. {
  1590. return ActivityMaterial.Friction;
  1591. }
  1592. /// <summary>
  1593. /// 获取当前旋转摩擦力
  1594. /// </summary>
  1595. public float GetCurrentRotationFriction()
  1596. {
  1597. return ActivityMaterial.RotationFriction;
  1598. }
  1599. public long StartCoroutine(IEnumerator able)
  1600. {
  1601. return ProxyCoroutineHandler.ProxyStartCoroutine(ref _coroutineList, able);
  1602. }
  1603. public void StopCoroutine(long coroutineId)
  1604. {
  1605. ProxyCoroutineHandler.ProxyStopCoroutine(ref _coroutineList, coroutineId);
  1606. }
  1607.  
  1608. public bool IsCoroutineOver(long coroutineId)
  1609. {
  1610. return ProxyCoroutineHandler.ProxyIsCoroutineOver(ref _coroutineList, coroutineId);
  1611. }
  1612.  
  1613. public void StopAllCoroutine()
  1614. {
  1615. ProxyCoroutineHandler.ProxyStopAllCoroutine(ref _coroutineList);
  1616. }
  1617. /// <summary>
  1618. /// 播放 AnimatedSprite 上的动画, 如果没有这个动画, 则什么也不会发生
  1619. /// </summary>
  1620. /// <param name="name">动画名称</param>
  1621. public void PlaySpriteAnimation(string name)
  1622. {
  1623. var spriteFrames = AnimatedSprite.SpriteFrames;
  1624. if (spriteFrames != null && spriteFrames.HasAnimation(name))
  1625. {
  1626. AnimatedSprite.Play(name);
  1627. }
  1628. }
  1629.  
  1630. /// <summary>
  1631. /// 将当前 ActivityObject 变成静态图像绘制到地面上, 用于优化渲染大量物体<br/>
  1632. /// 调用该函数后会排队进入渲染队列, 并且禁用所有行为, 当渲染完成后会销毁当前对象, 也就是调用 Destroy() 函数<br/>
  1633. /// </summary>
  1634. public void BecomesStaticImage()
  1635. {
  1636. if (_processingBecomesStaticImage)
  1637. {
  1638. return;
  1639. }
  1640. if (AffiliationArea == null)
  1641. {
  1642. Debug.LogError($"调用函数: BecomesStaticImage() 失败, 物体{Name}没有归属区域, 无法确定绘制到哪个ImageCanvas上, 直接执行销毁");
  1643. Destroy();
  1644. return;
  1645. }
  1646.  
  1647. _processingBecomesStaticImage = true;
  1648. EnableBehavior = false;
  1649. var roomInfo = AffiliationArea.RoomInfo;
  1650. var position = roomInfo.ToCanvasPosition(GlobalPosition);
  1651. roomInfo.StaticImageCanvas.DrawActivityObjectInCanvas(this, position.X, position.Y, () =>
  1652. {
  1653. Destroy();
  1654. });
  1655. }
  1656.  
  1657. /// <summary>
  1658. /// 是否正在处理成为静态图片
  1659. /// </summary>
  1660. public bool IsProcessingBecomesStaticImage()
  1661. {
  1662. return _processingBecomesStaticImage;
  1663. }
  1664. /// <summary>
  1665. /// 冻结物体,多余的节点就会被移出场景树,逻辑也会被暂停,用于优化性能
  1666. /// </summary>
  1667. public void Freeze()
  1668. {
  1669. if (_freezeSprite == null)
  1670. {
  1671. _freezeSprite = new FreezeSprite(this);
  1672. }
  1673. _freezeSprite.Freeze();
  1674. }
  1675.  
  1676. /// <summary>
  1677. /// 解冻物体, 恢复正常逻辑
  1678. /// </summary>
  1679. public void Unfreeze()
  1680. {
  1681. if (_freezeSprite == null)
  1682. {
  1683. return;
  1684. }
  1685. _freezeSprite.Unfreeze();
  1686. }
  1687.  
  1688. /// <summary>
  1689. /// 获取中心点坐标
  1690. /// </summary>
  1691. public Vector2 GetCenterPosition()
  1692. {
  1693. return AnimatedSprite.Position + Position;
  1694. }
  1695.  
  1696. /// <summary>
  1697. /// 设置物体朝向
  1698. /// </summary>
  1699. public void SetForwardDirection(FaceDirection face)
  1700. {
  1701. if ((face == FaceDirection.Left && Scale.X > 0) || (face == FaceDirection.Right && Scale.X < 0))
  1702. {
  1703. Scale *= new Vector2(-1, 1);
  1704. }
  1705. }
  1706. /// <summary>
  1707. /// 添加一个击退力
  1708. /// </summary>
  1709. public void AddRepelForce(Vector2 velocity)
  1710. {
  1711. if (_repelForce == null)
  1712. {
  1713. _repelForce = new ExternalForce(ForceNames.Repel);
  1714. }
  1715.  
  1716. //不在 MoveController 中
  1717. if (_repelForce.MoveController == null)
  1718. {
  1719. _repelForce.Velocity = velocity;
  1720. MoveController.AddForce(_repelForce);
  1721. }
  1722. else
  1723. {
  1724. _repelForce.Velocity += velocity;
  1725. }
  1726. }
  1727.  
  1728. /// <summary>
  1729. /// 获取击退力
  1730. /// </summary>
  1731. public Vector2 GetRepelForce()
  1732. {
  1733. if (_repelForce == null || _repelForce.MoveController == null)
  1734. {
  1735. return Vector2.Zero;
  1736. }
  1737.  
  1738. return _repelForce.Velocity;
  1739. }
  1740.  
  1741. /// <summary>
  1742. /// 根据笔刷 id 在该物体位置绘制液体, 该 id 为 LiquidMaterial 表的 id<br/>
  1743. /// 需要清除记录的点就请将 BrushPrevPosition 置为 null
  1744. /// </summary>
  1745. public void DrawLiquid(string brushId)
  1746. {
  1747. if (AffiliationArea != null)
  1748. {
  1749. DrawLiquid(LiquidBrushManager.GetBrush(brushId));
  1750. }
  1751. }
  1752. /// <summary>
  1753. /// 根据笔刷数据在该物体位置绘制液体<br/>
  1754. /// 需要清除记录的点就请将 BrushPrevPosition 置为 null
  1755. /// </summary>
  1756. public void DrawLiquid(BrushImageData brush)
  1757. {
  1758. if (AffiliationArea != null)
  1759. {
  1760. var pos = AffiliationArea.RoomInfo.LiquidCanvas.ToLiquidCanvasPosition(Position);
  1761. AffiliationArea.RoomInfo.LiquidCanvas.DrawBrush(brush, BrushPrevPosition, pos, 0);
  1762. BrushPrevPosition = pos;
  1763. }
  1764. }
  1765. /// <summary>
  1766. /// 根据笔刷 id 在该物体位置绘制液体, 该 id 为 LiquidMaterial 表的 id<br/>
  1767. /// 需要清除记录的点就请将 BrushPrevPosition 置为 null
  1768. /// </summary>
  1769. public void DrawLiquid(string brushId, Vector2I offset)
  1770. {
  1771. if (AffiliationArea != null)
  1772. {
  1773. DrawLiquid(LiquidBrushManager.GetBrush(brushId), offset);
  1774. }
  1775. }
  1776. /// <summary>
  1777. /// 根据笔刷数据在该物体位置绘制液体<br/>
  1778. /// 需要清除记录的点就请将 BrushPrevPosition 置为 null
  1779. /// </summary>
  1780. public void DrawLiquid(BrushImageData brush, Vector2I offset)
  1781. {
  1782. if (AffiliationArea != null)
  1783. {
  1784. var pos = AffiliationArea.RoomInfo.LiquidCanvas.ToLiquidCanvasPosition(Position) + offset;
  1785. AffiliationArea.RoomInfo.LiquidCanvas.DrawBrush(brush, BrushPrevPosition, pos, 0);
  1786. BrushPrevPosition = pos;
  1787. }
  1788. }
  1789. }