2012-12-26 35 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