Newer
Older
DungeonShooting / DungeonShooting_Godot / src / framework / ActivityObject.cs
  1.  
  2. using System;
  3. using System.Collections.Generic;
  4. using Godot;
  5. using Plugin;
  6.  
  7. /// <summary>
  8. /// 房间内活动物体基类
  9. /// </summary>
  10. public abstract partial class ActivityObject : CharacterBody2D
  11. {
  12. /// <summary>
  13. /// 是否是调试模式
  14. /// </summary>
  15. public static bool IsDebug { get; set; }
  16.  
  17. /// <summary>
  18. /// 当前物体类型id, 用于区分是否是同一种物体, 如果不是通过 ActivityObject.Create() 函数创建出来的对象那么 ItemId 为 null
  19. /// </summary>
  20. public string ItemId { get; private set; }
  21.  
  22. /// <summary>
  23. /// 是否放入 ySort 节点下
  24. /// </summary>
  25. public bool UseYSort { get; }
  26.  
  27. /// <summary>
  28. /// 当前物体显示的精灵图像, 节点名称必须叫 "AnimatedSprite2D", 类型为 AnimatedSprite2D
  29. /// </summary>
  30. public AnimatedSprite2D AnimatedSprite { get; }
  31.  
  32. /// <summary>
  33. /// 当前物体显示的阴影图像, 节点名称必须叫 "ShadowSprite", 类型为 Sprite2D
  34. /// </summary>
  35. public Sprite2D ShadowSprite { get; }
  36.  
  37. /// <summary>
  38. /// 当前物体碰撞器节点, 节点名称必须叫 "Collision", 类型为 CollisionShape2D
  39. /// </summary>
  40. public CollisionShape2D Collision { get; }
  41.  
  42. /// <summary>
  43. /// 动画播放器
  44. /// </summary>
  45. /// <value></value>
  46. public AnimationPlayer AnimationPlayer { get; }
  47.  
  48. /// <summary>
  49. /// 是否调用过 Destroy() 函数
  50. /// </summary>
  51. public bool IsDestroyed { get; private set; }
  52.  
  53. /// <summary>
  54. /// 是否正在投抛过程中
  55. /// </summary>
  56. public bool IsThrowing => _throwData != null && !_throwData.IsOver;
  57.  
  58. /// <summary>
  59. /// 阴影偏移
  60. /// </summary>
  61. public Vector2 ShadowOffset { get; protected set; } = new Vector2(0, 2);
  62. /// <summary>
  63. /// 移动控制器
  64. /// </summary>
  65. public MoveController MoveController { get; }
  66.  
  67. /// <summary>
  68. /// 物体移动基础速率
  69. /// </summary>
  70. public Vector2 BasisVelocity
  71. {
  72. get => MoveController.BasisVelocity;
  73. set => MoveController.BasisVelocity = value;
  74. }
  75. // /// <summary>
  76. // /// 这个速度就是玩家当前物理帧移动的真实速率, 该速度由物理帧循环更新, 并不会马上更新
  77. // /// 该速度就是 BasisVelocity + 外力总和
  78. // /// </summary>
  79. // public Vector2 Velocity => MoveController.Velocity;
  80.  
  81. //组件集合
  82. private List<KeyValuePair<Type, Component>> _components = new List<KeyValuePair<Type, Component>>();
  83. //是否初始化阴影
  84. private bool _initShadow;
  85. //上一帧动画名称
  86. private string _prevAnimation;
  87. //上一帧动画
  88. private int _prevAnimationFrame;
  89.  
  90. //播放 Hit 动画
  91. private bool _playHit;
  92. private float _playHitSchedule;
  93.  
  94. //混色shader材质
  95. private ShaderMaterial _blendShaderMaterial;
  96.  
  97. //存储投抛该物体时所产生的数据
  98. private ObjectThrowData _throwData;
  99.  
  100. //标记字典
  101. private Dictionary<string, object> _signMap;
  102.  
  103. public ActivityObject(string scenePath)
  104. {
  105. //加载预制体
  106. var tempPrefab = ResourceManager.Load<PackedScene>(scenePath);
  107. if (tempPrefab == null)
  108. {
  109. throw new Exception("创建 ActivityObject 没有找到指定挂载的预制体: " + scenePath);
  110. }
  111.  
  112. var tempNode = tempPrefab.Instantiate<ActivityObjectTemplate>();
  113. ZIndex = tempNode.z_index;
  114. CollisionLayer = tempNode.collision_layer;
  115. CollisionMask = tempNode.collision_mask;
  116. UseYSort = tempNode.UseYSort;
  117. Scale = tempNode.scale;
  118. Visible = tempNode.visible;
  119.  
  120. //移动子节点
  121. var count = tempNode.GetChildCount();
  122. for (int i = 0; i < count; i++)
  123. {
  124. var body = tempNode.GetChild(0);
  125. tempNode.RemoveChild(body);
  126. AddChild(body);
  127. switch (body.Name)
  128. {
  129. case "AnimatedSprite":
  130. AnimatedSprite = (AnimatedSprite2D)body;
  131. _blendShaderMaterial = AnimatedSprite.Material as ShaderMaterial;
  132. break;
  133. case "ShadowSprite":
  134. ShadowSprite = (Sprite2D)body;
  135. ShadowSprite.Visible = false;
  136. break;
  137. case "Collision":
  138. Collision = (CollisionShape2D)body;
  139. break;
  140. case "AnimationPlayer":
  141. AnimationPlayer = (AnimationPlayer)body;
  142. break;
  143. }
  144. }
  145.  
  146. MoveController = new MoveController();
  147. AddComponent(MoveController);
  148. }
  149.  
  150. /// <summary>
  151. /// 显示阴影
  152. /// </summary>
  153. public void ShowShadowSprite()
  154. {
  155. if (!_initShadow)
  156. {
  157. _initShadow = true;
  158. ShadowSprite.Material = ResourceManager.BlendMaterial;
  159. }
  160.  
  161. var anim = AnimatedSprite.Animation;
  162. var frame = AnimatedSprite.Frame;
  163. if (_prevAnimation != anim || _prevAnimationFrame != frame)
  164. {
  165. var frames = AnimatedSprite.SpriteFrames;
  166. if (frames.HasAnimation(anim))
  167. {
  168. //切换阴影动画
  169. ShadowSprite.Texture = frames.GetFrameTexture(anim, frame);
  170. }
  171. }
  172.  
  173. _prevAnimation = anim;
  174. _prevAnimationFrame = frame;
  175.  
  176. CalcShadow();
  177. ShadowSprite.Visible = true;
  178. }
  179.  
  180. /// <summary>
  181. /// 隐藏阴影
  182. /// </summary>
  183. public void HideShadowSprite()
  184. {
  185. ShadowSprite.Visible = false;
  186. }
  187.  
  188. /// <summary>
  189. /// 设置默认序列帧动画的第一帧
  190. /// </summary>
  191. public void SetDefaultTexture(Texture2D texture)
  192. {
  193. if (AnimatedSprite.SpriteFrames == null)
  194. {
  195. SpriteFrames spriteFrames = new SpriteFrames();
  196. AnimatedSprite.SpriteFrames = spriteFrames;
  197. spriteFrames.AddFrame("default", texture);
  198. }
  199. else
  200. {
  201. SpriteFrames spriteFrames = AnimatedSprite.SpriteFrames;
  202. spriteFrames.SetFrame("default", 0, texture);
  203. }
  204. AnimatedSprite.Play("default");
  205. }
  206.  
  207. /// <summary>
  208. /// 获取默认序列帧动画的第一帧
  209. /// </summary>
  210. public Texture2D GetDefaultTexture()
  211. {
  212. return AnimatedSprite.SpriteFrames.GetFrameTexture("default", 0);
  213. }
  214. /// <summary>
  215. /// 获取当前序列帧动画的 Texture2D
  216. /// </summary>
  217. public Texture2D GetCurrentTexture()
  218. {
  219. return AnimatedSprite.SpriteFrames.GetFrameTexture(AnimatedSprite.Name, AnimatedSprite.Frame);
  220. }
  221.  
  222. /// <summary>
  223. /// 返回是否能与其他ActivityObject互动
  224. /// </summary>
  225. /// <param name="master">触发者</param>
  226. public virtual CheckInteractiveResult CheckInteractive(ActivityObject master)
  227. {
  228. return new CheckInteractiveResult(this);
  229. }
  230.  
  231. /// <summary>
  232. /// 与其它ActivityObject互动时调用, 如果要检测是否能互动请 CheckInteractive() 函数, 如果直接调用该函数那么属于强制互动行为, 例如子弹碰到物体
  233. /// </summary>
  234. /// <param name="master">触发者</param>
  235. public virtual void Interactive(ActivityObject master)
  236. {
  237. }
  238.  
  239. /// <summary>
  240. /// 开始投抛该物体时调用
  241. /// </summary>
  242. protected virtual void OnThrowStart()
  243. {
  244. }
  245. /// <summary>
  246. /// 投抛该物体达到最高点时调用
  247. /// </summary>
  248. protected virtual void OnThrowMaxHeight(float height)
  249. {
  250. }
  251.  
  252. /// <summary>
  253. /// 投抛状态下第一次接触地面时调用, 之后的回弹落地将不会调用该函数
  254. /// </summary>
  255. protected virtual void OnFirstFallToGround()
  256. {
  257. }
  258.  
  259. /// <summary>
  260. /// 投抛状态下每次接触地面时调用
  261. /// </summary>
  262. protected virtual void OnFallToGround()
  263. {
  264. }
  265.  
  266. /// <summary>
  267. /// 投抛结束时调用
  268. /// </summary>
  269. protected virtual void OnThrowOver()
  270. {
  271. }
  272.  
  273. /// <summary>
  274. /// 当前物体销毁时调用, 销毁物体请调用 Destroy() 函数
  275. /// </summary>
  276. protected virtual void OnDestroy()
  277. {
  278. }
  279.  
  280. /// <summary>
  281. /// 每帧调用一次, 物体的 Process() 会在组件的 Process() 之前调用
  282. /// </summary>
  283. protected virtual void Process(float delta)
  284. {
  285. }
  286. /// <summary>
  287. /// 每物理帧调用一次, 物体的 PhysicsProcess() 会在组件的 PhysicsProcess() 之前调用
  288. /// </summary>
  289. protected virtual void PhysicsProcess(float delta)
  290. {
  291. }
  292. /// <summary>
  293. /// 如果开启 debug, 则每帧调用该函数, 可用于绘制文字线段等
  294. /// </summary>
  295. protected virtual void DebugDraw()
  296. {
  297. }
  298.  
  299. /// <summary>
  300. /// 拾起一个 node 节点
  301. /// </summary>
  302. public void Pickup()
  303. {
  304. var parent = GetParent();
  305. if (parent != null)
  306. {
  307. if (IsThrowing)
  308. {
  309. StopThrow();
  310. }
  311.  
  312. parent.RemoveChild(this);
  313. }
  314. }
  315.  
  316. /// <summary>
  317. /// 将一个节点扔到地上, 并设置显示的阴影
  318. /// </summary>
  319. public virtual void PutDown()
  320. {
  321. var parent = GetParent();
  322. var root = GameApplication.Instance.RoomManager.GetRoot(UseYSort);
  323. if (parent != root)
  324. {
  325. if (parent != null)
  326. {
  327. parent.RemoveChild(this);
  328. }
  329.  
  330. root.AddChild(this);
  331. }
  332.  
  333. if (IsInsideTree())
  334. {
  335. ShowShadowSprite();
  336. }
  337. else
  338. {
  339. //注意需要延时调用
  340. CallDeferred(nameof(ShowShadowSprite));
  341. }
  342. }
  343.  
  344. /// <summary>
  345. /// 将一个节点扔到地上, 并设置显示的阴影
  346. /// </summary>
  347. /// <param name="position">放置的位置</param>
  348. public void PutDown(Vector2 position)
  349. {
  350. PutDown();
  351. Position = position;
  352. }
  353.  
  354. /// <summary>
  355. /// 将该节点投抛出去
  356. /// </summary>
  357. /// <param name="size">碰撞器大小</param>
  358. /// <param name="start">起始坐标 (全局)</param>
  359. /// <param name="startHeight">起始高度</param>
  360. /// <param name="direction">投抛角度 (0-360)</param>
  361. /// <param name="xSpeed">移动速度</param>
  362. /// <param name="ySpeed">下坠速度</param>
  363. /// <param name="rotate">旋转速度</param>
  364. /// <param name="bounce">落地时是否回弹</param>
  365. /// <param name="bounceStrength">落地回弹力度, 1为不消耗能量, 值越小回弹力度越小</param>
  366. /// <param name="bounceSpeed">落地回弹后的速度, 1为不消速度, 值越小回弹速度消耗越大</param>
  367. public void Throw(Vector2 size, Vector2 start, float startHeight, float direction, float xSpeed,
  368. float ySpeed, float rotate, bool bounce = false, float bounceStrength = 0.5f, float bounceSpeed = 0.8f)
  369. {
  370. if (_throwData == null)
  371. {
  372. _throwData = new ObjectThrowData();
  373. }
  374.  
  375. SetThrowCollision();
  376.  
  377. _throwData.IsOver = false;
  378. _throwData.Size = size;
  379. _throwData.StartPosition = _throwData.CurrPosition = start;
  380. _throwData.Direction = direction;
  381. _throwData.XSpeed = xSpeed;
  382. _throwData.YSpeed = ySpeed;
  383. _throwData.StartXSpeed = xSpeed;
  384. _throwData.StartYSpeed = ySpeed;
  385. _throwData.RotateSpeed = rotate;
  386. _throwData.ThrowForce = MoveController.AddConstantForce("ThrowForce");
  387. _throwData.ThrowForce.Velocity =
  388. new Vector2(_throwData.XSpeed, 0).Rotated(_throwData.Direction * Mathf.Pi / 180);
  389. _throwData.Y = startHeight;
  390. _throwData.Bounce = bounce;
  391. _throwData.BounceStrength = bounceStrength;
  392. _throwData.BounceSpeed = bounceSpeed;
  393.  
  394. _throwData.RectangleShape.Size = _throwData.Size * 0.5f;
  395.  
  396. Throw();
  397. }
  398.  
  399. /// <summary>
  400. /// 强制停止投抛运动
  401. /// </summary>
  402. public void StopThrow()
  403. {
  404. _throwData.IsOver = true;
  405. RestoreCollision();
  406. }
  407.  
  408. /// <summary>
  409. /// 往当前物体上挂载一个组件
  410. /// </summary>
  411. /// <param name="component">组件对象</param>
  412. public void AddComponent(Component component)
  413. {
  414. if (!ContainsComponent(component))
  415. {
  416. _components.Add(new KeyValuePair<Type, Component>(component.GetType(), component));
  417. component._SetActivityObject(this);
  418. component.OnMount();
  419. }
  420. }
  421.  
  422. /// <summary>
  423. /// 移除一个组件
  424. /// </summary>
  425. /// <param name="component">组件对象</param>
  426. public void RemoveComponent(Component component)
  427. {
  428. for (int i = 0; i < _components.Count; i++)
  429. {
  430. if (_components[i].Value == component)
  431. {
  432. _components.RemoveAt(i);
  433. component.OnUnMount();
  434. component._SetActivityObject(null);
  435. return;
  436. }
  437. }
  438. }
  439.  
  440. /// <summary>
  441. /// 根据类型获取一个组件
  442. /// </summary>
  443. public Component GetComponent(Type type)
  444. {
  445. for (int i = 0; i < _components.Count; i++)
  446. {
  447. var temp = _components[i];
  448. if (temp.Key == type)
  449. {
  450. return temp.Value;
  451. }
  452. }
  453.  
  454. return null;
  455. }
  456.  
  457. /// <summary>
  458. /// 根据类型获取一个组件
  459. /// </summary>
  460. public TC GetComponent<TC>() where TC : Component
  461. {
  462. var component = GetComponent(typeof(TC));
  463. if (component == null) return null;
  464. return (TC)component;
  465. }
  466. /// <summary>
  467. /// 每帧调用一次, 为了防止子类覆盖 _Process(), 给 _Process() 加上了 sealed, 子类需要帧循环函数请重写 Process() 函数
  468. /// </summary>
  469. public sealed override void _Process(double delta)
  470. {
  471. var newDelta = (float)delta;
  472. Process(newDelta);
  473. //更新组件
  474. if (_components.Count > 0)
  475. {
  476. var arr = _components.ToArray();
  477. for (int i = 0; i < arr.Length; i++)
  478. {
  479. if (IsDestroyed) return;
  480. var temp = arr[i].Value;
  481. if (temp != null && temp.ActivityObject == this && temp.Enable)
  482. {
  483. if (!temp.IsReady)
  484. {
  485. temp.Ready();
  486. temp.IsReady = true;
  487. }
  488.  
  489. temp.Process(newDelta);
  490. }
  491. }
  492. }
  493.  
  494. //投抛计算
  495. if (_throwData != null && !_throwData.IsOver)
  496. {
  497. GlobalRotationDegrees = GlobalRotationDegrees + _throwData.RotateSpeed * newDelta;
  498. CalcThrowAnimatedPosition();
  499.  
  500. var ysp = _throwData.YSpeed;
  501.  
  502. _throwData.Y += _throwData.YSpeed * newDelta;
  503. _throwData.YSpeed -= GameConfig.G * newDelta;
  504.  
  505. //当高度大于16时, 显示在所有物体上
  506. if (_throwData.Y >= 16)
  507. {
  508. AnimatedSprite.ZIndex = 20;
  509. }
  510. else
  511. {
  512. AnimatedSprite.ZIndex = 0;
  513. }
  514. //达到最高点
  515. if (ysp * _throwData.YSpeed < 0)
  516. {
  517. OnThrowMaxHeight(_throwData.Y);
  518. }
  519.  
  520. //落地判断
  521. if (_throwData.Y <= 0)
  522. {
  523.  
  524. _throwData.IsOver = true;
  525.  
  526. //第一次接触地面
  527. if (_throwData.FirstOver)
  528. {
  529. _throwData.FirstOver = false;
  530. OnFirstFallToGround();
  531. }
  532.  
  533. //如果落地高度不够低, 再抛一次
  534. if (_throwData.StartYSpeed > 1 && _throwData.Bounce)
  535. {
  536. _throwData.StartPosition = Position;
  537. _throwData.Y = 0;
  538. _throwData.XSpeed = _throwData.StartXSpeed = _throwData.StartXSpeed * _throwData.BounceSpeed;
  539. _throwData.YSpeed = _throwData.StartYSpeed = _throwData.StartYSpeed * _throwData.BounceStrength;
  540. _throwData.RotateSpeed = _throwData.RotateSpeed * _throwData.BounceStrength;
  541. _throwData.ThrowForce.Velocity *= _throwData.BounceSpeed;
  542. _throwData.FirstOver = false;
  543. _throwData.IsOver = false;
  544.  
  545. OnFallToGround();
  546. }
  547. else //结束
  548. {
  549. OnFallToGround();
  550. ThrowOver();
  551. }
  552. }
  553. }
  554.  
  555. //阴影
  556. if (ShadowSprite.Visible)
  557. {
  558. //更新阴影贴图, 使其和动画一致
  559. var anim = AnimatedSprite.Animation;
  560. var frame = AnimatedSprite.Frame;
  561. if (_prevAnimation != anim || _prevAnimationFrame != frame)
  562. {
  563. //切换阴影动画
  564. ShadowSprite.Texture = AnimatedSprite.SpriteFrames.GetFrameTexture(anim, AnimatedSprite.Frame);
  565. }
  566.  
  567. _prevAnimation = anim;
  568. _prevAnimationFrame = frame;
  569.  
  570. //计算阴影
  571. CalcShadow();
  572. }
  573.  
  574. // Hit 动画
  575. if (_playHit && _blendShaderMaterial != null)
  576. {
  577. if (_playHitSchedule < 0.05f)
  578. {
  579. _blendShaderMaterial.SetShaderParameter("schedule", 1);
  580. }
  581. else if (_playHitSchedule < 0.15f)
  582. {
  583. _blendShaderMaterial.SetShaderParameter("schedule", Mathf.Lerp(1, 0, (_playHitSchedule - 0.05f) / 0.1f));
  584. }
  585. if (_playHitSchedule >= 0.15f)
  586. {
  587. _blendShaderMaterial.SetShaderParameter("schedule", 0);
  588. _playHitSchedule = 0;
  589. _playHit = false;
  590. }
  591. else
  592. {
  593. _playHitSchedule += newDelta;
  594. }
  595. }
  596. //调试绘制
  597. if (IsDebug)
  598. {
  599. QueueRedraw();
  600. }
  601. }
  602.  
  603. /// <summary>
  604. /// 每物理帧调用一次, 为了防止子类覆盖 _PhysicsProcess(), 给 _PhysicsProcess() 加上了 sealed, 子类需要帧循环函数请重写 PhysicsProcess() 函数
  605. /// </summary>
  606. public sealed override void _PhysicsProcess(double delta)
  607. {
  608. var newDelta = (float)delta;
  609. PhysicsProcess(newDelta);
  610. //更新组件
  611. if (_components.Count > 0)
  612. {
  613. var arr = _components.ToArray();
  614. for (int i = 0; i < arr.Length; i++)
  615. {
  616. if (IsDestroyed) return;
  617. var temp = arr[i].Value;
  618. if (temp != null && temp.ActivityObject == this && temp.Enable)
  619. {
  620. if (!temp.IsReady)
  621. {
  622. temp.Ready();
  623. temp.IsReady = true;
  624. }
  625.  
  626. temp.PhysicsProcess(newDelta);
  627. }
  628. }
  629. }
  630. }
  631.  
  632. /// <summary>
  633. /// 绘制函数, 子类不允许重写, 需要绘制函数请重写 DebugDraw()
  634. /// </summary>
  635. public sealed override void _Draw()
  636. {
  637. if (IsDebug)
  638. {
  639. DebugDraw();
  640. var arr = _components.ToArray();
  641. for (int i = 0; i < arr.Length; i++)
  642. {
  643. if (IsDestroyed) return;
  644. var temp = arr[i].Value;
  645. if (temp != null && temp.ActivityObject == this && temp.Enable)
  646. {
  647. temp.DebugDraw();
  648. }
  649. }
  650. }
  651. }
  652.  
  653. /// <summary>
  654. /// 重新计算物体阴影的位置和旋转信息, 无论是否显示阴影
  655. /// </summary>
  656. public void CalcShadow()
  657. {
  658. //缩放
  659. ShadowSprite.Scale = AnimatedSprite.Scale;
  660. //阴影角度
  661. ShadowSprite.Rotation = 0;
  662. //阴影位置计算
  663. var pos = AnimatedSprite.GlobalPosition;
  664. if (_throwData != null && !_throwData.IsOver)
  665. {
  666. ShadowSprite.GlobalPosition = new Vector2(pos.X + ShadowOffset.X, pos.Y + ShadowOffset.Y + _throwData.Y);
  667. }
  668. else
  669. {
  670. ShadowSprite.GlobalPosition = pos + ShadowOffset;
  671. }
  672. }
  673. //计算位置
  674. private void CalcThrowAnimatedPosition()
  675. {
  676. if (Scale.Y < 0)
  677. {
  678. AnimatedSprite.GlobalPosition = GlobalPosition + new Vector2(0, -_throwData.Y) - _throwData.OriginSpritePosition.Rotated(Rotation) * Scale.Abs();
  679. }
  680. else
  681. {
  682. AnimatedSprite.GlobalPosition = GlobalPosition + new Vector2(0, -_throwData.Y) + _throwData.OriginSpritePosition.Rotated(Rotation);
  683. }
  684. }
  685.  
  686.  
  687. /// <summary>
  688. /// 销毁物体
  689. /// </summary>
  690. public void Destroy()
  691. {
  692. if (IsDestroyed)
  693. {
  694. return;
  695. }
  696.  
  697. IsDestroyed = true;
  698.  
  699. OnDestroy();
  700. QueueFree();
  701. var arr = _components.ToArray();
  702. for (int i = 0; i < arr.Length; i++)
  703. {
  704. arr[i].Value?.Destroy();
  705. }
  706. }
  707.  
  708. /// <summary>
  709. /// 延时销毁
  710. /// </summary>
  711. public void DelayDestroy()
  712. {
  713. CallDeferred(nameof(Destroy));
  714. }
  715.  
  716. //返回该组件是否被挂载到当前物体上
  717. private bool ContainsComponent(Component component)
  718. {
  719. for (int i = 0; i < _components.Count; i++)
  720. {
  721. if (_components[i].Value == component)
  722. {
  723. return true;
  724. }
  725. }
  726.  
  727. return false;
  728. }
  729.  
  730. /// <summary>
  731. /// 触发投抛动作
  732. /// </summary>
  733. private void Throw()
  734. {
  735. var parent = GetParent();
  736. //投抛时必须要加入 sortRoot 节点下
  737. var root = GameApplication.Instance.RoomManager.GetRoot();
  738. var throwRoot = GameApplication.Instance.RoomManager.GetRoot(true);
  739. if (parent == null)
  740. {
  741. throwRoot.AddChild(this);
  742. }
  743. else if (parent == root)
  744. {
  745. parent.RemoveChild(this);
  746. throwRoot.AddChild(this);
  747. }
  748.  
  749. GlobalPosition = _throwData.StartPosition;
  750.  
  751. CalcThrowAnimatedPosition();
  752. //显示阴影
  753. ShowShadowSprite();
  754. OnThrowStart();
  755. }
  756.  
  757. /// <summary>
  758. /// 设置投抛状态下的碰撞器
  759. /// </summary>
  760. private void SetThrowCollision()
  761. {
  762. if (_throwData != null && _throwData.UseOrigin)
  763. {
  764. _throwData.OriginShape = Collision.Shape;
  765. _throwData.OriginPosition = Collision.Position;
  766. _throwData.OriginRotation = Collision.Rotation;
  767. _throwData.OriginScale = Collision.Scale;
  768. _throwData.OriginZIndex = ZIndex;
  769. _throwData.OriginSpritePosition = AnimatedSprite.Position;
  770. _throwData.OriginCollisionEnable = Collision.Disabled;
  771. _throwData.OriginCollisionPosition = Collision.Position;
  772. _throwData.OriginCollisionRotation = Collision.Rotation;
  773. _throwData.OriginCollisionScale = Collision.Scale;
  774. _throwData.OriginCollisionMask = CollisionMask;
  775. _throwData.OriginCollisionLayer = CollisionLayer;
  776.  
  777. if (_throwData.RectangleShape == null)
  778. {
  779. _throwData.RectangleShape = new RectangleShape2D();
  780. }
  781.  
  782. Collision.Shape = _throwData.RectangleShape;
  783. Collision.Position = Vector2.Zero;
  784. Collision.Rotation = 0;
  785. Collision.Scale = Vector2.One;
  786. ZIndex = 0;
  787. Collision.Disabled = false;
  788. Collision.Position = Vector2.Zero;
  789. Collision.Rotation = 0;
  790. Collision.Scale = Vector2.One;
  791. CollisionMask = 1;
  792. CollisionLayer = 0;
  793. _throwData.UseOrigin = false;
  794. }
  795. }
  796.  
  797. /// <summary>
  798. /// 重置碰撞器
  799. /// </summary>
  800. private void RestoreCollision()
  801. {
  802. if (_throwData != null && !_throwData.UseOrigin)
  803. {
  804. Collision.Shape = _throwData.OriginShape;
  805. Collision.Position = _throwData.OriginPosition;
  806. Collision.Rotation = _throwData.OriginRotation;
  807. Collision.Scale = _throwData.OriginScale;
  808. ZIndex = _throwData.OriginZIndex;
  809. AnimatedSprite.Position = _throwData.OriginSpritePosition;
  810. Collision.Disabled = _throwData.OriginCollisionEnable;
  811. Collision.Position = _throwData.OriginCollisionPosition;
  812. Collision.Rotation = _throwData.OriginCollisionRotation;
  813. Collision.Scale = _throwData.OriginCollisionScale;
  814. CollisionMask = _throwData.OriginCollisionMask;
  815. CollisionLayer = _throwData.OriginCollisionLayer;
  816.  
  817. _throwData.UseOrigin = true;
  818. }
  819. }
  820.  
  821. /// <summary>
  822. /// 投抛结束
  823. /// </summary>
  824. private void ThrowOver()
  825. {
  826. //移除投抛的力
  827. MoveController.RemoveForce(_throwData.ThrowForce);
  828. GetParent().RemoveChild(this);
  829. GameApplication.Instance.RoomManager.GetRoot(UseYSort).AddChild(this);
  830. RestoreCollision();
  831.  
  832. OnThrowOver();
  833. }
  834.  
  835. /// <summary>
  836. /// 设置标记, 用于在物体上记录自定义数据
  837. /// </summary>
  838. /// <param name="name">标记名称</param>
  839. /// <param name="v">存入值</param>
  840. public void SetSign(string name, object v)
  841. {
  842. if (_signMap == null)
  843. {
  844. _signMap = new Dictionary<string, object>();
  845. }
  846.  
  847. _signMap[name] = v;
  848. }
  849.  
  850. /// <summary>
  851. /// 返回是否存在指定名称的标记数据
  852. /// </summary>
  853. public bool HasSign(string name)
  854. {
  855. return _signMap == null ? false : _signMap.ContainsKey(name);
  856. }
  857.  
  858. /// <summary>
  859. /// 根据名称获取标记值
  860. /// </summary>
  861. public object GetSign(string name)
  862. {
  863. if (_signMap == null)
  864. {
  865. return null;
  866. }
  867.  
  868. _signMap.TryGetValue(name, out var value);
  869. return value;
  870. }
  871.  
  872. /// <summary>
  873. /// 根据名称获取标记值
  874. /// </summary>
  875. public T GetSign<T>(string name)
  876. {
  877. if (_signMap == null)
  878. {
  879. return default;
  880. }
  881.  
  882. _signMap.TryGetValue(name, out var value);
  883. if (value is T v)
  884. {
  885. return v;
  886. }
  887. return default;
  888. }
  889.  
  890. /// <summary>
  891. /// 根据名称删除标记
  892. /// </summary>
  893. public void RemoveSign(string name)
  894. {
  895. if (_signMap != null)
  896. {
  897. _signMap.Remove(name);
  898. }
  899. }
  900.  
  901. /// <summary>
  902. /// 播放受伤动画, 该动画不与 Animation 节点的动画冲突
  903. /// </summary>
  904. public void PlayHitAnimation()
  905. {
  906. _playHit = true;
  907. _playHitSchedule = 0;
  908. }
  909.  
  910. /// <summary>
  911. /// 通过 ItemId 实例化 ActivityObject 对象
  912. /// </summary>
  913. public static T Create<T>(string itemId) where T : ActivityObject
  914. {
  915. return null;
  916. }
  917. }