You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Python模拟键盘按键并解决《鸣潮》角色移动控制失效问题

Python模拟键盘输入与《鸣潮》角色移动实现方案

一、如何用Python准确模拟键盘任意按键输入

模拟键盘输入的核心是区分虚拟键码(VK)和扫描码(Scan Code):

  • 普通应用(如记事本)用虚拟键码即可生效,但大多数3D游戏(包括《鸣潮》)使用DirectInput捕获输入,必须用扫描码才能被正确识别。
  • 优先使用Windows API的SendInput函数,它是系统级别的输入模拟,比其他上层库更可靠。

两种可靠实现方式

1. 使用pydirectinput(简化版)

pydirectinput是专门针对游戏优化的库,默认会用扫描码模拟输入,只需注意以下几点:

  • 确保库版本最新,避免兼容性问题
  • 禁用安全退出(FAILSAFE)防止意外中断
  • 明确指定按键名称,无需手动映射键码
import time
import pydirectinput

# 禁用安全退出,避免移动鼠标到角落触发停止
pydirectinput.FAILSAFE = False
# 设置输入延迟,匹配游戏的输入响应速度
pydirectinput.PAUSE = 0.05

def hold_key(key, duration=0.2):
    pydirectinput.keyDown(key)
    time.sleep(duration)
    pydirectinput.keyUp(key)

# 循环测试A键(左移)
while True:
    hold_key('a')
    time.sleep(0.1)

2. 使用ctypes调用SendInput(底层可控版)

直接调用Windows API,完全自定义输入参数,适合需要精确控制的场景:

  • 必须设置dwFlags为0x0008(KEYEVENTF_SCANCODE),表示使用扫描码
  • 扫描码可以通过微软官方文档或工具查询,比如A键的扫描码是0x1E
import time
import ctypes

# 定义Windows API所需的结构体
PUL = ctypes.POINTER(ctypes.c_ulong)

class KeyBdInput(ctypes.Structure):
    _fields_ = [
        ("wVk", ctypes.c_ushort),
        ("wScan", ctypes.c_ushort),
        ("dwFlags", ctypes.c_ulong),
        ("time", ctypes.c_ulong),
        ("dwExtraInfo", PUL)
    ]

class Input_I(ctypes.Union):
    _fields_ = [("ki", KeyBdInput)]

class Input(ctypes.Structure):
    _fields_ = [
        ("type", ctypes.c_ulong),
        ("ii", Input_I)
    ]

# 模拟按下按键(扫描码)
def press_scan_code(scan_code):
    extra = ctypes.c_ulong(0)
    input_event = Input_I()
    input_event.ki = KeyBdInput(0, scan_code, 0x0008, 0, ctypes.pointer(extra))
    send_input = Input(1, input_event)
    ctypes.windll.user32.SendInput(1, ctypes.pointer(send_input), ctypes.sizeof(send_input))

# 模拟释放按键(扫描码)
def release_scan_code(scan_code):
    extra = ctypes.c_ulong(0)
    input_event = Input_I()
    # 加上KEYEVENTF_KEYUP标志(0x0002)
    input_event.ki = KeyBdInput(0, scan_code, 0x0008 | 0x0002, 0, ctypes.pointer(extra))
    send_input = Input(1, input_event)
    ctypes.windll.user32.SendInput(1, ctypes.pointer(send_input), ctypes.sizeof(send_input))

# 常用按键扫描码映射
scan_codes = {
    'a': 0x1E,
    'w': 0x11,
    's': 0x1F,
    'd': 0x20,
    'space': 0x39
}

# 循环测试A键左移
while True:
    press_scan_code(scan_codes['a'])
    time.sleep(0.2)
    release_scan_code(scan_codes['a'])
    time.sleep(0.1)

二、《鸣潮》角色移动的可行代码方案

你之前的代码失效的核心原因:

  • pydirectinput代码中未定义key_dict,导致按键映射错误
  • ctypes代码中混合使用了虚拟键码和扫描码,且未设置KEYEVENTF_SCANCODE标志,无法被游戏的DirectInput捕获

修正后的可运行代码(推荐pydirectinput,更简洁)

import time
import pydirectinput

pydirectinput.FAILSAFE = False
pydirectinput.PAUSE = 0.03  # 缩短延迟,匹配游戏响应

def move_left(duration=0.3):
    # 按住A键实现左移
    pydirectinput.keyDown('a')
    time.sleep(duration)
    pydirectinput.keyUp('a')

def move_forward(duration=0.3):
    # 按住W键实现前进
    pydirectinput.keyDown('w')
    time.sleep(duration)
    pydirectinput.keyUp('w')

# 测试循环:前进->左移->停顿
while True:
    move_forward()
    time.sleep(0.2)
    move_left()
    time.sleep(0.2)

运行注意事项

  • 管理员权限运行:右键Python脚本或终端,选择“以管理员身份运行”,否则可能无法向游戏窗口发送输入
  • 游戏窗口前台:运行代码前确保《鸣潮》处于前台激活状态
  • 关闭中文输入法:切换到英文输入法,避免按键被输入法拦截
  • 游戏设置检查:确保游戏内的移动控制设置为键盘按键(未切换到手柄模式)

内容的提问来源于stack exchange,提问作者TokaiTeio

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 13:37:10