Theseus 模组文档
API 参考 / 只读视图、场景、音频与文本

Scene


想先跑起来?

这一页是签名与行为参考。场景基类:生命周期、渲染与输入。直接做一遍:教程 · 自定义场景。

模组可实现的场景抽象。模组实现此接口并经 SceneHost#push / SceneHost#replace 注册,宿主用 ModSceneAdapter 把它桥接到内核场景管理器——用于实现自定义界面(如模组自制的图鉴、设置页、房间列表)。

方法速览

方法用途
id()场景唯一标识(唯一必须实现的方法)
onEnter()进入场景时调用
update(double)每帧逻辑更新(渲染与输入转发之前)
render(RenderCanvas)每帧渲染
handleInput(InputEvent)处理输入,返回 true 表示已消费
onExit()退出场景时调用

id()

java
String id();

行为:场景唯一标识,宿主以 "_mod_" + id 作为内部注册名。同一 id 重复 push / replace 会替换注册表中的场景实例(热重载友好);返回 null 时宿主直接忽略本次注册。模组可用 SceneHost#current().id() 与自己声明的 id 直接比对(内部名不外泄)。 示例:

java
@Override
public String id() {
    return "mymod:panel";
}

onEnter()

java
default void onEnter();

行为:进入场景时由宿主调用。默认空实现;抛出的异常被宿主隔离并限频记录,不影响场景切换。 示例:

java
@Override
public void onEnter() {
    query.reset("");
}

update(double)

java
default void update(double dt);

行为:每帧逻辑更新,在渲染与本帧输入转发之前调用(dt 为宿主实测帧间隔,单位秒,已 clamp 到合理范围)。动画推进、计时器、状态机应放在这里,而不是在 render 里隐式依赖帧率。默认空实现;异常被宿主隔离。 示例:

java
@Override
public void update(double dt) {
    elapsed += dt;
}

render(RenderCanvas)

java
default void render(RenderCanvas canvas);

行为:每帧渲染。RenderCanvas 是模组唯一允许的绘制入口抽象(后端无关);默认空实现,异常被宿主隔离并限频记录。 示例:

java
@Override
public void render(RenderCanvas canvas) {
    canvas.setColor(Color.WHITE);
    canvas.drawText("我的界面", 20, 40, TextStyle.of(16, Color.WHITE));
}

handleInput(InputEvent)

java
default boolean handleInput(InputEvent event);

行为:处理输入,返回 true 表示已消费;默认返回 false(不消费)。宿主在 update 阶段把本帧按键按下、文本输入(逐字符)与鼠标事件转发进来;ESC 未被消费时宿主会回退到上一场景(存在历史时)。异常被宿主捕获并返回 false。 示例:

java
@Override
public boolean handleInput(InputEvent event) {
    return event.type() == InputType.KEY_PRESSED
            && event.keyCode() == java.awt.event.KeyEvent.VK_SPACE;
}

onExit()

java
default void onExit();

行为:退出场景时由宿主调用(pop / replace 离栈)。默认空实现;异常被宿主隔离。应在此释放自己建立的临时订阅与资源引用。 示例:

java
@Override
public void onExit() {
    subscription.unsubscribe();
}

完整签名

java
public interface Scene {
    String id();
    default void onEnter();
    default void update(double dt);
    default void render(RenderCanvas canvas);
    default boolean handleInput(InputEvent event);
    default void onExit();
}

跳转干预:不在此接口——需要否决/改道场景跳转时订阅 SceneChangeEvent.Pre,放行不改结果、否决用 setResult(EventResult.DENY)、改道用 redirect(...)。

线程:源码未声明额外线程约束。宿主把场景导航封送到场景栈所在线程;回调均在渲染线程同步执行。

性能:update / render 每帧调用,实现应保持轻量;handleInput 只应做分派与组件转发。

稳定性:2.0 起冻结:2.x 内只增不破。update(double) 为后加 default 方法(纯增,旧实现无需改动)。