键位映射(Key Mappings)
键位映射(key mapping,或称为 key binding)定义了某个输入(如鼠标点击、按键等)所对应的特定动作。每个通过键位映射定义的动作,都可以在客户端能够接收输入时进行检测。此外,每个键位映射都可以通过 控制选项菜单 分配给任意输入。
注册一个 KeyMapping
要注册一个 KeyMapping,需要在仅限物理客户端的 mod 事件总线(event bus) 上监听 RegisterKeyMappingsEvent,并调用 #register 方法。
// 在某个仅限物理客户端的类中
// 键位映射采用延迟初始化,因此在注册前并不存在
public static final Lazy<KeyMapping> EXAMPLE_MAPPING = Lazy.of(() -> /*...*/);
// 事件只会在物理客户端的 mod 事件总线上触发
@SubscribeEvent
public void registerBindings(RegisterKeyMappingsEvent event) {
event.register(EXAMPLE_MAPPING.get());
}
创建一个 KeyMapping
可以通过构造函数来创建一个 KeyMapping。KeyMapping 需要传入一个 翻译键(translation key) 用于定义该映射的名称、该映射的默认输入,以及一个 翻译键 用于定义该映射在 控制选项菜单 中所在的分类。
你可以通过提供一个非原版自带的分类 翻译键,将 KeyMapping 添加到自定义分类中。自定义分类的翻译键应包含 mod id,例如 key.categories.examplemod.examplecategory。
默认输入(Default Inputs)
每个键位映射都关联有一个默认输入。这个输入通过 InputConstants.Key 提供。每个输入由一个 InputConstants.Type(定义输入设备类型)和一个整数(定义该设备上输入的唯一标识符)组成。
原版(vanilla)提供了三种输入类型:KEYSYM(通过 GLFW 键位码定义的键盘输入)、SCANCODE(通过平台相关的扫描码定义的键盘输入)、以及 MOUSE(鼠标输入)。
强烈建议你在处理键盘输入时优先使用 KEYSYM,因为 GLFW 键位码不依赖于具体系统。你可以在 GLFW 文档 中了解更多信息。
整数值取决于所选类型。所有输入码都定义在 GLFW 中:KEYSYM 相关的常量以 GLFW_KEY_* 为前缀,MOUSE 相关的常量以 GLFW_MOUSE_* 为前缀。
new KeyMapping(
"key.examplemod.example1", // 会使用这个翻译键进行本地化
InputConstants.Type.KEYSYM, // 默认映射到键盘
GLFW.GLFW_KEY_P, // 默认按键为 P
"key.categories.misc" // 映射会出现在“杂项”分类下
)
如果你不希望该键位映射有默认绑定,应将输入设置为 InputConstants#UNKNOWN。原版构造函数需要你通过 InputConstants$Key#getValue 提取输入码,而 NeoForge 的构造函数则可以直接传入原始输入字段。
IKeyConflictContext
并不是所有的按键映射(mapping)都会在每种上下文(context)下使用。有些按键映射只在图形界面(GUI)中使用,而有些则仅在游戏中使用。为了避免同一个按键在不同上下文下的映射发生冲突,可以为其分配一个 IKeyConflictContext。
每个冲突上下文(conflict context)都包含两个方法:#isActive,用于判断当前游戏状态下该映射是否可用;以及 #conflicts,用于判断该映射是否与同一或不同冲突上下文中的按键发生冲突。
目前,NeoForge 通过 KeyConflictContext 定义了三种基本的上下文:UNIVERSAL,即默认值,表示该按键可在所有上下文下使用;GUI,表示该映射仅在有 Screen(界面)打开时可用;IN_GAME,表示该映射仅在没有 Screen 打开时可用。如果需要新的冲突上下文,可以通过实现 IKeyConflictContext 自定义。
new KeyMapping(
"key.examplemod.example2",
KeyConflictContext.GUI, // 该按键映射仅在界面打开时可用
InputConstants.Type.MOUSE, // 默认映射为鼠标
GLFW.GLFW_MOUSE_BUTTON_LEFT, // 默认鼠标输入为鼠标左键
"key.categories.examplemod.examplecategory" // 该按键映射会归入新的示例分类
)
KeyModifier
模组开发者可能不希望映射在按下修饰键(modifier key)时表现一致(例如 G 与 CTRL + G)。为了解决这个问题,NeoForge 为构造函数增加了一个额外的参数,可以传入 KeyModifier,从而为任何输入添加控制键(KeyModifier#CONTROL)、Shift(KeyModifier#SHIFT)或 Alt(KeyModifier#ALT)。默认值为 KeyModifier#NONE,即不应用任何修饰键。
你可以在 控制选项菜单 中,通过同时按下修饰键和对应按键来添加修饰符。
new KeyMapping(
"key.examplemod.example3",
KeyConflictContext.UNIVERSAL,
KeyModifier.SHIFT, // 默认映射需要按住 Shift 键
InputConstants.Type.KEYSYM, // 默认映射为键盘
GLFW.GLFW_KEY_G, // 默认按键为 G
"key.categories.misc"
)
检查一个 KeyMapping
你可以检查一个 KeyMapping 是否被点击。根据不同的时机,可以在条件语句中使用该映射来执行相关逻辑。
游戏内
在游戏内,应该通过监听 事件总线 上的 ClientTickEvent.Post 事件,并在 while 循环中检查 KeyMapping#consumeClick