I have a problem on getting user input.
I do not like the keyboard
module because it requires root user and the pynput
module blocks the entire script.
I tried this and it is pretty fast for normal request but when I have two loops, it is nearly impossible to get the user input (I need it in two loops because I print an ASCII animation to the console):
(UPDATED Example-CODE, to small reproducable one):
import tty
import termios
import select
import sys
def get_pressed_key():
"""
Detects which arrow key is pressed on the keyboard and returns the corresponding direction.
"""
fd = sys.stdin.fileno()
old_settings = termios.tcgetattr(fd)
try:
tty.setcbreak(sys.stdin.fileno()) # Set the terminal to cbreak mode
ch = None
if sys.stdin in select.select([sys.stdin], [], [], 0.001)[0]: # Adjust delay value here
ch = sys.stdin.read(1)
if ch == '\x1b': # Escape key
ch = sys.stdin.read(2)
if ch == '[A':
return "up"
elif ch == '[B':
return "down"
elif ch == '[C':
return "right"
elif ch == '[D':
return "left"
elif ch == '\r' or ch == '\n': # Enter key
return "enter"
elif ch == ' ': # Space key
return "space"
finally:
termios.tcsetattr(fd, termios.TCSADRAIN, old_settings)
return None
def clear_input():
termios.tcflush(sys.stdin, termios.TCIOFLUSH)
def clear_console():
"""clearing the console"""
os.system("cls" if os.name == "nt" else "clear")
printing the animation goes something like this:
import time
import os
def start_screen():
"""Prints a beautiful ASCII-Logo for the game to the console"""
stop = False
while stop is False:
if ((get_pressed_key() == "enter")or (stop is True)):
stop = True
break
frames = ["file1", "file2", "file3"]
for index, frame in enumerate(frames):
for line in frames[index]:
if ((get_pressed_key() == "enter")or (stop is True)):
stop = True
break
print(line)
print(f"\nHit the Enter Key, to continue", end="")
# Check while sleeping if enter has been entered
ind = 0
while ind in range(40):
time.sleep(0.01)
if ((get_pressed_key() == "enter")or (stop is True)):
stop = True
break
ind += 1
if stop is True:
break
clear_console()
time.sleep(0.1)
clear_console()
start_screen()
Update Question:
Maybe is there a way using multiprocessing to get the keyboard input? How would you do it running a seperate kernel from the main scripts kernel?