using System.Collections.Generic; using UnityEngine; public class JudgeManager : MonoBehaviour { public static JudgeManager Instance { get; private set; } // ===== 原有数据 ===== private Dictionary> judgeQueues = new Dictionary>(); private Dictionary startJudgedNotes = new Dictionary(); private Dictionary releasedNotes = new Dictionary(); private Dictionary noteEndTimes = new Dictionary(); private Dictionary middlePassedCounts = new Dictionary(); // ===== 新增:长音符全局互斥状态 ===== private class HoldJudgeState { public bool startResolved; // Start 是否已经判定过(成功 or 失败) public bool endResolved; // End 是否已经判定过 public bool skillTriggered; // 技能是否已触发 } private Dictionary holdStates = new Dictionary(); private HoldJudgeState GetHoldState(string noteID) { if (!holdStates.ContainsKey(noteID)) holdStates[noteID] = new HoldJudgeState(); return holdStates[noteID]; } private void Awake() { if (Instance == null) Instance = this; else Destroy(gameObject); } // ===== 新增:判定互斥闸门 ===== public bool TryResolveStart(string noteID) { var s = GetHoldState(noteID); if (s.startResolved) return false; s.startResolved = true; return true; } public bool TryResolveEnd(string noteID) { var s = GetHoldState(noteID); if (s.endResolved) return false; s.endResolved = true; return true; } public bool TryTriggerSkill(string noteID) { var s = GetHoldState(noteID); if (s.skillTriggered) return false; s.skillTriggered = true; return true; } public void ClearHoldState(string noteID) { if (holdStates.ContainsKey(noteID)) holdStates.Remove(noteID); } // ===== 原有接口(保持不变) ===== public void RegisterScheduledEndTime(string noteID, float endTime) { noteEndTimes[noteID] = endTime; } public float GetScheduledEndTime(string noteID) { return noteEndTimes.ContainsKey(noteID) ? noteEndTimes[noteID] : 0f; } public void RegisterStartJudged(string noteID, bool state) { startJudgedNotes[noteID] = state; } public bool IsStartJudged(string noteID) { return startJudgedNotes.ContainsKey(noteID) && startJudgedNotes[noteID]; } public void RegisterNoteReleased(string noteID, bool state) { releasedNotes[noteID] = state; Debug.Log($"[JudgeManager] RegisterNoteReleased: {noteID} = {state}"); } public bool HasNoteReleased(string noteID) { return releasedNotes.ContainsKey(noteID) && releasedNotes[noteID]; } public void RegisterNote(KeyCode key, Note note) { if (!judgeQueues.ContainsKey(key)) judgeQueues[key] = new Queue(); if (!judgeQueues[key].Contains(note)) judgeQueues[key].Enqueue(note); } public void UnregisterNote(KeyCode key, Note note) { if (!judgeQueues.ContainsKey(key)) return; Queue newQueue = new Queue(); while (judgeQueues[key].Count > 0) { Note n = judgeQueues[key].Dequeue(); if (n != note) newQueue.Enqueue(n); else if (!n.IsJudged()) n.JudgeMiss(); } judgeQueues[key] = newQueue; } public void JudgeEarliestNote(KeyCode key) { if (judgeQueues.ContainsKey(key) && judgeQueues[key].Count > 0) { Note note = judgeQueues[key].Dequeue(); if (note != null && !note.IsJudged()) note.Judge(); } } public void RegisterMiddlePassed(string noteID) { if (!middlePassedCounts.ContainsKey(noteID)) middlePassedCounts[noteID] = 0; middlePassedCounts[noteID]++; Debug.Log($"[JudgeManager] Middle passed for {noteID}, total={middlePassedCounts[noteID]}"); } public int GetMiddlePassedCount(string noteID) { return middlePassedCounts.ContainsKey(noteID) ? middlePassedCounts[noteID] : 0; } public void ClearNoteRecord(string noteID) { startJudgedNotes.Remove(noteID); releasedNotes.Remove(noteID); noteEndTimes.Remove(noteID); middlePassedCounts.Remove(noteID); ClearHoldState(noteID); } }