Player.cs 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. using Cinemachine;
  2. using DG.Tweening;
  3. using System.Collections;
  4. using System.Collections.Generic;
  5. using System.Linq;
  6. using UnityEngine;
  7. public class Player : EntityBase
  8. {
  9. internal override bool isPressingCrouch() => InputM.GetKeyEvent(InputM.KeyType.Crouch);
  10. internal override bool isPressDownJump() => InputM.GetKeyEvent(InputM.KeyType.Jump);
  11. internal override bool isPressingLeft() => InputM.GetKeyEvent(InputM.KeyType.Left);
  12. internal override bool isPressingRight() => InputM.GetKeyEvent(InputM.KeyType.Right);
  13. // 生命
  14. public RectTransform[] hearts;
  15. private int _hp = 3;
  16. private int hp
  17. {
  18. get { return _hp; }
  19. set
  20. {
  21. if (_hp == value) return;
  22. _hp = value;
  23. if (_hp == 0) _hp = 3;
  24. RefreshHearts();
  25. }
  26. }
  27. public float knockbackForceH = 30f, knockbackForceV = 15f;
  28. internal override void OnHitBorder()
  29. {
  30. Hurt();
  31. transform.position = new Vector3(0, 8, 0);
  32. }
  33. internal override void OnHitEnemy(Collision2D collision)
  34. {
  35. Hurt();
  36. int face = collision.transform.position.x < transform.position.x ? 1 : -1;
  37. rb.velocity = new Vector2(face * knockbackForceH, knockbackForceV);
  38. }
  39. public void Hurt()
  40. {
  41. hp--;
  42. AudioM.Play("hurt");
  43. rb.velocity = Vector2.zero;
  44. DOTween.Kill("ScreenShake");
  45. Camera.current.DOShakePosition(0.3f, 0.3f, 20).SetId("ScreenShake");
  46. }
  47. // 治疗
  48. public float healTime = 4f; private float currentHealTime = 0f;
  49. private void RefreshHearts()
  50. {
  51. float totalHp = Mathf.Clamp(hp + Mathf.Pow(currentHealTime / healTime, 7f) * 0.7f + currentHealTime / healTime * 0.3f, 0, 3);
  52. for (int i = 0; i < 3; i++)
  53. {
  54. hearts[i].localScale = Vector3.one * Mathf.Clamp(totalHp - i, 0, 1);
  55. }
  56. }
  57. // 射击
  58. public int maxBullet = 20, currentBullet = 20;
  59. public float shootDelay = 0.15f; private float currentShootDelay = 0f;
  60. public float reloadDelay = 1.5f; private float currentReloadDelay = 0f;
  61. public float bulletSpeed = 50f, bulletKnockback = 1f;
  62. public GameObject bullet; public TMPro.TextMeshProUGUI textBullet;
  63. internal override void OnUpdate()
  64. {
  65. // 治疗
  66. if (isPressingCrouch() && hp < 3 && isLand)
  67. {
  68. currentHealTime += Time.deltaTime;
  69. if (currentHealTime > healTime)
  70. {
  71. currentHealTime -= healTime;
  72. hp++;
  73. }
  74. RefreshHearts();
  75. }
  76. else if (currentHealTime != 0f)
  77. {
  78. currentHealTime = 0f;
  79. RefreshHearts();
  80. }
  81. // 装填
  82. if (InputM.GetKeyEvent(InputM.KeyType.Reload) && currentBullet < maxBullet && currentReloadDelay <= 0f)
  83. {
  84. AudioM.Play("reload");
  85. currentReloadDelay = reloadDelay;
  86. }
  87. else if (currentReloadDelay > 0 && currentReloadDelay < Time.deltaTime)
  88. {
  89. currentReloadDelay = 0f; currentBullet = maxBullet;
  90. }
  91. else if (currentReloadDelay > 0)
  92. {
  93. currentReloadDelay -= Time.deltaTime;
  94. }
  95. // 开火
  96. if (InputM.GetKeyEvent(InputM.KeyType.Fire) && currentBullet > 0 && currentShootDelay <= 0f && currentReloadDelay <= 0f)
  97. {
  98. AudioM.Play("fire");
  99. currentBullet--; currentShootDelay = shootDelay;
  100. Vector2 fromPos = transform.position + Vector3.up * 0.55f;
  101. Vector2 toPos = Camera.allCameras[0].ScreenToWorldPoint(Input.mousePosition);
  102. Vector2 shootVector = (toPos - fromPos).normalized;
  103. GameObject newBullet = Instantiate(bullet, fromPos, Quaternion.identity);
  104. newBullet.GetComponent<Rigidbody2D>().velocity = bulletSpeed * shootVector;
  105. newBullet.transform.eulerAngles = (shootVector.x > 0 ? -1 : 1) * Vector2.Angle(shootVector, Vector2.up) * Vector3.forward;
  106. // 后座力
  107. rb.velocity += bulletKnockback * -shootVector;
  108. }
  109. else if (currentShootDelay > 0)
  110. {
  111. currentShootDelay -= Time.deltaTime;
  112. }
  113. // 更新 UI
  114. textBullet.text = currentReloadDelay > 0f ?
  115. "".PadLeft(maxBullet - Mathf.RoundToInt(currentReloadDelay / reloadDelay * maxBullet), "|".ToCharArray().First()) :
  116. "".PadLeft(currentBullet, "|".ToCharArray().First());
  117. textBullet.color = currentReloadDelay > 0f ? new Color(0.6f, 0.6f, 0.6f) : new Color(0.6588235f, 1f, 0.6941177f);
  118. }
  119. }