HOLD 音符 - 长押音符
概述
HOLD 音符需要玩家按住一段时间的音符。多个 HOLD 音符可以通过 holdGroup 连接形成完整的长押。
技术规格
| 属性 | 值 |
|---|---|
| 类型值 | 2 |
| ZNear | 1 |
| ZFar | 25 |
| Java 枚举 | NoteType.HOLD |
JSON 格式
{
"noteType": 2,
"beat": 4.0,
"pos": [0, 0, 0],
"scale": [1, 1, 1],
"rotation": [0, 0, 0],
"holdGroup": 0
}
字段说明
| 字段 | 类型 | 必需 | 说明 |
|---|---|---|---|
| noteType | int | 是 | 固定为 2 |
| beat | double | 是 | 音符出现的拍数位置 |
| pos | double[3] | 是 | [X, Y, Z] 坐标(数组格式) |
| scale | float[3] | 是 | [X, Y, Z] 缩放(数组格式) |
| rotation | float[3] | 是 | [X, Y, Z] 旋转角度(数组格式) |
| holdGroup | int | 是 | 长押组 ID(>= 0 表示参与长押) |
判定系统
判定窗口
| 判定类型 | 时间窗口 | 说明 |
|---|---|---|
| PERFECT | ±110ms | 完美命中 |
| FAST_GREAT | 110ms ~ 220ms | 偏快的大好 |
| LATE_GREAT | -220ms ~ -110ms | 偏慢的大好 |
| MISS | >220ms 或 <-220ms | 未命中 |
容差值
- 空间容差: 0.15(
TOLERATE_HOLD) - 判定逻辑: 检测玩家是否在音符位置附近并按住
长押组机制
holdGroup 字段
-1: 该音符不参与任何长押组(单独的 HOLD)>= 0: 长押组 ID,相同 ID 的 HOLD 音符形成长押
长押位置标记
系统会根据 holdGroup 自动识别长押的位置:
| 位置 | 说明 | 示例 |
|---|---|---|
| START | 长押起始音符 | 第一个音符 |
| MIDDLE | 长押中间音符 | 中间连接音符 |
| END | 长押结束音符 | 最后一个音符 |
| SOLO | 单独的长押音符 | 整首歌只有一个 HOLD |
长押识别规则
- 同一轨道: 相同
holdGroup的音符必须在同一轨道上 - 顺序排列: 音符必须按拍数顺序连续排列
- 类型限制: 只有
noteType=2的音符才能形成长押
判定逻辑
HOLD 音符的判定分为两个阶段:
- 起始判定: 检测玩家是否在起始时间点击/按住
- 持续判定: 检测玩家是否在整个长押期间保持在位置附近
HOLD 链式判定
HOLD 音符支持链式判定:
- 如果当前帧已经有 HOLD 判定成功,后续的 HOLD 音符可以被"拯救"
- 这允许玩家在连续的长押中保持判定
HOLD 位置计算
HOLD 音符的位置计算考虑了:
- 音符自身的坐标
- 轨道的变换(平移、旋转、缩放)
- 玩家的视线方向
使用示例
基本长押(2拍)
[
{
"noteType": 2,
"beat": 4.0,
"pos": [0, 0, 0],
"scale": [1, 1, 1],
"rotation": [0, 0, 0],
"holdGroup": 0
},
{
"noteType": 2,
"beat": 6.0,
"pos": [0, 0, 0],
"scale": [1, 1, 1],
"rotation": [0, 0, 0],
"holdGroup": 0
}
]
这两个 HOLD 音符在拍数 4.0 到 6.0 之间会被系统识别为同一个长押:
- 第一个音符会被标记为
START - 第二个音符会被标记为
END
复杂长押(多段)
[
{
"noteType": 2,
"beat": 0.0,
"pos": [0, 0, 0],
"scale": [1, 1, 1],
"rotation": [0, 0, 0],
"holdGroup": 0
},
{
"noteType": 2,
"beat": 2.0,
"pos": [0, 0, 0],
"scale": [1, 1, 1],
"rotation": [0, 0, 0],
"holdGroup": 0
},
{
"noteType": 2,
"beat": 4.0,
"pos": [0, 0, 0],
"scale": [1, 1, 1],
"rotation": [0, 0, 0],
"holdGroup": 0
}
]
这个长押包含三个音符,形成 START-MIDDLE-END 结构。
单独的 HOLD(SOLO)
{
"noteType": 2,
"beat": 8.0,
"pos": [0, 0, 0],
"scale": [1, 1, 1],
"rotation": [0, 0, 0],
"holdGroup": -1
}
这是一个单独的 HOLD 音符,不与其他音符连接。
与 TAP/LOOK 的区别
| 特性 | TAP/LOOK | HOLD |
|---|---|---|
| 持续时间 | 瞬时 | 持续一段时间 |
| 判定次数 | 一次 | 多次(起始 + 持续) |
| 组机制 | 不支持 | 支持长押组 |
| 容差值 | 0.15 | 0.15 |
| ZNear | 0 | 1 |
注意事项
holdGroup仅对 HOLD 音符有效,其他类型会被忽略- 长押组内的音符必须按拍数顺序排列
- 同一长押组的音符必须在同一轨道上
- 单独的 HOLD(holdGroup=-1)也是一个完整的长押
- 长押的持续时间由起始和结束音符的拍数决定