响应速度拉满!手把手教你自制 FPS 级虚拟键盘 (Flutter + Python + UDP 深度实战),深夜算竞助手
·
响应速度拉满!手把手教你自制高性能 FPS 级虚拟键盘 (Flutter + Python + UDP)
你在宿舍敲代码的时候是否感觉到键盘声音太大影响室友,图书馆时,需要敲键盘但是又怕影响到其他人,想玩一些一般的FPS游戏又没有带键盘 ,而市面上的模拟键盘产品要么效果差要么需要收费,本篇就是一个完全免费开源的解决这个问题的项目,可以直接将项目安装包安装在你的安卓设备上,便可以使用高性能虚拟键盘
Github(“https://github.com/MoonPointer-Byte/MoonKeyboard”)
1. 引言:为什么要自制虚拟键盘?
在远程控制、多端协同或 FPS 游戏场景中,我们经常需要一个能自定义按键布局、且响应极快的虚拟键盘。市面上的远程输入软件通常存在两个问题:
- 延迟高:基于 TCP 或 HTTP 的传输在高频操作下有明显的滞后感。
- 游戏屏蔽:普通的自动化库(如
pyautogui)发送的是应用层指令,无法被基于 DirectX 的全屏游戏识别。
本项目通过 Flutter 打造极致的笔记本 UI,结合 UDP 协议 实现毫秒级响应,并利用 Python PyDirectInput 驱动级模拟,成功穿透游戏屏蔽,打造出一款真正能“打游戏”的虚拟键盘。
2. 技术架构与选型
本项目由移动端(客户端)和 PC 端(服务端)两部分组成:
- 移动端 (Flutter):
- UI 布局:采用
Expanded+flex权重布局,完美对齐成长方形,还原笔记本手感。 - 底层监听:使用
Listener获取原始触控数据,实现智能手掌防误触。 - 网络通信:使用
RawDatagramSocket发送极简 UDP 包。
- UI 布局:采用
- PC 服务端 (Python):
- 网络监听:异步处理 UDP 数据包,识别指令。
- 硬件模拟:调用
pydirectinput发送驱动级扫描码(Scan Codes),确保游戏兼容性。
3. 核心功能实现方案
3.1 UDP 极速握手与心跳机制
为了实现“按下即响应”,我们抛弃了 TCP。UDP 就像发短信,不需要建立连接,速度极快。
同时,为了实现 App 端的在线/离线状态感应,我们设计了双向心跳:
- App 端:每 2 秒发送一个
PING:PING指令。 - 服务端:收到包含
PING的数据后立即返回PONG。 - 状态联动:App 若在 4 秒内未收到回传,指示灯自动变红,按钮切回离线状态。
3.2 完美的笔记本式布局 (Rectangle Layout)
笔记本键盘的左右两侧是绝对对齐的。在 Flutter 中,如果手动计算宽度,很容易因为 Margin 导致溢出。
解决方案:统一每一行的 flex 权重总和(例如 100),通过分配比例实现完美长方形。
- 普通字母键:
flex: 60 - Tab 键:
flex: 90 - Space 键:
flex: 335 - 品字形方向键:通过
Column嵌套实现上下键半高显示,完美还原照片布局。
3.3 交互体验:按下发光与触觉反馈
为了赋予软件“机械感”,我们为按键增加了多维反馈:
- 视觉反馈:通过
AnimatedContainer追踪_activeKeys状态。按下时,按键边框变亮,产生外发光(Glow Effect)并模拟阴影下陷。 - 触觉反馈:调用
HapticFeedback.selectionClick(),让手指在点按时感受到微弱震动。
4. 关键代码解析
4.1 Python 服务端核心逻辑
import pydirectinput
import socket
# 将暂停时间设为0,消除 pydirectinput 的内置延迟
pydirectinput.PAUSE = 0
# 处理心跳与按键映射
def handle_message(message, addr, sock):
if "PING" in message:
sock.sendto(b"PONG", addr) # 返回心跳响应
return
action, key = message.split(":")
target = key_map.get(key)
if target:
if action == "DOWN":
pydirectinput.keyDown(target) # 驱动级模拟按下
else:
pydirectinput.keyUp(target) # 驱动级模拟松开
4.2 Flutter 智能防误触
Dart
Listener(
onPointerDown: (event) {
// 识别触点面积:手指尖接触面积小,手掌肉垫接触面积大
// radiusMajor 是判断手掌误触的关键
if (event.kind == PointerDeviceKind.touch && event.radiusMajor > 25) {
print("Palm detected, ignoring...");
return;
}
_sendKey("DOWN", id);
},
onPointerUp: (_) => _sendKey("UP", id),
)
5. 效果展示
连接前:左上角红色指示灯显示 ENGINE OFFLINE,蓝色 CONNECT 按钮诱导用户连接。
连接后:指示灯变为亮绿色呼吸动画,文字切换为 ENGINE ONLINE。IP 输入框锁定并调暗,按钮变为沉浸式深色。
操作感:WASD 绿色高亮,按键按下时产生实时光效,响应几乎零延迟。
6. 结语
本项目结合了移动端跨平台 UI 开发、网络套接字编程以及硬件模拟技术。如果你正在寻找一个低延迟的远程控制方案,或者想为自己的 FPS 游戏做一个自定义按键宏面板,这个思路绝对值得参考。
如果你觉得这个项目有趣,欢迎在 GitHub 上点个 Star!有任何问题欢迎在评论区交流。
更多推荐




所有评论(0)