使用pynput实现贪吃蛇自动化:Backspace无法终止循环问题求助
解决贪吃蛇自动程序的终止问题
核心问题分析
你的代码存在两个关键问题:
on_press中Space触发的键盘操作和sleep都是阻塞代码,会占用键盘监听器的线程,导致Backspace的按键事件无法被及时处理。- 手动创建
on_press和on_release的线程完全多余,pynput的Listener本身已经以线程方式运行,这部分代码不会起作用,还会造成混乱。
修复后的代码
from pynput import keyboard from pynput.keyboard import Key, Controller import threading import time kb = Controller() # 全局标志,控制自动操作线程的运行状态 auto_running = False auto_thread = None # 简化键盘操作函数,去掉不必要的key参数 def droite(): kb.press(Key.right) kb.release(Key.right) def gauche(): kb.press(Key.left) kb.release(Key.left) def haut(): kb.press(Key.up) kb.release(Key.up) def bas(): kb.press(Key.down) kb.release(Key.down) # 自动操作的核心逻辑,放在单独线程中执行 def auto_play(): global auto_running try: print('开始自动操作') droite() time.sleep(1.7) haut() time.sleep(0.9) gauche() time.sleep(2.15) bas() time.sleep(1.9) droite() time.sleep(2.15) # 外层循环加入标志判断,允许中途终止 for i in range(255): if not auto_running: break for j in range(6): if not auto_running: break haut() time.sleep(0.1) gauche() time.sleep(2.1) haut() time.sleep(0.1) droite() time.sleep(2.1) if not auto_running: break if auto_running: gauche() time.sleep(2.15) bas() time.sleep(1.9) droite() print('自动操作结束') finally: auto_running = False def on_press(key): global auto_running, auto_thread if key == Key.space and not auto_running: auto_running = True # 启动新线程执行自动操作,不阻塞监听器线程 auto_thread = threading.Thread(target=auto_play) auto_thread.start() def on_release(key): global auto_running if key == Key.backspace: print('终止自动操作') auto_running = False # 如果线程存在,等待它结束 if auto_thread and auto_thread.is_alive(): auto_thread.join() # 返回False终止监听器 return False # 启动键盘监听器 with keyboard.Listener(on_press=on_press, on_release=on_release) as listener: listener.join()
关键改进点
- 使用
auto_running全局标志控制自动操作的执行,每次循环都检查该标志,确保收到终止信号后能及时退出。 - 将自动操作逻辑放到独立线程中执行,避免阻塞键盘监听器的线程,保证Backspace按键能被及时响应。
- 简化了键盘操作函数,去掉了冗余的参数。
- 移除了原代码中多余的手动线程创建逻辑,只保留pynput官方的Listener线程。
内容的提问来源于stack exchange,提问作者Yogeek
相关产品推荐
相关产品推荐

