using System; using System.Collections; using Game; using Sound; using UnityEngine; using UnityEngine.UI; namespace Comp { public class CockActionComp : MonoBehaviour { private static readonly Color HpGreen = new Color(0.06f, 0.9f, 0.18f); private static readonly Color HpYellow = new Color(0.9f, 0.9f, 0.18f); private static readonly Color HpRed = new Color(0.9f, 0.18f, 0.18f); private const string CockTag = "cock"; private ICockController _cockController; // 血量条组件 private Image _backgroundImage, _foregroundImage; private int _maxHp, _curHp; public int reduceHp; // 需要扣除的Hp public int MaxHp { set { _maxHp = value; _curHp = _maxHp; } } private void ReduceCurHp(int hp) { _curHp -= hp; var hpPercent = (float)_curHp / _maxHp; if (hpPercent > 0.5f) { _foregroundImage.color = HpGreen; } else if (hpPercent is >= 0.25f and <= 0.5f) { _foregroundImage.color = HpYellow; } else { _foregroundImage.color = HpRed; } var backgroundSize = _backgroundImage.rectTransform.sizeDelta; var foregroundSize = _foregroundImage.rectTransform.sizeDelta; var newForegroundWidth = backgroundSize.x * hpPercent; _foregroundImage.rectTransform.sizeDelta = new Vector2(newForegroundWidth, foregroundSize.y); } // 跑步跟切换待机状态相关参数 private bool _firstTrigger = true; // 第一次碰撞切换为待机 private Vector3 _thrust; private const float MoveSpeed = 1f; // 锁定物体相关参数 private float _miniY; // 最低Y坐标 // 执行动作相关 public Action curAction; private readonly WaitForSeconds _waitEverySecond = new WaitForSeconds(1f); // 水平与垂直方向运动相关 private CockJumpData _lowData, _highData, _curData; public int playerId; public int cockId; public bool rightForward = false; // miss文本相关参数 private GameObject _missPrefab; private bool _createMiss = false; public ICockController CockController { get { if (_cockController == null) { _cockController = new AnimatorCockController(animator); _cockController.OnRun += OnRun; _cockController.OnIdle += OnIdle; _cockController.OnAttack += OnAttack; _cockController.OnJumpAttack += OnJumpAttack; return _cockController; } return _cockController; } } public Animator animator; private void OnCollisionEnter(Collision collision) { if (collision.gameObject.CompareTag(CockTag) && _firstTrigger) { _firstTrigger = false; _cockController.IdleInBattle(); GameCore.Instance.GetCurState().BattleStart(); } } private void Start() { _missPrefab = Resources.Load("Prefab/prefab_miss"); // 获取血条的填充图片 var images = GetComponentsInChildren(); foreach (var image in images) { if (image.name == "Background") { _backgroundImage = image; } if (image.name == "Foreground") { _foregroundImage = image; } } // 获取最低Y坐标 _miniY = transform.position.y; // 跳跃相关 _lowData = new CockJumpData(0.5f, 0.45f, false); _highData = new CockJumpData(1.0f, 0.3f, true); _curData = _highData; StartCoroutine(CallEverySeconds()); } private IEnumerator CallEverySeconds() { while (true) { curAction?.Invoke(); curAction = null; yield return _waitEverySecond; } } private void Update() { if (_createMiss) { _createMiss = false; CreateMissText(); } if (reduceHp != 0) { ReduceCurHp(reduceHp); reduceHp = 0; } } private void FixedUpdate() { transform.Translate(_thrust * Time.deltaTime); // 移动游戏对象 // if (GameCore.Instance.inBattleState) transform.position += _curData.GetJumpVector(); if (GameCore.Instance.inBattleState) { if (rightForward) { transform.position += _curData.GetMoveVector(); } else { transform.position -= _curData.GetMoveVector(); } } if (transform.position.y < _miniY) { var position = transform.position; position = new Vector3(position.x, _miniY, position.z); transform.position = position; } } private void OnRun() { _thrust = new Vector3(0, 0, MoveSpeed); } private void OnIdle() { _thrust = new Vector3(0, 0, 0); } private void OnAttack() { _curData.StartMove(); } private void OnJumpAttack() { SoundCore.Instance.PlaySound(SoundType.CockJumpAttack, "player-" + playerId); _curData.StartJump(); } public void OnAttackEnd() { _curData.StopMove(); } public void OnJumpEnd() { _curData.StopJump(); } public void SetHighJump(bool high) { _curData = high ? _highData : _lowData; } public void CreateMiss() { this._createMiss = true; } private void CreateMissText() { var obj = Instantiate(_missPrefab); obj.GetComponent().SetTarget(transform); } } public class CockJumpData { private readonly float _gravity; // 重力 private readonly float _jumpVelocity; // 跳跃速度 private readonly bool _forward; // 是否前进 private Vector3 _jumpDirection = Vector3.zero; private Vector3 _moveDirection = Vector3.zero; private bool _move = false; // 是否移动状态 private float _timeToJumpApex; private float _curJumpTime; // 跳跃高度 到达跳跃高度的时间 public CockJumpData(float jumpHeight, float timeToJumpApex, bool forward) { _forward = forward; _timeToJumpApex = timeToJumpApex; // 计算跳跃速度和重力 _gravity = -(2 * jumpHeight) / Mathf.Pow(timeToJumpApex, 2); _jumpVelocity = Mathf.Abs(_gravity) * timeToJumpApex; } public Vector3 GetJumpVector() { if (_curJumpTime < 0) { return Vector3.zero; } // 计算重力 _jumpDirection.y += _gravity * Time.deltaTime; _curJumpTime -= Time.deltaTime; // 移动游戏对象 return _jumpDirection * Time.deltaTime; } public Vector3 GetMoveVector() { if (!_move) return Vector3.zero; // 计算位移 _moveDirection.x = (_forward ? 30f : -30f) * Time.deltaTime; return _moveDirection * Time.deltaTime; } public void StartJump() { _jumpDirection.y = _jumpVelocity; _curJumpTime = _timeToJumpApex * 2; // 双倍时间 _move = true; } public void StartMove() { _move = true; } public void StopJump() { _move = false; } public void StopMove() { _move = false; } } }