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