为生成器做好准备
扩展音符盒(Extended Note Block)拥有许多自定义 NBT 标签,利用这些标签可以实现比传统音符盒更丰富的音乐效果。这对于通过命令方块或外部生成器批量生成音符盒非常有用。
NBT 结构概览
扩展音符盒的 NBT 数据主要分为基础属性和高级数据 (AdvancedData) 两部分。
基础属性 (Root)
这些属性直接位于 NBT 的根节点下:
| 标签名 | 类型 | 描述 | 范围/单位 | 默认值 |
|---|---|---|---|---|
note | Int | MIDI 音高 | 0-127 (60 为中央C) | 60 |
velocity | Int | MIDI 力度 (基础音量) | 0-127 | 100 |
sustainTime | Int | 音符持续时间 | 游戏刻 (Ticks, 20 ticks = 1s) | 40 |
delayedPlayingTime | Int | 延迟播放时间 | 毫秒 (ms) | 0 |
fadeInTime | Int | 淡入时间 | 游戏刻 (Ticks) | 0 |
fadeOutTime | Int | 淡出时间 | 游戏刻 (Ticks) | 0 |
方块状态 (Block States)
除了 NBT 数据,扩展音符盒还使用 BlockStates 来处理红石信号和视觉表现。
| 状态名 | 类型 | 可选值 | 描述 |
|---|---|---|---|
pitch | Enum | c, cs, d, ds, e, f, fs, g, gs, a, as, b | 对应当前音符在一个八度内的音高(Note % 12)。主要用于资源包更改方块纹理。例如 cs 代表 C#。 |
powered | Boolean | true, false | 标记方块是否被红石信号激活。用于检测信号边缘(上升沿/下降沿)。 |
注意
当你使用 setblock 放置方块时,通常不需要手动指定 pitch,因为方块在被红石激活时,会根据 NBT 中的 note 值自动计算并更新这个状态。
高级数据 (AdvancedData Compound)
所有高级功能的数据都存储在一个名为 AdvancedData 的复合标签内。生成器需要构造精确的 List 数据结构。
1. 弯音曲线 (PitchBendPoints)
- 类型:
List<Compound> - 元素结构:
{t: <float>, v: <float>}t(Time): 时间点,范围0.0(开始) 到1.0(结束)。v(Value): 半音 (Semitones) 偏移量。0.0: 无偏移(原音高)。12.0: 升高一个八度。-12.0: 降低一个八度。- 支持小数,例如
0.5半音(50 音分)。
- 插值行为: 游戏会在两个关键点之间进行线性插值。
2. 音量包络 (VolumePoints)
- 类型:
List<Compound> - 元素结构:
{t: <float>, v: <float>}t(Time): 时间点,范围0.0到1.0。v(Value): 音量倍率 (Multiplier)。1.0: 标准音量(由velocity决定)。0.0: 静音。2.0: 两倍标准音量。
- 插值行为: 游戏会在两个关键点之间进行线性插值。
- 覆盖规则: 一旦此列表非空,NBT 根节点的
fadeInTime/fadeOutTime将失效。
3. 声源移动路径 (SoundPath)
- 类型:
List<Compound> - 元素结构:
{x: <double>, y: <double>, z: <double>}- 这组坐标是相对于音符盒中心的偏移量。例如
{x:0, y:1, z:0}表示在音符盒上方 1 格处。
- 这组坐标是相对于音符盒中心的偏移量。例如
- 采样行为: 与曲线不同,
SoundPath不进行线性插值。- 游戏会根据当前播放进度,计算出索引
Index = Progress * (Size - 1),直接取对应点的位置。 - 建议: 如果需要平滑移动,生成器应生成足够密集的点(例如,如果
sustainTime为 40 ticks,建议生成 40 个路径点,每 tick 一个点)。
- 游戏会根据当前播放进度,计算出索引
4. GUI 表达式缓存 (ExpressionX/Y/Z)
- 类型:
String - 这些仅字符串用于在 GUI 中回显用户输入的公式(如
sin(t * pi))。
重要
游戏核心逻辑完全忽略这些字符串。如果你是一个外部生成器,不需要生成这些字符串,除非你想让玩家打开 GUI 时看到特定的公式。你需要生成的是上方的 SoundPath 列表。
Setblock 命令示例
你可以使用 /setblock 命令来放置一个带有预设 NBT 数据的扩展音符盒。
基础示例:
setblock ~ ~1 ~ extendednoteblock:extended_note_block{note:64, velocity:120, sustainTime:10}高级示例(包含弯音):
setblock ~ ~1 ~ extendednoteblock:extended_note_block{note:60, sustainTime:40, AdvancedData:{PitchBendPoints:[{t:0.0f, v:0.0f}, {t:1.0f, v:12.0f}]}}注意事项
SoundPath 与 Expression 的关系
在 AdvancedData 中,你可能会发现同时存在 SoundPath 和 ExpressionX/Y/Z。
- Expr (表达式):仅用于GUI 界面显示和编辑。游戏在运行时不会计算这些表达式。
- SoundPath (路径):这是游戏实际播放声音时使用的路径数据。
关键点: 如果你编写生成器,必须直接生成 SoundPath 列表数据。仅仅写入 Expression 字符串是无效的,声音不会移动,除非玩家手动打开 GUI 并保存,此时客户端才会根据表达式计算出路径点并写入 SoundPath。
音量控制优先权
音量主要由以下两个属性控制:
velocity(基础力度):决定全曲的基础音量。VolumePoints(高级音量曲线):如果AdvancedData中存在非空的VolumePoints列表,它将完全覆盖 (Override) 基础velocity的效果。
这意味着,如果你想使用动态的音量包络(ADSR等),应使用 VolumePoints;如果是简单的固定音量,使用 velocity 即可。