Telegram群控BizHawk模拟器Bot故障:无法执行移动指令
问题分析与修复方案
核心问题排查
你的Telegram Bot无法操控BizHawk模拟器,问题集中在两个关键层面:
- 窗口激活后未给系统足够同步时间,
pyautogui按键操作在窗口未完全获取焦点时执行,导致输入被忽略 - BizHawk作为模拟器,对全局键盘事件的捕获有特殊机制,
pyautogui的全局模拟无法被正确识别
针对性修复步骤
1. 增加焦点延迟(基础修复)
在触发按键操作前添加短暂延迟,确保窗口完全激活:
import time # 新增导入 def move_character(direction): focus_pokemon_window("Pokemon - FireRed Version (USA) [Gameboy Advance] - BizHawk") time.sleep(0.1) # 等待窗口完成焦点切换 pyautogui.press(MOVEMENTS[direction]) # 改用press替代hotkey,适配单键操作
2. 改用窗口级输入事件(推荐方案)
使用pywin32直接向BizHawk窗口发送键盘消息,绕过全局模拟的限制:
首先安装依赖:
pip install pywin32
修改核心代码:
import win32api import win32con import time # 将按键映射替换为Windows虚拟键码 MOVEMENTS = { "up": win32con.VK_UP, "down": win32con.VK_DOWN, "left": win32con.VK_LEFT, "right": win32con.VK_RIGHT } def focus_pokemon_window(window_title): try: window = gw.getWindowsWithTitle(window_title)[0] window.restore() window.activate() return window._hWnd # 返回窗口句柄用于发送消息 except IndexError: print(f"No se encontró ninguna ventana con el título '{window_title}'.") return None def move_character(direction): hwnd = focus_pokemon_window("Pokemon - FireRed Version (USA) [Gameboy Advance] - BizHawk") if not hwnd: return time.sleep(0.1) # 模拟按键按下和释放的完整事件 win32api.SendMessage(hwnd, win32con.WM_KEYDOWN, MOVEMENTS[direction], 0) time.sleep(0.05) # 模拟实际按键按下时长 win32api.SendMessage(hwnd, win32con.WM_KEYUP, MOVEMENTS[direction], 0)
3. 系统权限与设置检查
- 确保Python脚本以管理员权限运行,避免系统拦截窗口操控
- 关闭Windows"专注助手"等可能拦截输入的系统功能
- 检查BizHawk设置,确认"键盘控制"选项处于启用状态
完整修改后的代码
import logging import time import pygetwindow as gw import win32api import win32con from telegram import Update from telegram.ext import Updater, CommandHandler, MessageHandler, Filters, CallbackContext # Configurar el registro logging.basicConfig(level=logging.INFO) TOKEN = "TOKEN" MOVEMENTS = { "up": win32con.VK_UP, "down": win32con.VK_DOWN, "left": win32con.VK_LEFT, "right": win32con.VK_RIGHT } def focus_pokemon_window(window_title): try: window = gw.getWindowsWithTitle(window_title)[0] window.restore() window.activate() return window._hWnd except IndexError: print(f"No se encontró ninguna ventana con el título '{window_title}'.") return None def move_character(direction): hwnd = focus_pokemon_window("Pokemon - FireRed Version (USA) [Gameboy Advance] - BizHawk") if not hwnd: return time.sleep(0.1) win32api.SendMessage(hwnd, win32con.WM_KEYDOWN, MOVEMENTS[direction], 0) time.sleep(0.05) win32api.SendMessage(hwnd, win32con.WM_KEYUP, MOVEMENTS[direction], 0) def start(update: Update, context: CallbackContext): update.message.reply_text("Bot activado! Envía @你的bot用户名 +方向(up/down/left/right)来操控游戏。") def handle_text(update: Update, context: CallbackContext): bot_username = context.bot.username text = update.message.text.lower() if f"@{bot_username.lower()}" not in text: return text = text.replace(f"@{bot_username.lower()}", "").strip() if text in MOVEMENTS: move_character(text) else: update.message.reply_text("Comando desconocido. Por favor, envía una dirección válida (up, down, left, right).") def main(): updater = Updater(TOKEN) dispatcher = updater.dispatcher dispatcher.add_handler(CommandHandler("start", start)) dispatcher.add_handler(MessageHandler(Filters.text & ~Filters.command, handle_text)) updater.start_polling() updater.idle() if __name__ == "__main__": main()
内容的提问来源于stack exchange,提问作者Kevin Walch
相关产品推荐
相关产品推荐

