Theseus 模组文档
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); // 3

beatPhase(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 不携带拍号),本类不消费拍号,变拍号属未来扩展。

线程:源码未声明额外线程约束(纯静态函数)。

稳定性: 新增,纯函数无副作用。