
combind
扩展原版按键绑定,增加组合键支持
查看大图本模组扩展了原版的按键绑定功能,增加了组合键支持,让你可以将任意动作绑定到和弦或按键序列上,而非单个按键。
仅客户端安装,无需服务端安装。

功能
和弦组合
- 将动作绑定到按键组合,例如 左 Shift + E、左 Ctrl + 鼠标左键,或任意其他按住键 + 触发键的组合
- 任意按键或鼠标按钮都可以作为组合中的触发键或按住键。录制时按下的最后一个键成为触发键,之前所有按住的键构成完整的组合
- 无限制!你可以按住任意多个按键,创建任意复杂的组合
- 可以后接序列组合
序列组合
- 将动作绑定到重复按键,例如 双击 Q 或 三次按空格
- 可配置的时间窗口决定按键之间必须多快才能被识别为序列
- 无限制!你可以绑定任意多次点击
控制界面集成
- 组合键录制直接嵌入原版的 控制 > 按键绑定 界面,无需单独的 UI
- 按 Escape 可以解除按键绑定
配置
- 允许冲突:禁用后,按下某个组合键时,不会同时触发其完全包含的子组合绑定。例如,同时绑定了 E 和 左 Shift + E,按下 左 Shift + E 通常会触发两者。禁用此选项可确保只触发 左 Shift + E。序列键同理:如果同一个键同时绑定了单次按压和多次点击(例如 Q 和 Q Q),按下该键只会触发单次按压绑定。像 左 Ctrl + E 和 左 Shift + E 这样的两个绑定不被视为冲突,因为按下其中一个绝不会意外触发另一个。只有当你故意同时按住 左 Ctrl + 左 Shift + E 时,两者才会同时触发。此设置仅适用于共享相同触发键的绑定(默认:开启)
- 序列窗口:游戏中必须多快地重复按键才能被识别为一个序列(默认:400 毫秒)
- 序列录制窗口:在控制界面录制序列时,录制器在两次点击之间等待的时间(默认:200 毫秒)
- 设置保存到
config/combind.json
用例
本模组在按键稀缺、每个绑定都需要精心设计的整合包中表现出色,但在原版中同样能提供额外的灵活性。
实际例子
双击 Q(Q Q)(甚至三击 Q(Q Q Q)!)来丢弃物品,而不是单次按压。不再意外丢物。
兼容性
本模组除了 Fabric API 之外没有其他必需的依赖。它可以与以下模组配合使用:
- ModMenu (推荐) — 在模组列表中添加一个配置按钮,作为手动编辑
config/combind.json的替代方案 - Controlling 和 Searchables — 使用类似
key:"Left Shift + E"或key:"Q Q"的语法,按组合键搜索绑定
注意:某些特定的原版交互与特定的输入类型绑定,重新绑定后可能无法正常工作。例如,将鼠标按钮绑定到“打开物品栏”将无法像按键一样关闭它;将按键绑定到“选取方块”将无法像鼠标按钮一样在容器内支持拖拽复制方块。
注意:如果遇到任何兼容性问题,请在 GitHub Issues 页面 报告。
给模组开发者
使用 Combind API
Combind 在 net.pemiridosa.combind.api 下公开了三个 API 类,让你的模组可以注册带有完整组合键支持的按键绑定。
依赖设置
通过 Modrinth Maven 仓库将 Combind 添加为编译时依赖:
// build.gradle
repositories {
maven { url "https://api.modrinth.com/maven" }
}
dependencies {
compileOnly "maven.modrinth:combind:VERSION"
localRuntime "maven.modrinth:combind:VERSION" // 可选:用于开发运行
}
在 fabric.mod.json 中声明依赖。如果你的模组需要 Combind,请使用 depends;如果是可选的,请使用 suggests:
"depends": {
"combind": "*"
}
API 类
| 类 | 用途 |
|---|---|
CombindKeyBinding |
包装了一个原版 KeyMapping 并添加了组合键支持——主要入口点 |
KeyCombo |
描述一个组合键:单个键、和弦、序列、或和弦 + 序列 |
InputKey |
代表一个物理输入——InputKey.keyboard(glfwCode) 或 InputKey.mouse(glfwButton) |
示例
和弦——按住修饰键 + 触发键
将动作绑定到 左 Shift + E:
KeyMapping.Category category = KeyMapping.Category.register(
Identifier.fromNamespaceAndPath("mymod", "mymod")
);
KeyMapping someActionMapping = KeyMappingHelper.registerKeyMapping(
new KeyMapping("key.mymod.someaction", GLFW.GLFW_KEY_E, category)
);
// 左 Shift + E
CombindKeyBinding someActionBinding = CombindKeyBinding.of(someActionMapping,
new KeyCombo(
InputKey.keyboard(GLFW.GLFW_KEY_E),
new InputKey[]{ InputKey.keyboard(GLFW.GLFW_KEY_LEFT_SHIFT) }
)
);
someActionBinding
.onPress(ctx -> LOGGER.info("按下动作 — 组合键: {}", ctx.combo().getDisplayName()))
.onRelease(ctx -> LOGGER.info("释放动作 — 组合键: {}", ctx.combo().getDisplayName()));
带多个修饰键的和弦
将动作绑定到 左 Ctrl + 左 Shift + E:
KeyMapping someActionMapping = KeyMappingHelper.registerKeyMapping(
new KeyMapping("key.mymod.someaction", GLFW.GLFW_KEY_E, category)
);
// 左 Ctrl + 左 Shift + E
CombindKeyBinding someActionBinding = CombindKeyBinding.of(someActionMapping,
new KeyCombo(
InputKey.keyboard(GLFW.GLFW_KEY_E),
new InputKey[]{
InputKey.keyboard(GLFW.GLFW_KEY_LEFT_CONTROL),
InputKey.keyboard(GLFW.GLFW_KEY_LEFT_SHIFT)
}
)
);
someActionBinding
.onPress(ctx -> LOGGER.info("按下动作 — 组合键: {}", ctx.combo().getDisplayName()))
.onRelease(ctx -> LOGGER.info("释放动作 — 组合键: {}", ctx.combo().getDisplayName()));
序列——多次点击同一个键
将动作绑定到 M M(双击)或 M M M(三击):
KeyMapping someActionMapping = KeyMappingHelper.registerKeyMapping(
new KeyMapping("key.mymod.someaction", GLFW.GLFW_KEY_M, category)
);
// 双击 M (M M)
CombindKeyBinding someActionBinding = CombindKeyBinding.of(someActionMapping,
KeyCombo.sequence(InputKey.keyboard(GLFW.GLFW_KEY_M), 2)
);
// 三击 M (M M M) — 更安全
CombindKeyBinding someActionBinding = CombindKeyBinding.of(someActionMapping,
KeyCombo.sequence(InputKey.keyboard(GLFW.GLFW_KEY_M), 3)
);
someActionBinding
.onPress(ctx -> LOGGER.info("按下动作 — 组合键: {}", ctx.combo().getDisplayName()))
.onRelease(ctx -> LOGGER.info("释放动作 — 组合键: {}", ctx.combo().getDisplayName()));
和弦 + 序列——按住修饰键的同时多次点击
将动作绑定到 左 Shift + Q Q(按住 Shift 的同时双击 Q):
// 左 Shift + Q Q
CombindKeyBinding binding = CombindKeyBinding.of(mapping,
new KeyCombo(
InputKey.keyboard(GLFW.GLFW_KEY_Q),
new InputKey[]{ InputKey.keyboard(GLFW.GLFW_KEY_LEFT_SHIFT) },
2
)
);
鼠标按钮作为触发键
将动作绑定到 左 Ctrl + 鼠标左键:
// 左 Ctrl + 鼠标左键
CombindKeyBinding binding = CombindKeyBinding.of(mapping,
new KeyCombo(
InputKey.mouse(GLFW.GLFW_MOUSE_BUTTON_LEFT),
new InputKey[]{ InputKey.keyboard(GLFW.GLFW_KEY_LEFT_CONTROL) }
)
);
单个按键(无需显式组合键)
CombindKeyBinding.of(mapping) 会从 KeyMapping 的默认按键推断出初始组合键:
CombindKeyBinding binding = CombindKeyBinding.of(mapping); // 默认为 KeyMapping 的按键
未绑定——默认未分配按键
// 玩家必须在 控制 > 按键绑定 界面中进行配置
CombindKeyBinding binding = CombindKeyBinding.of(mapping, KeyCombo.unbound());
基于 Tick 的轮询(原版风格)
如果你更喜欢标准的 tick 轮询模式而不是回调,可以通过原版 KeyMapping 直接实现,无需改动:
ClientTickEvents.END_CLIENT_TICK.register(client -> {
while (someActionMapping.consumeClick()) {
// 处理每个排队的点击
}
if (someActionMapping.isDown()) {
// 当前按住绑定
}
});
更多细节,请查看 src/client/java/net/pemiridosa/combind/api 的完整实现。
正在加载版本记录…


正在加载评论…
评论在新手盒子客户端中发表,这里同步展示。