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