切换自由相机
基本信息
| 属性 | 值 |
|---|---|
| 翻译键 | key.freecam.toggle |
| 显示名 | Toggle Freecam(en_US.lang) |
| 默认按键 | F4(Keyboard.KEY_F4) |
| 默认类别 | key.categories.freecam → 显示为 Freecam |
| 构造位置 | ClientEventHandler 构造函数 |
| 注册方式 | ClientRegistry.registerKeyBinding(toggleKey) |
| 事件 | InputEvent.KeyInputEvent(ClientEventHandler.onKeyInput) |
| 唯一有默认按键的条目 | ✅ 另外两个按键默认均为 KEY_NONE |
按下与松开是两段语义
这是本按键最不直观的地方——它是边沿触发的,且按下阶段还兼作其它操作的"修饰键":
| 阶段 | 行为 |
|---|---|
按下(pressed == true) |
置 toggleKeyHeld = true,并把 tripodActivated 重置为 false |
松开(pressed == false) |
若 tripodActivated 仍为 false → 调用 FreecamController.toggle();随后 toggleKeyHeld = false |
tripodActivated 标志的作用是"消费"本轮操作:一旦在按住期间用数字键选过机位、
或用了另外两个按键,松手时不再切换自由相机。因此"按住 F4 选机位"与"点按 F4 进出"
共用一个按键,靠这个标志区分。
按住期间的三个分支
toggleKeyHeld 为真时,后续按键事件进入以下判定(顺序固定):
| 顺序 | 条件 | 行为 |
|---|---|---|
| 1 | TripodSlot.ofKeyCode(key) != NONE(数字键 1~9) |
清空对应 keyBindsHotbar[index] 的 isPressed() 队列;松开时调 toggleTripod(slot),置 tripodActivated = true |
| 2 | 松开且命中 重置相机 | 清空队列 → resetTripods(),置 tripodActivated = true |
| 3 | 松开且命中 玩家控制开关 | 清空队列 → togglePlayerControl(),置 tripodActivated = true |
三条分支的共同手法是 while (binding.isPressed()) {}——把 KeyBinding 内部积压的按键事件
队列排空,防止同一次按键继续被原版或其它 mod 处理。
附属的按键屏蔽
F4 按住期间,本 mod 会主动阻止数字键切换物品栏:
onClientTick(ClientTickEvent.END):toggleKeyHeld为真时遍历gameSettings.keyBindsHotbar,对每个按键执行while (hotbarKey.isPressed()) {};onKeyInput分支 1:再针对命中的那个下标单独排空一次。
按键冲突处理
| 冲突方 | 处理方式 |
|---|---|
| Controlling | 装了 Controlling 时 matchesKeyBinding 走 isComboModifierActive(binding),本按键可挂 Ctrl/Shift/Alt 修饰键 |
| Et Futurum | 装了 EFR 且 ConfigFunctions.enableGamemodeSwitcher 时,若同时按着 F3 则本次直接 return,既不进出也不排空队列 |
| Angelica 缩放 | 只影响滚轮,与本按键无关(见 移动速度) |
⚠️ EFR 规避分支的 return 发生在 while (toggleKey.isPressed()) {} 之前,
所以这次按键事件仍会残留在 KeyBinding 队列中。