API 参考 / 只读视图、场景、音频与文本
BeatGrid
拍序号 / 拍相位的权威定义与纯函数实现(τ 进、拍信息出,无状态、无副作用)。宿主用它填充 GameplayContext 的节拍面与 BeatEvent;模组可直接复用它对任意 τ 求拍(如倒带窗口内对齐自己的演出、提前半拍触发)。
方法速览
| 方法 | 用途 |
|---|---|
periodMs(double) | 一拍的时长(毫秒) |
beatIndex(long, double, long) | 拍序号(可为负 = count-in) |
beatPhase(long, double, long) | 段内相位 [0,1) |
periodMs(double)
java
public static long periodMs(double bpm);行为:返回 round(60000 / bpm);bpm <= 0 视为无节拍信息返回 0(不抛异常)。
示例:
java
long p = BeatGrid.periodMs(174.0);beatIndex(long, double, long)
java
public static long beatIndex(long timeMs, double bpm, long sectionStartMs);行为:自 BPM 段起点以来的整拍数,floorDiv(timeMs - sectionStartMs, periodMs(bpm));timeMs 为负(进场倒计时)或早于段起点时结果为负数。bpm <= 0 或拍长为 0 返回 -1。
示例:
java
long idx = BeatGrid.beatIndex(1534L, 120.0, 0L); // 3beatPhase(long, double, long)
java
public static double beatPhase(long timeMs, double bpm, long sectionStartMs);行为:段内相位 [0,1),floorMod(timeMs - sectionStartMs, period) / period,0 = 正落在拍点上;无节拍信息返回 -1。与 beatIndex() 同源,因此三态(正常推进 / 倒带重演 / 暂停冻结)下同一 τ 恒得同一值。
示例:
java
double ph = BeatGrid.beatPhase(ctx.musicTimeMs(), ctx.beatBpm(), 0L);完整签名
java
public final class BeatGrid {
public static long periodMs(double bpm);
public static long beatIndex(long timeMs, double bpm, long sectionStartMs);
public static double beatPhase(long timeMs, double bpm, long sectionStartMs);
}节拍模型:以「当前 BPM 段」为基准——宿主取 τ 所在 BPM 段(最后一个 timeMs ≤ τ 的 timing point;无 timing point 时默认 120 BPM、段起点 0ms)。拍号当前恒为 4/4(谱面 JSON 不携带拍号),本类不消费拍号,变拍号属未来扩展。
线程:源码未声明额外线程约束(纯静态函数)。
稳定性: 新增,纯函数无副作用。