响应速度拉满!手把手教你自制高性能 FPS 级虚拟键盘 (Flutter + Python + UDP)

你在宿舍敲代码的时候是否感觉到键盘声音太大影响室友,图书馆时,需要敲键盘但是又怕影响到其他人,想玩一些一般的FPS游戏又没有带键盘 ,而市面上的模拟键盘产品要么效果差要么需要收费,本篇就是一个完全免费开源的解决这个问题的项目,可以直接将项目安装包安装在你的安卓设备上,便可以使用高性能虚拟键盘

Github(“https://github.com/MoonPointer-Byte/MoonKeyboard”)

1. 引言:为什么要自制虚拟键盘?

在远程控制、多端协同或 FPS 游戏场景中,我们经常需要一个能自定义按键布局、且响应极快的虚拟键盘。市面上的远程输入软件通常存在两个问题:

  1. 延迟高:基于 TCP 或 HTTP 的传输在高频操作下有明显的滞后感。
  2. 游戏屏蔽:普通的自动化库(如 pyautogui)发送的是应用层指令,无法被基于 DirectX 的全屏游戏识别。

本项目通过 Flutter 打造极致的笔记本 UI,结合 UDP 协议 实现毫秒级响应,并利用 Python PyDirectInput 驱动级模拟,成功穿透游戏屏蔽,打造出一款真正能“打游戏”的虚拟键盘。


2. 技术架构与选型

本项目由移动端(客户端)和 PC 端(服务端)两部分组成:

  • 移动端 (Flutter)
    • UI 布局:采用 Expanded + flex 权重布局,完美对齐成长方形,还原笔记本手感。
    • 底层监听:使用 Listener 获取原始触控数据,实现智能手掌防误触
    • 网络通信:使用 RawDatagramSocket 发送极简 UDP 包。
  • 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 交互体验:按下发光与触觉反馈

为了赋予软件“机械感”,我们为按键增加了多维反馈:

  1. 视觉反馈:通过 AnimatedContainer 追踪 _activeKeys 状态。按下时,按键边框变亮,产生外发光(Glow Effect)并模拟阴影下陷。
  2. 触觉反馈:调用 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!有任何问题欢迎在评论区交流。

Logo

开源鸿蒙跨平台开发社区汇聚开发者与厂商,共建“一次开发,多端部署”的开源生态,致力于降低跨端开发门槛,推动万物智联创新。

更多推荐