Player.cs 3.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  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. internal override bool isPressingCrouch() => InputM.GetKeyEvent(InputM.KeyType.Crouch);
  9. internal override bool isPressDownJump() => InputM.GetKeyEvent(InputM.KeyType.Jump);
  10. internal override bool isPressingLeft() => InputM.GetKeyEvent(InputM.KeyType.Left);
  11. internal override bool isPressingRight() => InputM.GetKeyEvent(InputM.KeyType.Right);
  12. internal override void OnHitBorder() {
  13. Hurt();
  14. transform.position = new Vector3(0, 8, 0);
  15. }
  16. public float knockbackForceH = 30f, knockbackForceV = 15f;
  17. internal override void OnHitEnemy(Collision2D collision) {
  18. Hurt();
  19. int face = collision.transform.position.x < transform.position.x ? 1 : -1;
  20. rb.velocity = new Vector2(face * knockbackForceH, knockbackForceV);
  21. }
  22. public void Hurt() {
  23. AudioM.Play("hurt");
  24. rb.velocity = Vector2.zero;
  25. DOTween.Kill("ScreenShake");
  26. Camera.current.DOShakePosition(0.3f, 0.3f, 20).SetId("ScreenShake");
  27. }
  28. // 射击
  29. public int maxBullet = 20, currentBullet = 20;
  30. public float shootDelay = 0.15f; private float currentShootDelay = 0f;
  31. public float reloadDelay = 1.5f; private float currentReloadDelay = 0f;
  32. public float bulletSpeed = 50f, bulletKnockback = 1f;
  33. public GameObject bullet; public TMPro.TextMeshProUGUI textBullet;
  34. internal override void OnUpdate() {
  35. // 装填
  36. if (InputM.GetKeyEvent(InputM.KeyType.Reload) && currentBullet < maxBullet && currentReloadDelay <= 0f) {
  37. // TODO: 装填音效(总时长为 reloadDelay,看 Unity 里的 Player 右边栏,这里的数字可能是过期的)
  38. currentReloadDelay = reloadDelay;
  39. } else if (currentReloadDelay > 0 && currentReloadDelay < Time.deltaTime) {
  40. currentReloadDelay = 0f; currentBullet = maxBullet;
  41. } else if (currentReloadDelay > 0) {
  42. currentReloadDelay -= Time.deltaTime;
  43. }
  44. // 开火
  45. if (InputM.GetKeyEvent(InputM.KeyType.Fire) && currentBullet > 0 && currentShootDelay <= 0f && currentReloadDelay <= 0f) {
  46. // TODO: 开火音效
  47. currentBullet--; currentShootDelay = shootDelay;
  48. Vector2 fromPos = transform.position + Vector3.up * 0.55f;
  49. Vector2 toPos = Camera.allCameras[0].ScreenToWorldPoint(Input.mousePosition);
  50. Vector2 shootVector = (toPos - fromPos).normalized;
  51. GameObject newBullet = Instantiate(bullet, fromPos, Quaternion.identity);
  52. newBullet.GetComponent<Rigidbody2D>().velocity = bulletSpeed * shootVector;
  53. newBullet.transform.eulerAngles = (shootVector.x > 0 ? -1 : 1) * Vector2.Angle(shootVector, Vector2.up) * Vector3.forward;
  54. // 后座力
  55. rb.velocity += bulletKnockback * -shootVector;
  56. } else if (currentShootDelay > 0) {
  57. currentShootDelay -= Time.deltaTime;
  58. }
  59. // 更新 UI
  60. textBullet.text = currentReloadDelay > 0f ?
  61. "".PadLeft(maxBullet - Mathf.RoundToInt(currentReloadDelay / reloadDelay * maxBullet), "|".ToCharArray().First()) :
  62. "".PadLeft(currentBullet, "|".ToCharArray().First());
  63. textBullet.color = currentReloadDelay > 0f ? new Color(0.5f, 0.5f, 0.5f) : new Color(1, 1, 0.6f);
  64. }
  65. }