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