Newer
Older
DungeonShooting / DungeonShooting_Godot / src / game / item / weapon / Weapon.cs
@小李xl 小李xl on 3 Nov 2022 23 KB 像素化后解决ui问题
  1. using Godot;
  2. using System;
  3.  
  4. /// <summary>
  5. /// 武器的基类
  6. /// </summary>
  7. public abstract class Weapon : ActivityObject
  8. {
  9. /// <summary>
  10. /// 武器的唯一id
  11. /// </summary>
  12. public string Id { get; }
  13.  
  14. /// <summary>
  15. /// 开火回调事件
  16. /// </summary>
  17. public event Action<Weapon> FireEvent;
  18.  
  19. /// <summary>
  20. /// 属性数据
  21. /// </summary>
  22. public WeaponAttribute Attribute { get; private set; }
  23. /// <summary>
  24. /// 动画播放器
  25. /// </summary>
  26. /// <value></value>
  27. public AnimationPlayer AnimationPlayer { get; private set; }
  28.  
  29. /// <summary>
  30. /// 武器攻击的目标阵营
  31. /// </summary>
  32. public CampEnum TargetCamp { get; set; }
  33.  
  34. /// <summary>
  35. /// 该武器的拥有者
  36. /// </summary>
  37. public Role Master { get; private set; }
  38.  
  39. /// <summary>
  40. /// 当前弹夹弹药剩余量
  41. /// </summary>
  42. public int CurrAmmo { get; private set; }
  43. /// <summary>
  44. /// 剩余弹药量
  45. /// </summary>
  46. public int ResidueAmmo { get; private set; }
  47.  
  48. /// <summary>
  49. /// 武器管的开火点
  50. /// </summary>
  51. public Position2D FirePoint { get; private set; }
  52. /// <summary>
  53. /// 武器管的原点
  54. /// </summary>
  55. public Position2D OriginPoint { get; private set; }
  56. /// <summary>
  57. /// 弹壳抛出的点
  58. /// </summary>
  59. public Position2D ShellPoint { get; private set; }
  60. /// <summary>
  61. /// 碰撞器节点
  62. /// </summary>
  63. /// <value></value>
  64. public CollisionShape2D CollisionShape2D { get; private set; }
  65. /// <summary>
  66. /// 武器的当前散射半径
  67. /// </summary>
  68. public float CurrScatteringRange { get; private set; } = 0;
  69. /// <summary>
  70. /// 是否在换弹中
  71. /// </summary>
  72. /// <value></value>
  73. public bool Reloading { get; private set; } = false;
  74. /// <summary>
  75. /// 换弹计时器
  76. /// </summary>
  77. public float ReloadTimer { get; private set; } = 0;
  78. /// <summary>
  79. /// 换弹进度 (0 - 1)
  80. /// </summary>
  81. public float ReloadProgress
  82. {
  83. get
  84. {
  85. if (Attribute.AloneReload)
  86. {
  87. var num = 1f / Attribute.AmmoCapacity;
  88. return num * (Attribute.AmmoCapacity - CurrAmmo - 1) + num * (ReloadTimer / Attribute.ReloadTime);
  89. }
  90. return ReloadTimer / Attribute.ReloadTime;
  91. }
  92. }
  93.  
  94. //是否按下
  95. private bool triggerFlag = false;
  96. //扳机计时器
  97. private float triggerTimer = 0;
  98. //开火前延时时间
  99. private float delayedTime = 0;
  100. //开火间隙时间
  101. private float fireInterval = 0;
  102. //开火武器口角度
  103. private float fireAngle = 0;
  104. //攻击冷却计时
  105. private float attackTimer = 0;
  106. //攻击状态
  107. private bool attackFlag = false;
  108. //按下的时间
  109. private float downTimer = 0;
  110. //松开的时间
  111. private float upTimer = 0;
  112. //连发次数
  113. private float continuousCount = 0;
  114. //连发状态记录
  115. private bool continuousShootFlag = false;
  116.  
  117. /// <summary>
  118. /// 根据属性创建一把武器
  119. /// </summary>
  120. /// <param name="id">武器唯一id</param>
  121. /// <param name="attribute">属性</param>
  122. public Weapon(string id, WeaponAttribute attribute): base(attribute.WeaponPrefab)
  123. {
  124. Id = id;
  125. Attribute = attribute;
  126.  
  127. FirePoint = GetNode<Position2D>("WeaponBody/FirePoint");
  128. OriginPoint = GetNode<Position2D>("WeaponBody/OriginPoint");
  129. ShellPoint = GetNode<Position2D>("WeaponBody/ShellPoint");
  130. AnimationPlayer = GetNode<AnimationPlayer>("WeaponBody/AnimationPlayer");
  131. CollisionShape2D = GetNode<CollisionShape2D>("WeaponBody/Collision");
  132.  
  133. //更新图片
  134. var texture = ResourceLoader.Load<Texture>(Attribute.Sprite);
  135. SetDefaultTexture(texture);
  136. AnimatedSprite.Position = Attribute.CenterPosition;
  137.  
  138. //开火位置
  139. FirePoint.Position = new Vector2(Attribute.FirePosition.x, -Attribute.FirePosition.y);
  140. OriginPoint.Position = new Vector2(0, -Attribute.FirePosition.y);
  141.  
  142. //弹药量
  143. CurrAmmo = Attribute.AmmoCapacity;
  144. //剩余弹药量
  145. ResidueAmmo = Attribute.MaxAmmoCapacity - Attribute.AmmoCapacity;
  146. }
  147.  
  148. /// <summary>
  149. /// 当按下扳机时调用
  150. /// </summary>
  151. protected abstract void OnDownTrigger();
  152.  
  153. /// <summary>
  154. /// 当松开扳机时调用
  155. /// </summary>
  156. protected abstract void OnUpTrigger();
  157.  
  158. /// <summary>
  159. /// 单次开火时调用的函数
  160. /// </summary>
  161. protected abstract void OnFire();
  162.  
  163. /// <summary>
  164. /// 发射子弹时调用的函数, 每发射一枚子弹调用一次,
  165. /// 如果做霰弹武器效果, 一次开火发射5枚子弹, 则该函数调用5次
  166. /// </summary>
  167. protected abstract void OnShoot();
  168.  
  169. /// <summary>
  170. /// 当开始换弹时调用
  171. /// </summary>
  172. protected abstract void OnReload();
  173.  
  174. /// <summary>
  175. /// 当换弹完成时调用
  176. /// </summary>
  177. protected abstract void OnReloadFinish();
  178.  
  179. /// <summary>
  180. /// 当武器被拾起时调用
  181. /// </summary>
  182. /// <param name="master">拾起该武器的角色</param>
  183. protected abstract void OnPickUp(Role master);
  184.  
  185. /// <summary>
  186. /// 当武器从武器袋中移除时调用
  187. /// </summary>
  188. protected abstract void OnRemove();
  189.  
  190. /// <summary>
  191. /// 当武器被激活时调用, 也就是使用当武器是调用
  192. /// </summary>
  193. protected abstract void OnActive();
  194.  
  195. /// <summary>
  196. /// 当武器被收起时调用
  197. /// </summary>
  198. protected abstract void OnConceal();
  199.  
  200. public override void _Process(float delta)
  201. {
  202. base._Process(delta);
  203. if (Master == null) //这把武器被扔在地上
  204. {
  205. Reloading = false;
  206. ReloadTimer = 0;
  207. triggerTimer = triggerTimer > 0 ? triggerTimer - delta : 0;
  208. triggerFlag = false;
  209. attackFlag = false;
  210. attackTimer = attackTimer > 0 ? attackTimer - delta : 0;
  211. CurrScatteringRange = Mathf.Max(CurrScatteringRange - Attribute.ScatteringRangeBackSpeed * delta, Attribute.StartScatteringRange);
  212. continuousCount = 0;
  213. delayedTime = 0;
  214. }
  215. else if (Master.Holster.ActiveWeapon != this) //当前武器没有被使用
  216. {
  217. Reloading = false;
  218. ReloadTimer = 0;
  219. triggerTimer = triggerTimer > 0 ? triggerTimer - delta : 0;
  220. triggerFlag = false;
  221. attackFlag = false;
  222. attackTimer = attackTimer > 0 ? attackTimer - delta : 0;
  223. CurrScatteringRange = Mathf.Max(CurrScatteringRange - Attribute.ScatteringRangeBackSpeed * delta, Attribute.StartScatteringRange);
  224. continuousCount = 0;
  225. delayedTime = 0;
  226. }
  227. else //正在使用中
  228. {
  229.  
  230. //换弹
  231. if (Reloading)
  232. {
  233. ReloadTimer -= delta;
  234. if (ReloadTimer <= 0)
  235. {
  236. ReloadSuccess();
  237. }
  238. }
  239.  
  240. if (triggerFlag)
  241. {
  242. if (upTimer > 0) //第一帧按下扳机
  243. {
  244. upTimer = 0;
  245. DownTrigger();
  246. }
  247. downTimer += delta;
  248. }
  249. else
  250. {
  251. if (downTimer > 0) //第一帧松开扳机
  252. {
  253. downTimer = 0;
  254. UpTrigger();
  255. }
  256. upTimer += delta;
  257. }
  258.  
  259. // 攻击的计时器
  260. if (attackTimer > 0)
  261. {
  262. attackTimer -= delta;
  263. if (attackTimer < 0)
  264. {
  265. delayedTime += attackTimer;
  266. attackTimer = 0;
  267. }
  268. }
  269. else if (delayedTime > 0) //攻击延时
  270. {
  271. delayedTime -= delta;
  272. if (attackTimer < 0)
  273. {
  274. delayedTime = 0;
  275. }
  276. }
  277.  
  278. //连发判断
  279. if (continuousCount > 0 && delayedTime <= 0 && attackTimer <= 0)
  280. {
  281. //开火
  282. TriggerFire();
  283. }
  284.  
  285. if (!attackFlag && attackTimer <= 0)
  286. {
  287. CurrScatteringRange = Mathf.Max(CurrScatteringRange - Attribute.ScatteringRangeBackSpeed * delta, Attribute.StartScatteringRange);
  288. }
  289. triggerTimer = triggerTimer > 0 ? triggerTimer - delta : 0;
  290. triggerFlag = false;
  291. attackFlag = false;
  292.  
  293. //武器身回归
  294. Position = Position.MoveToward(Vector2.Zero, 35 * delta);
  295. if (fireInterval == 0)
  296. {
  297. RotationDegrees = 0;
  298. }
  299. else
  300. {
  301. RotationDegrees = Mathf.Lerp(0, fireAngle, attackTimer / fireInterval);
  302. }
  303. }
  304. }
  305.  
  306. /// <summary>
  307. /// 扳机函数, 调用即视为扣动扳机
  308. /// </summary>
  309. public void Trigger()
  310. {
  311. //是否第一帧按下
  312. var justDown = downTimer == 0;
  313. //是否能发射
  314. var flag = false;
  315. if (continuousCount <= 0) //不能处于连发状态下
  316. {
  317. if (Attribute.ContinuousShoot) //自动射击
  318. {
  319. if (triggerTimer > 0)
  320. {
  321. if (continuousShootFlag)
  322. {
  323. flag = true;
  324. }
  325. }
  326. else
  327. {
  328. flag = true;
  329. if (delayedTime <= 0 && attackTimer <= 0)
  330. {
  331. continuousShootFlag = true;
  332. }
  333. }
  334. }
  335. else //半自动
  336. {
  337. if (justDown && triggerTimer <= 0)
  338. {
  339. flag = true;
  340. }
  341. }
  342. }
  343.  
  344. if (flag)
  345. {
  346. var fireFlag = true; //是否能开火
  347. if (Reloading) //换弹中
  348. {
  349. if (CurrAmmo > 0 && Attribute.AloneReload && Attribute.AloneReloadCanShoot) //立即停止换弹
  350. {
  351. Reloading = false;
  352. ReloadTimer = 0;
  353. }
  354. else
  355. {
  356. fireFlag = false;
  357. }
  358. }
  359. else if (CurrAmmo <= 0)
  360. {
  361. fireFlag = false;
  362. //子弹不够
  363. _Reload();
  364. }
  365.  
  366. if (fireFlag)
  367. {
  368. if (justDown)
  369. {
  370. //开火前延时
  371. delayedTime = Attribute.DelayedTime;
  372. //扳机按下间隔
  373. triggerTimer = Attribute.TriggerInterval;
  374. //连发数量
  375. if (!Attribute.ContinuousShoot)
  376. {
  377. continuousCount = MathUtils.RandRangeInt(Attribute.MinContinuousCount, Attribute.MaxContinuousCount);
  378. }
  379. }
  380. if (delayedTime <= 0 && attackTimer <= 0)
  381. {
  382. TriggerFire();
  383. }
  384. attackFlag = true;
  385. }
  386.  
  387. }
  388. triggerFlag = true;
  389. }
  390.  
  391. /// <summary>
  392. /// 刚按下扳机
  393. /// </summary>
  394. private void DownTrigger()
  395. {
  396. OnDownTrigger();
  397. }
  398.  
  399. /// <summary>
  400. /// 刚松开扳机
  401. /// </summary>
  402. private void UpTrigger()
  403. {
  404. continuousShootFlag = false;
  405. if (delayedTime > 0)
  406. {
  407. continuousCount = 0;
  408. }
  409. OnUpTrigger();
  410. }
  411.  
  412. /// <summary>
  413. /// 触发开火
  414. /// </summary>
  415. private void TriggerFire()
  416. {
  417. continuousCount = continuousCount > 0 ? continuousCount - 1 : 0;
  418.  
  419. //减子弹数量
  420. CurrAmmo--;
  421. //开火间隙
  422. fireInterval = 60 / Attribute.StartFiringSpeed;
  423. //攻击冷却
  424. attackTimer += fireInterval;
  425.  
  426. //触发开火函数
  427. OnFire();
  428.  
  429. //开火发射的子弹数量
  430. var bulletCount = MathUtils.RandRangeInt(Attribute.MaxFireBulletCount, Attribute.MinFireBulletCount);
  431. //武器口角度
  432. var angle = new Vector2(GameConfig.ScatteringDistance, CurrScatteringRange).Angle();
  433.  
  434. //创建子弹
  435. for (int i = 0; i < bulletCount; i++)
  436. {
  437. //先算武器口方向
  438. Rotation = (float)GD.RandRange(-angle, angle);
  439. //发射子弹
  440. OnShoot();
  441. }
  442.  
  443. //当前的散射半径
  444. CurrScatteringRange = Mathf.Min(CurrScatteringRange + Attribute.ScatteringRangeAddValue, Attribute.FinalScatteringRange);
  445. //武器的旋转角度
  446. RotationDegrees -= Attribute.UpliftAngle;
  447. fireAngle = RotationDegrees;
  448. //武器身位置
  449. Position = new Vector2(Mathf.Max(-Attribute.MaxBacklash, Position.x - MathUtils.RandRange(Attribute.MinBacklash, Attribute.MaxBacklash)), Position.y);
  450.  
  451. if (FireEvent != null)
  452. {
  453. FireEvent(this);
  454. }
  455. }
  456.  
  457. /// <summary>
  458. /// 返回弹药是否到达上限
  459. /// </summary>
  460. public bool IsFullAmmo()
  461. {
  462. return CurrAmmo + ResidueAmmo >= Attribute.MaxAmmoCapacity;
  463. }
  464.  
  465. /// <summary>
  466. /// 返回是否弹药耗尽
  467. /// </summary>
  468. public bool IsEmptyAmmo()
  469. {
  470. return CurrAmmo + ResidueAmmo == 0;
  471. }
  472.  
  473. /// <summary>
  474. /// 拾起的弹药数量, 如果到达容量上限, 则返回拾取完毕后剩余的弹药数量
  475. /// </summary>
  476. /// <param name="count">弹药数量</param>
  477. private int PickUpAmmo(int count)
  478. {
  479. var num = ResidueAmmo;
  480. ResidueAmmo = Mathf.Min(ResidueAmmo + count, Attribute.MaxAmmoCapacity - CurrAmmo);
  481. return count - ResidueAmmo + num;
  482. }
  483.  
  484. /// <summary>
  485. /// 触发换弹
  486. /// </summary>
  487. public void _Reload()
  488. {
  489. if (CurrAmmo < Attribute.AmmoCapacity && ResidueAmmo > 0 && !Reloading)
  490. {
  491. Reloading = true;
  492. ReloadTimer = Attribute.ReloadTime;
  493. OnReload();
  494. }
  495. }
  496.  
  497. /// <summary>
  498. /// 换弹计时器时间到, 执行换弹操作
  499. /// </summary>
  500. private void ReloadSuccess()
  501. {
  502. if (Attribute.AloneReload) //单独装填
  503. {
  504. if (ResidueAmmo >= Attribute.AloneReloadCount) //剩余子弹充足
  505. {
  506. if (CurrAmmo + Attribute.AloneReloadCount <= Attribute.AmmoCapacity)
  507. {
  508. ResidueAmmo -= Attribute.AloneReloadCount;
  509. CurrAmmo += Attribute.AloneReloadCount;
  510. }
  511. else //子弹满了
  512. {
  513. var num = Attribute.AmmoCapacity - CurrAmmo;
  514. CurrAmmo = Attribute.AmmoCapacity;
  515. ResidueAmmo -= num;
  516. }
  517. }
  518. else if (ResidueAmmo != 0) //剩余子弹不足
  519. {
  520. if (ResidueAmmo + CurrAmmo <= Attribute.AmmoCapacity)
  521. {
  522. CurrAmmo += ResidueAmmo;
  523. ResidueAmmo = 0;
  524. }
  525. else //子弹满了
  526. {
  527. var num = Attribute.AmmoCapacity - CurrAmmo;
  528. CurrAmmo = Attribute.AmmoCapacity;
  529. ResidueAmmo -= num;
  530. }
  531. }
  532. if (ResidueAmmo == 0 || CurrAmmo == Attribute.AmmoCapacity) //换弹结束
  533. {
  534. Reloading = false;
  535. ReloadTimer = 0;
  536. OnReloadFinish();
  537. }
  538. else
  539. {
  540. ReloadTimer = Attribute.ReloadTime;
  541. OnReload();
  542. }
  543. }
  544. else //换弹结束
  545. {
  546. if (ResidueAmmo >= Attribute.AmmoCapacity)
  547. {
  548. ResidueAmmo -= Attribute.AmmoCapacity - CurrAmmo;
  549. CurrAmmo = Attribute.AmmoCapacity;
  550. }
  551. else
  552. {
  553. CurrAmmo = ResidueAmmo;
  554. ResidueAmmo = 0;
  555. }
  556. Reloading = false;
  557. ReloadTimer = 0;
  558. OnReloadFinish();
  559. }
  560. }
  561.  
  562. public override CheckInteractiveResult CheckInteractive(ActivityObject master)
  563. {
  564. var result = new CheckInteractiveResult(this);
  565. if (master is Role roleMaster) //碰到角色
  566. {
  567. if (Master == null)
  568. {
  569. var masterWeapon = roleMaster.Holster.ActiveWeapon;
  570. //查找是否有同类型武器
  571. var index = roleMaster.Holster.FindWeapon(Id);
  572. if (index != -1) //如果有这个武器
  573. {
  574. if (CurrAmmo + ResidueAmmo != 0) //子弹不为空
  575. {
  576. var targetWeapon = roleMaster.Holster.GetWeapon(index);
  577. if (!targetWeapon.IsFullAmmo()) //背包里面的武器子弹未满
  578. {
  579. //可以互动拾起弹药
  580. result.CanInteractive = true;
  581. result.Message = Attribute.Name;
  582. result.ShowIcon = "res://resource/sprite/ui/icon/icon_bullet.png";
  583. return result;
  584. }
  585. }
  586. }
  587. else //没有武器
  588. {
  589. if (roleMaster.Holster.CanPickupWeapon(this)) //能拾起武器
  590. {
  591. //可以互动, 拾起武器
  592. result.CanInteractive = true;
  593. result.Message = Attribute.Name;
  594. result.ShowIcon = "res://resource/sprite/ui/icon/icon_pickup.png";
  595. return result;
  596. }
  597. else if (masterWeapon != null && masterWeapon.Attribute.WeightType == Attribute.WeightType) //替换武器
  598. {
  599. //可以互动, 切换武器
  600. result.CanInteractive = true;
  601. result.Message = Attribute.Name;
  602. result.ShowIcon = "res://resource/sprite/ui/icon/icon_replace.png";
  603. return result;
  604. }
  605. }
  606. }
  607. }
  608. return result;
  609. }
  610.  
  611. public override void Interactive(ActivityObject master)
  612. {
  613. if (master is Role roleMaster) //与role碰撞
  614. {
  615. var holster = roleMaster.Holster;
  616. //查找是否有同类型武器
  617. var index = holster.FindWeapon(Id);
  618. if (index != -1) //如果有这个武器
  619. {
  620. if (CurrAmmo + ResidueAmmo == 0) //没有子弹了
  621. {
  622. return;
  623. }
  624.  
  625. var weapon = holster.GetWeapon(index);
  626. //子弹上限
  627. var maxCount = Attribute.MaxAmmoCapacity;
  628. //是否捡到子弹
  629. var flag = false;
  630. if (ResidueAmmo > 0 && weapon.CurrAmmo + weapon.ResidueAmmo < maxCount)
  631. {
  632. var count = weapon.PickUpAmmo(ResidueAmmo);
  633. if (count != ResidueAmmo)
  634. {
  635. ResidueAmmo = count;
  636. flag = true;
  637. }
  638. }
  639.  
  640. if (CurrAmmo > 0 && weapon.CurrAmmo + weapon.ResidueAmmo < maxCount)
  641. {
  642. var count = weapon.PickUpAmmo(CurrAmmo);
  643. if (count != CurrAmmo)
  644. {
  645. CurrAmmo = count;
  646. flag = true;
  647. }
  648. }
  649.  
  650. //播放互动效果
  651. if (flag)
  652. {
  653. Throw(new Vector2(30, 15), GlobalPosition, 0, 0,
  654. MathUtils.RandRangeInt(-20, 20), MathUtils.RandRangeInt(20, 50),
  655. MathUtils.RandRangeInt(-180, 180));
  656. }
  657. }
  658. else //没有武器
  659. {
  660. if (holster.PickupWeapon(this) == -1)
  661. {
  662. var slot = holster.SlotList[holster.ActiveIndex];
  663. if (slot.Type == Attribute.WeightType)
  664. {
  665. var weapon = holster.RemoveWeapon(holster.ActiveIndex);
  666. weapon.TriggerThrowWeapon(roleMaster);
  667. roleMaster.PickUpWeapon(this);
  668. }
  669. }
  670. }
  671. }
  672. }
  673.  
  674. /// <summary>
  675. /// 触发扔掉武器操作
  676. /// </summary>
  677. /// <param name="master">触发扔掉该武器的的角色</param>
  678. public void TriggerThrowWeapon(Role master)
  679. {
  680. //阴影偏移
  681. ShadowOffset = new Vector2(0, 2);
  682. if (master.Face == FaceDirection.Left)
  683. {
  684. Scale *= new Vector2(1, -1);
  685. RotationDegrees = 180;
  686. }
  687. var startHeight = 6;
  688. var direction = master.GlobalRotationDegrees + MathUtils.RandRangeInt(-20, 20);
  689. var xf = 30;
  690. var yf = MathUtils.RandRangeInt(60, 120);
  691. var rotate = MathUtils.RandRangeInt(-180, 180);
  692. Throw(new Vector2(30, 15), master.MountPoint.GlobalPosition, startHeight, direction, xf, yf, rotate, true);
  693. }
  694. public override void OnThrowOver()
  695. {
  696. //启用碰撞
  697. CollisionShape2D.Disabled = false;
  698. }
  699.  
  700. /// <summary>
  701. /// 触发拾起
  702. /// </summary>
  703. public void _PickUpWeapon(Role master)
  704. {
  705. Master = master;
  706. //握把位置
  707. AnimatedSprite.Position = Attribute.HoldPosition;
  708. //停止动画
  709. AnimationPlayer.Stop();
  710. //清除泛白效果
  711. ShaderMaterial sm = (ShaderMaterial) AnimatedSprite.Material;
  712. sm.SetShaderParam("schedule", 0);
  713. ZIndex = 0;
  714. //禁用碰撞
  715. CollisionShape2D.Disabled = true;
  716. OnPickUp(master);
  717. }
  718.  
  719. /// <summary>
  720. /// 触发移除
  721. /// </summary>a
  722. public void _Remove()
  723. {
  724. Master = null;
  725. AnimatedSprite.Position = Attribute.CenterPosition;
  726. AnimationPlayer.Play("Floodlight");
  727. OnRemove();
  728. }
  729.  
  730. /// <summary>
  731. /// 触发启用武器
  732. /// </summary>
  733. public void _Active()
  734. {
  735. ShadowOffset = new Vector2(0, Master.GlobalPosition.y - GlobalPosition.y);
  736. ShowShadowSprite();
  737. OnActive();
  738. }
  739.  
  740. /// <summary>
  741. /// 触发收起武器
  742. /// </summary>
  743. public void _Conceal()
  744. {
  745. HideShadowSprite();
  746. OnConceal();
  747. }
  748.  
  749. /// <summary>
  750. /// 实例化并返回子弹对象
  751. /// </summary>
  752. /// <param name="bulletPack">子弹的预制体</param>
  753. protected T CreateBullet<T>(PackedScene bulletPack, Vector2 globalPostion, float globalRotation, Node parent = null) where T : Node2D, IBullet
  754. {
  755. return (T)CreateBullet(bulletPack, globalPostion, globalRotation, parent);
  756. }
  757.  
  758. /// <summary>
  759. /// 实例化并返回子弹对象
  760. /// </summary>
  761. /// <param name="bulletPack">子弹的预制体</param>
  762. protected IBullet CreateBullet(PackedScene bulletPack, Vector2 globalPostion, float globalRotation, Node parent = null)
  763. {
  764. // 实例化子弹
  765. Node2D bullet = bulletPack.Instance<Node2D>();
  766. // 设置坐标
  767. bullet.GlobalPosition = globalPostion;
  768. // 旋转角度
  769. bullet.GlobalRotation = globalRotation;
  770. if (parent == null)
  771. {
  772. GameApplication.Instance.Room.SortRoot.AddChild(bullet);
  773. }
  774. else
  775. {
  776. parent.AddChild(bullet);
  777. }
  778. // 调用初始化
  779. IBullet result = (IBullet)bullet;
  780. result.Init(TargetCamp, this, null);
  781. return result;
  782. }
  783. }