Reputation: 2269
I am making a snake game which requires the player to press the WASD
keys without stopping the game process to to get input from player. So I can't use input()
for this situation because then the game stops ticking to get input.
I found a getch()
function which immediately gives input without pressing enter, but this function also stops game ticking to get input like input()
. I decided to use threading module to get input via getch()
in different thread. The problem is that getch() isn't working while in different thread and I'm not sure why.
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)
So why getch()
is useless when it is in thread1()
?
Upvotes: 0
Views: 17739
Reputation: 64038
The problem was that you're creating a local variable key
inside thread1
instead of overwriting the existing one. The quick-and-easy solution would be to declare key
to be global inside thread1
.
Finally, you should consider using locks. I don't know if it's necessary or not, but I'd imagine weird things could happen if you try and write a value to key
in the thread while printing it out at the same time.
The working code:
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)
Upvotes: 5
Reputation: 312
I tried using getch but it didn't work for me... (win7 here).
You can try using tkinter module // but I still can't make it running with threads
# 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()
As Michael0x2a says you may try using library made for game-making - pygame or pyglet.
@EDIT @Michael0x2a: Are you sure your code works? Whatever I press it always prints the same key.
@EDIT2: Thanks!
Upvotes: 0