- item_tooltip_view.gd: 新增 avoid_rect 属性,tooltip 与装备窗口重叠时自动推到左侧 - inventory_ui.gd: 悬停装备时传入窗口矩形作为避让区域 - 包含其他累积的功能开发和测试文件
12 KiB
12 KiB
ui.input_camera_mobile —— 鼠标、相机、光标、IME、触屏和移动端窗口
状态:PARTIAL
本合同检查 40250 的输入优先级、键盘状态、鼠标按钮映射、智能拾取、相机连续控制、事件相机、光标状态、IME 生命周期,以及当前端的触屏/移动端适配。判断标准是状态机、调用顺序、拒绝条件、清理副作用和可观察结果一致;“有一个可用的 Godot 控件”不能单独视为与 40250 等价。
40250 参考调用链
UserInterface/PythonPlayerInputKeyboard.cppNEW_SetSingleDIKKeyState先取消钓鱼,再处理方向键;NEW_SetSingleDirKeyState更新方向按键状态并立即进入多方向计算。NEW_SetMultiDirKeyState在__CanMove允许时按 WASD/方向键组合计算唯一旋转角,支持精确的四方向和四个对角方向;无方向时调用NEW_Stop。- 攻击键在钓鱼状态下走钓鱼分支,否则更新攻击状态。
UserInterface/PythonPlayerInputMouse.cpp- 移动、智能、相机、自动攻击、普通攻击和技能按钮由统一的
NEW_SetMouseState分派。 - 智能点击优先级为物品→角色→地面,并受私店、表情、眩晕等状态门控;相机按下进入拖拽,点击结束拖拽或选中目标并打开角色菜单。
- 中键相机、Ctrl 行为、技能按钮和拾取/地面射线均有独立状态清理。
- 移动、智能、相机、自动攻击、普通攻击和技能按钮由统一的
UserInterface/PythonApplicationCamera.cpp- 普通、站立、混合三类相机状态按帧更新;事件相机保存默认相机,混合期间锁定直接控制,结束后恢复普通相机。
- 相机旋转、俯仰和缩放使用连续速度;缩放按
1.0 + zoomSpeed * direction的比例更新,而不是固定距离步进。
UserInterface/PythonApplicationCursor.cpp/EterLib/Input.cpp- 光标有连续光标状态、硬件光标显隐和相机旋转等光标形状;DirectInput 键盘维护 256 字节状态并支持重新获取。
UserInterface/PythonIME.cpp- 文本输入显式处理左右/Home/End/删除、Tab/Return/Escape、字符输入、候选窗口和输入法状态回调。
当前端实现映射
project/player_controller.gd/project/game_scene.gd- 已实现桌面 WASD/方向键状态、按键释放清理、地面/物品/角色点击优先级,以及触屏点击与拖拽分离;移动端摇杆复用同一移动入口。
- 当前按键分为
_input处理释放、_unhandled_input处理按下,和 40250 的统一即时输入回调不是同一时序;角色碰撞/拾取也由 Godot 射线和简化碰撞半径适配。
project/game_camera.gd- 已有桌面右键拖拽、滚轮缩放、触屏单指旋转、双指缩放、Q/E/R/F/T/G 连续控制、普通/站立/混合事件相机、地形遮挡和镜头震动。
- 当前默认距离/俯仰角、固定缩放步进、相机目标高度和事件相机锁定/恢复语义没有与
CCamera的常量和比例缩放逐项统一。
project/ui/mouse_controller.gd/project/ui/cursor_manager.gd- 已实现物品/技能/表情拖拽、右键/ESC/失焦取消,以及
.sub光标资源加载和 Godot 光标映射。 - 没有完整复刻
NEW_SetMouseState的所有按钮分派;没有显式连续光标编号状态、硬件光标显隐封装和相机拖拽时隐藏硬件光标的等价链路。
- 已实现物品/技能/表情拖拽、右键/ESC/失焦取消,以及
project/ui/mobile/*- 已有安全区、横屏布局、虚拟摇杆、触屏按钮、长按技能瞄准、菜单返回和窗口焦点/暂停时触摸清理;这是移动平台适配层,不是 40250 Windows 输入实现本身。
- Godot
LineEdit/聊天 UI- 当前依赖引擎默认文本输入,没有独立的
PythonIME等价封装来记录光标移动、删除、候选窗口、编码页和输入法回调。
- 当前依赖引擎默认文本输入,没有独立的
分支等价矩阵
| 40250 判据/副作用 | 当前实现 | 结论 |
|---|---|---|
| WASD/方向键组合、对角角度、无键停止和按键释放清理 | _wasd 优先级、归一化、角色朝向和焦点清理已实现,输入按下/释放分属不同 Godot 阶段 |
部分等价;基础行为通过,时序和全部 __CanMove/钓鱼门控未形成同链证据 |
| 鼠标 MOVE/SMART/CAMERA/AUTO/ATTACK/SKILL 统一分派 | 物品、角色、地面点击和相机拖拽分别分布在 PlayerController/GameCamera/Quickbar | 部分等价;完整按钮映射、Ctrl/中键/角色菜单和拒绝分支未统一证明 |
| 智能点击物品→角色→地面及状态门控 | 当前 ground item→实体→地面顺序存在,触摸仲裁也存在 | 部分等价;私店、表情、眩晕、可拾取资格和 native 射线语义仍为适配近似 |
| 普通相机按帧跟随、旋转/俯仰/比例缩放 | 当前有跟随、拖拽、滚轮和连续键控制 | 不等价;缩放为固定距离步进,默认值/目标高度/连续速度尚未与参考公式统一;game_camera_test 3 项失败 |
| 事件相机保存、混合、锁定和恢复 | 有 NORMAL/STAND/BLEND 与字典插值/恢复 | 部分等价;缺少完整 CameraManager 状态锁、roll/视线/交叉线和异常中断清理证据 |
| 连续光标、相机旋转光标、硬件光标显隐 | 有资源加载和形状映射 | 部分等价;没有连续光标状态,拖拽期间未证明隐藏硬件光标,运行时自定义光标形状映射也不完整 |
| IME 光标/删除/候选/字符回调 | 依赖 Godot LineEdit | GAP;没有可审计的独立等价实现和回调测试 |
| 触屏、摇杆、双指缩放、移动窗口和安全区 | mobile UI/gesture/window 测试通过 | 平台适配通过;不应误标为 Windows 40250 输入链等价 |
| 失焦、暂停、重连、退出时输入状态清理 | PlayerController、MouseController、MobileOverlay 分别清理 | 部分等价;缺少 GameScene 统一清理和相机/鼠标/IME 组合状态的生产级测试 |
已执行测试
project/mouse_controller_test.gd:通过;覆盖全局物品拖拽状态和取消。project/input_key_test.gd:通过;覆盖 ClientVS22 桌面按键映射、Alt、快捷栏和模态 UI;进程有 20 个 ObjectDB 和 1 个 Camera RID 泄漏警告。project/mobile_gesture_test.gd:通过;覆盖长按、技能瞄准、快捷栏切换和物品触摸拖拽。project/mobile_ui_test.gd:通过;覆盖平台配置、横屏 HUD、菜单和控件。project/mobile_window_host_test.gd:通过;覆盖安全区、触摸桥和模态返回。project/game_camera_test.gd:失败 3 项:期望的默认距离 1550cm、默认俯仰角 27° 和RESTORE_CAMERA恢复保存普通视图均未满足;因此相机不能标记为等价。
上述三项是修复前的基线失败,已在本轮修正;后续结果见本合同末尾的实现修复记录。
Deep audit round 2026-09-21
Fresh regression results (修复前基线)
mouse_controller_test.gd、mobile_gesture_test.gd、mobile_ui_test.gd、mobile_window_host_test.gd均退出码 0;覆盖拖放取消、长按/技能瞄准、横屏控件、安全区、触摸桥和模态返回。input_key_test.gd断言通过,但有 20 个 ObjectDB 和 1 个 Camera RID 泄漏。game_camera_test.gd仍失败 3 项:默认距离 1550cm、默认俯仰 27°、RESTORE_CAMERA恢复保存普通视图。
Static parity conclusion (修复前基线)
- WASD/触屏和基础鼠标拖放路径可运行,但输入按下/释放分散在不同 Godot 阶段,尚未形成 40250
NEW_SetSingleDIKKeyState/统一鼠标状态分派的同一时序。 - 相机缩放、默认常量和恢复快照仍与参考不一致;事件相机的异常中断、相机/鼠标/IME 组合清理没有生产级证据。
- IME 仍依赖 Godot LineEdit,没有可审计的候选窗口、字符/删除/Home/End/Return/Escape 回调链;移动端测试通过不等于 Windows 40250 输入链一致。
修复前本轮仍为 PARTIAL;随后已针对相机默认值、缩放和目标高度完成实现修复,整体合同仍保持 PARTIAL。
Active EterLib core review
EterLib/Camera.cpp的CCamera维护普通/事件相机状态、Begin/EndDrag/Drag、滚轮和按比例Zoom(float ratio);相机管理器还负责当前相机、事件相机和恢复路径。当前game_camera.gd虽有同名交互入口,但使用固定距离步进,默认距离/俯仰和恢复快照已有 3 项测试失败,不能视为公式或状态机一致。EterLib/IME.cpp不只是文本框包装:它维护输入法启停、键盘捕获、组合字符串、候选/reading 窗口、code page、TSF 回调和字符串编辑。当前依赖 GodotLineEdit,没有对应的候选窗口、组合提交、编码页和回调生命周期;这是 Windows 输入链的明确缺口。- 因此本轮确认
Camera.cpp/.h、IME.cpp/.h、Input.h、msctf.h已完成活跃源码静态核对,但实现仍为PARTIAL,静态核对不等于运行时一致。
已确认差异和未验证项
- 已统一参考端与当前端的相机默认常量、单位、比例缩放、滚轮阻尼、连续控制速度、相机目标高度和恢复快照;
game_camera_test.gd的修复前 3 项失败已通过。 - 建立鼠标按钮分派矩阵,覆盖 MOVE/SMART/CAMERA/AUTO/ATTACK/SKILL、Ctrl、中键、技能/物品/角色/地面优先级和每个拒绝分支。
- 增加硬件光标显隐、连续光标、相机拖拽结束、失焦、暂停和异常退出的组合测试。
- 为聊天/输入框补充 IME 适配合同:光标移动、Home/End、删除、Return/Escape、候选窗口和字符回调;不能以 LineEdit 存在代替功能等价。
- 增加生产 GameScene 级输入清理测试,确认切图、断线、重连、窗口失焦和移动端触摸取消后没有粘滞按键、相机拖拽或拖放状态。
下一轮验证入口
- 先定位
game_camera.gd默认值和RESTORE_CAMERA失败的具体断言,按 40250 的 Camera 状态快照建立边界测试。 - 再审计
audio.bgm_ambience_3d,核对 BGM、区域环境音、角色音效、3D 监听器和前后台恢复调用链。
Active UserInterface IME bridge review
PythonIME.h/PythonIMEModule.cpp是 Windows IME 的完整桥:光标左右/Home/End/删除/设置位置、Create/Destroy、Tab/Return/Escape、WM_CHAR、候选/reading 更新、codepage 和输入模式都通过CPythonIME/EterLib::IME暴露给 Python。- 当前端
LineEdit能完成基本 UTF-8 文本输入,但没有证明多字节 codepage、候选窗口、reading string、组合态删除、焦点切换和系统 IME 回调的状态顺序一致;因此不能把普通键盘 smoke test 视为 IME 等价。
Static review evidence
已将 PythonIME.h、PythonIMEModule.cpp 纳入 active source 证据;相机/输入合同仍为 PARTIAL,需补真实输入法和失焦/取消清理测试。
Implementation fix round 2026-09-21
Reference chain
source/UserInterface/CameraProcedure.cpp::CCamera::Update:距离边界为 200/2500cm,滚轮速度按帧应用并以 0.5 阻尼,目标高度按距离从 100cm 插值到 150cm。source/UserInterface/PythonApplication.cpp:默认相机缩放速度为0.05。source/UserInterface/PythonApplicationCamera.cpp:ZoomCamera使用1.0 + speed * direction的比例缩放。source/EterLib/Camera.cpp::CCamera::Wheel:Win32 滚轮量按 0.3 resistance 转换为距离速度。
Current implementation
project/game_camera.gd已将默认值固定为 1550cm/27°,加入 200/2500cm 对应的目标高度插值、0.05 比例键盘缩放、36cm/刻度的滚轮速度和 0.5 阻尼;事件相机锁定时不消费普通缩放输入。project/game_camera_test.gd已覆盖默认值、RESTORE_CAMERA、目标高度的最小/最大距离边界、滚轮缩放阻尼和键盘 0.05 比例。
Verification
game_camera_test.gd:通过;默认值、事件相机恢复、动态目标高度、滚轮阻尼和比例缩放均通过。input_key_test.gd、mobile_gesture_test.gd、mobile_ui_test.gd、mobile_window_host_test.gd:通过;input_key_test.gd仍报告既有的 20 个 ObjectDB 与 1 个 Camera RID 泄漏警告。
该修复只闭合了相机默认值和缩放/目标高度的已确认差异;IME、完整鼠标按钮分派、硬件/连续光标和异常清理仍保持 PARTIAL,不能据此宣称输入系统整体等价。