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