2012-12-26 36 views
0

我正在制作一款蛇形游戏,要求玩家在不停止游戏过程的情况下按下WASD键来获得玩家的输入。所以我不能在这种情况下使用input(),因为那时游戏停止滴答作响以获得输入。如何使用线程获取python 3中的键盘输入?

我发现了一个getch()函数,它可以在不按下输入的情况下立即给出输入,但是此函数也会停止游戏滴答以获取输入,如input()。我决定使用线程模块在不同的线程中通过getch()获得输入。问题是getch()在不同的线程中不工作,我不知道为什么。

import threading, time 
from msvcrt import getch 

key = "lol" #it never changes because getch() in thread1 is useless 

def thread1(): 
    while True: 
     key = getch() #this simply is almost ignored by interpreter, the only thing it 
     #gives is that delays print() unless you press any key 
     print("this is thread1()") 

threading.Thread(target = thread1).start() 

while True: 
    time.sleep(1) 
    print(key) 

那么,为什么getch()是无用的,当它是thread1()

+0

你可能要考虑安装和使用pygame的,而不是使用线程。它具有让您轻松知道键盘上哪个键被按下的功能,所以您不必使用线程。 – Michael0x2a

回答

5

问题是,您在thread1内部创建了一个局部变量key,而不是覆盖现有变量。快速简便的解决方案是在thread1内声明key是全球性的。

最后,你应该考虑使用锁。我不知道是否有必要,但如果您在线程中尝试写入key的值,并同时打印出来,可能会发生奇怪的事情。

工作代码:

import threading, time 
from msvcrt import getch 

key = "lol" 

def thread1(): 
    global key 
    lock = threading.Lock() 
    while True: 
     with lock: 
      key = getch() 

threading.Thread(target = thread1).start() 

while True: 
    time.sleep(1) 
    print(key) 
+0

不工作,因为thread1()不像你说的那样重复。 我试过“while True:”thread1()中的所有内容,并且它开始正常工作。而我甚至不知道线程是什么。锁() – foxneSs

+0

@foxneSs:啊,你说得对'真的':' - 我的坏。我编辑了我的答案。 'threading.Lock'将确保只有线程被允许修改'锁'变量,当锁被激活。更多信息:http://stackoverflow.com/questions/6393073/why-should-you-lock-threads – Michael0x2a

0

我尝试使用残培但它并没有为我工作。(WIN7这里)。

您可以尝试使用的Tkinter模块//但我仍然不能使它与螺纹

# Respond to a key without the need to press enter 
import tkinter as tk #on python 2.x use "import Tkinter as tk" 

def keypress(event): 
    if event.keysym == 'Escape': 
     root.destroy() 
    x = event.char 
    if x == "w": 
     print ("W pressed") 
    elif x == "a": 
     print ("A pressed") 
    elif x == "s": 
     print ("S pressed") 
    elif x == "d": 
     print ("D pressed") 
    else: 
     print (x) 

root = tk.Tk() 
print ("Press a key (Escape key to exit):") 
root.bind_all('<Key>', keypress) 
# don't show the tk window 
root.withdraw() 
root.mainloop() 

运行作为Michael0x2a说,你可以尝试使用游戏制造由库 - pygame的或pyglet。

@EDIT @ Michael0x2a: 你确定你的代码工作? 无论我按什么,它总是打印相同的密钥。

@ EDIT2: 谢谢!

+1

无论出于何种原因,getch似乎只能从命令行工作。如果您在IDLE中运行该文件,它似乎不起作用。 – Michael0x2a