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