API 参考 / 事件系统
GameplayTickEvent
游玩逐帧事件,每个游玩帧投递两次:Pre 在游玩逻辑更新之前,Post 在其之后。暂停恢复的倒带重演窗口内也照常投递。
方法速览
| 方法 | 用途 |
|---|---|
musicTimeMs() | 当前音乐时间(毫秒,可为负) |
rewinding() | 是否处于倒带重演窗口 |
deltaSeconds() | 本帧真实帧间隔(秒,非负) |
stepIndex() | 游玩场景内 tick 步号 |
musicTimeMs()
java
public long musicTimeMs();行为:返回当前音乐时间 τ(毫秒,可为负,例如 count-in 阶段)。窗口内 τ 会先倒退再正向重演,不保证单调。
rewinding()
java
public boolean rewinding();行为:true 表示本帧处于暂停恢复的倒带重演窗口(含倒带倒流段与紧随其后的正向重演段),窗口外为 false。这是「这段时间不可信」的单一信号:窗口内宿主时间在回退、其余系统未按常规整帧更新,监听器应据此跳过或重建自身累积状态。
deltaSeconds()
java
public double deltaSeconds();行为:本帧真实帧间隔(秒,恒非负,负值在构造时被钳为 0)。可用于帧率无关积分;倒带窗口内的 tick 同样携带真实帧间隔,需与 rewinding() 配合使用。经旧构造器构造的事件返回 0.0。
stepIndex()
java
public long stepIndex();行为:游玩场景内从 0 开始递增的 tick 步号(每帧 +1,同帧 Pre / Post 同值;倒带窗口内照常递增)。可作为与帧率无关的稳定排序键。经旧构造器构造的事件返回 -1。
示例
java
ctx.eventBus().subscribe(GameplayTickEvent.Pre.class, EventPriority.LOW, event -> {
if (event.rewinding()) {
// 窗口内时间不可信:改为按 τ 求值,而不是继续累加
progress = evaluateAt(event.musicTimeMs());
return;
}
progress += event.deltaSeconds() * ratePerSecond;
});完整签名
java
public abstract class GameplayTickEvent extends Event {
protected GameplayTickEvent(long musicTimeMs);
protected GameplayTickEvent(long musicTimeMs, boolean rewinding);
protected GameplayTickEvent(long musicTimeMs, boolean rewinding, double deltaSeconds, long stepIndex);
public long musicTimeMs();
public boolean rewinding();
public double deltaSeconds();
public long stepIndex();
public static final class Pre extends GameplayTickEvent {
public Pre(long musicTimeMs);
public Pre(long musicTimeMs, boolean rewinding);
public Pre(long musicTimeMs, boolean rewinding, double deltaSeconds, long stepIndex);
}
public static final class Post extends GameplayTickEvent {
public Post(long musicTimeMs);
public Post(long musicTimeMs, boolean rewinding);
public Post(long musicTimeMs, boolean rewinding, double deltaSeconds, long stepIndex);
}
}行为核验:宿主逐帧构造新实例(不是复用同一对象),但仍不得缓存事件对象。宿主当前所有 tick 投递点都使用全参构造,因此实际收到的事件 deltaSeconds() 非负、stepIndex() 非负;0.0 / -1 只出现在模组自行用旧构造器创建事件时。窗口内的 tick 不等于「其它系统已按常规更新完毕」——应据 rewinding() 跳过或重建累计状态。
性能:每帧投递,监听器必须极轻。
稳定性:2.0 起冻结;deltaSeconds() / stepIndex() 为 阶段 2 纯增,旧构造器分别返回 0.0 / -1。