1

I am creating a console game, which takes user key presses.

I had trouble with hiding the letters that then spread across the screen simply because the user is pressing a button.

It won't work with modules like getpass, and I have already tried various ANSI codes to attempt to hide the text. The background is also full of text characters and symbols, so that stops just a complete ANSI character disappearo. I also don't wanna have to call os.system("clear") every frame, because even calling it once every second bugs out the terminal.

What I want to know, is whether there is a way to catch key presses without having said key appear on the console

Here is the board class I am using, and the draw() method inside is how I have been drawing it to the terminal:

class board:
  def __init__(self,length):
    import random
    self.random=random
    self.characters=[" ","░","▒","▓","█"]
    self.length=length
    self.dithering=False
    self.board=[[self.random.choice(self.characters) for y in range(self.length)] for x in range(self.length)]
  def draw(self,colour=None):
    if colour==None:
      colour=RGB(0,1,0)
    for x in range(len(self.board)):
      for y in range(len(self.board)):
        if self.board[y][x]==None:
          continue
        f=1
        if self.dithering==True:
          f=self.random.random()+0.5 # faintness
        print(f"\u001b[{y};{x*2+1}H\x1b[38;2;{int(colour.r*f)};{int(colour.g*f)};{int(colour.b*f)}m{str(self.board[y][x])*2}",end="")
    print("\x1b[0m")
  def redecorate(self,characters=None):
    if characters==None:
      characters=self.characters
    self.board=[[self.random.choice(characters) for y in range(self.length)] for x in range(self.length)]
  def empty(self):
    self.board=[[None for y in range(self.length)] for x in range(self.length)]

class RGB:
  def __init__(self,r,g,b):
    self.r=r*255
    self.g=g*255
    self.b=b*255
2
  • I don't understand your question. Do you want to catch user's key presses without displaying them? Please make you question more understandable. Commented Jan 9, 2022 at 12:35
  • @UltraStudioLTD Sorry 'bout the confusion. Yes, I would like to catch the key presses without displaying them. Commented Jan 9, 2022 at 23:54

1 Answer 1

1

To catch key presses without displaying them you need getch function. On Windows you can use msvcrt module to capture it, while on Unix-like and Linux platforms you need to implement it by yourself, although it is easy.

Here is code for Windows:

from msvcrt import getch

And for Linux and Unix-like platforms:

import sys
import termios
import tty
def getch() -> str:
    fd = sys.stdin.fileno()
    old_settings = termios.tcgetattr(fd)
    try:
        tty.setraw(sys.stdin.fileno())
        ch = sys.stdin.read(1)
    finally:
        termios.tcsetattr(fd, termios.TCSADRAIN, old_settings)
    return ch

NOTE: some keys are more than one char long (like arrow keys which are 3 char long) so you will need to run getch few times to fully capture it.

Sign up to request clarification or add additional context in comments.

3 Comments

So, to get this straight, I need to run this function just before the program, and it will keep key press characters invisible for the whole program?
Nevermind, I got it. Thanks for the help
Sorry for late reply, it was night. Answer is no. What this function does is that unlikely input or sys.stdin.read* that when called it only gets one char from sys.stdin and returns it without displaying that char.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.