修复一堆bug 加入粒子系统代替原击打特效 焕新长音符逻辑 修复多重计分 更新判定管理和音符生成器 搞了一个免费包

This commit is contained in:
2025-12-18 03:26:52 +08:00
parent 1dd6c95ec9
commit a7d8d71d10
1572 changed files with 1658779 additions and 527 deletions
@@ -5,40 +5,74 @@ public class JudgeManager : MonoBehaviour
{
public static JudgeManager Instance { get; private set; }
// ===== 原有数据 =====
private Dictionary<KeyCode, Queue<Note>> judgeQueues = new Dictionary<KeyCode, Queue<Note>>();
private Dictionary<string, bool> startJudgedNotes = new Dictionary<string, bool>();
private Dictionary<string, bool> releasedNotes = new Dictionary<string, bool>();
// 记录 End 段的 scheduledEndTime(防止 End 被回收后仍然能判定)
private Dictionary<string, float> noteEndTimes = new Dictionary<string, float>();
// 记录每条长音符中段通过的计数
private Dictionary<string, int> middlePassedCounts = new Dictionary<string, int>();
// ===== 新增:长音符全局互斥状态 =====
private class HoldJudgeState
{
public bool startResolved; // Start 是否已经判定过(成功 or 失败)
public bool endResolved; // End 是否已经判定过
public bool skillTriggered; // 技能是否已触发
}
private Dictionary<string, HoldJudgeState> holdStates = new Dictionary<string, HoldJudgeState>();
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);
return;
}
if (Instance == null) Instance = this;
else Destroy(gameObject);
}
/// <summary>
/// 记录某个颜色的长音符 End 段的 scheduledEndTime
/// </summary>
// ===== 新增:判定互斥闸门 =====
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;
}
/// <summary>
/// 获取某个颜色的 End 段的 scheduledEndTime
/// </summary>
public float GetScheduledEndTime(string noteID)
{
return noteEndTimes.ContainsKey(noteID) ? noteEndTimes[noteID] : 0f;
@@ -65,23 +99,15 @@ public class JudgeManager : MonoBehaviour
return releasedNotes.ContainsKey(noteID) && releasedNotes[noteID];
}
/// <summary>
/// 当音符进入判定区域时调用
/// </summary>
public void RegisterNote(KeyCode key, Note note)
{
if (!judgeQueues.ContainsKey(key))
judgeQueues[key] = new Queue<Note>();
if (!judgeQueues[key].Contains(note))
{
judgeQueues[key].Enqueue(note);
}
}
/// <summary>
/// 当音符离开判定区域时调用
/// </summary>
public void UnregisterNote(KeyCode key, Note note)
{
if (!judgeQueues.ContainsKey(key)) return;
@@ -91,39 +117,23 @@ public class JudgeManager : MonoBehaviour
{
Note n = judgeQueues[key].Dequeue();
if (n != note)
{
newQueue.Enqueue(n);
}
else
{
// **如果音符未被判定,则触发 Miss**
if (!n.IsJudged())
{
n.JudgeMiss();
}
}
else if (!n.IsJudged())
n.JudgeMiss();
}
judgeQueues[key] = newQueue;
}
/// <summary>
/// 按键按下时,判定队列中最早进入的音符
/// </summary>
public void JudgeEarliestNote(KeyCode key)
{
if (judgeQueues.ContainsKey(key) && judgeQueues[key].Count > 0)
{
Note note = judgeQueues[key].Dequeue(); // 只取最早的音符
Note note = judgeQueues[key].Dequeue();
if (note != null && !note.IsJudged())
{
note.Judge();
}
}
}
/// <summary>
/// 记录中段通过,用于调试或进一步判定策略
/// </summary>
public void RegisterMiddlePassed(string noteID)
{
if (!middlePassedCounts.ContainsKey(noteID))
@@ -139,9 +149,10 @@ public class JudgeManager : MonoBehaviour
public void ClearNoteRecord(string noteID)
{
if (startJudgedNotes.ContainsKey(noteID)) startJudgedNotes.Remove(noteID);
if (releasedNotes.ContainsKey(noteID)) releasedNotes.Remove(noteID);
if (noteEndTimes.ContainsKey(noteID)) noteEndTimes.Remove(noteID);
if (middlePassedCounts.ContainsKey(noteID)) middlePassedCounts.Remove(noteID);
startJudgedNotes.Remove(noteID);
releasedNotes.Remove(noteID);
noteEndTimes.Remove(noteID);
middlePassedCounts.Remove(noteID);
ClearHoldState(noteID);
}
}
}