3

Does anyone know how to capture keystrokes for a game (i.e. using the keypad to navigate a simple ascii based game where 8 = up, 2 = down, 4 left, etc... and pressing return is not necessary, moving in a single keystroke is the goal.)? I found this code, which looks like a good idea, but is over my head. Adding comments, or sending me to an article on the subject etc, would be great help. I know a lot of people have this question. Thanks in advance?

    try:
        from msvcrt import kbhit
    except ImportError:
        import termios, fcntl, sys, os
        def kbhit():
            fd = sys.stdin.fileno()
            oldterm = termios.tcgetattr(fd)
            newattr = termios.tcgetattr(fd)
            newattr[3] = newattr[3] & ~termios.ICANON & ~termios.ECHO
            termios.tcsetattr(fd, termios.TCSANOW, newattr)
            oldflags = fcntl.fcntl(fd, fcntl.F_GETFL)
            fcntl.fcntl(fd, fcntl.F_SETFL, oldflags | os.O_NONBLOCK)
            try:
                while True:
                    try:
                        c = sys.stdin.read(1)
                        return True
                    except IOError:
                        return False
            finally:
                termios.tcsetattr(fd, termios.TCSAFLUSH, oldterm)
                fcntl.fcntl(fd, fcntl.F_SETFL, oldflags)
anthonynorton
  • 1,173
  • 10
  • 19
  • You could use a game library, like [pygame](http://www.pygame.org/), which supports keypresses as events. – Casey Kuball Mar 27 '12 at 04:13
  • All this snippet does is define a `kbhit()` method if one cannot be imported from the `msvcrt` package. – Burhan Khalid Mar 27 '12 at 04:18
  • How complicated is it to learn pygame? I am very new at programming. I was hoping for something that I could implement relatively soon. – anthonynorton Mar 27 '12 at 05:20
  • check out the gamedev stack overflow: http://gamedev.stackexchange.com/ – Aralox Mar 27 '12 at 06:13
  • possible duplicate of [Detect in python which keys are pressed](http://stackoverflow.com/questions/694296/detect-in-python-which-keys-are-pressed) – mechanical_meat Mar 28 '12 at 15:06
  • The code in your question is exactly that given in [this](http://stackoverflow.com/a/5047058/355230) answer to the question _Python cross-platform listening for keypresses?_ Note however that the alternative definition of `kbhit()` is not equivalent to the one in the `msvcrt` module, which doesn't actually read the keypress in like this code does. – martineau Dec 17 '12 at 11:45

2 Answers2

1

Pygame is a good place to start, the documentation is really good. Here is a way you can get keyboard output:

import pygame    
pygame.init()
screen = pygame.display.set_mode((100, 100))
while 1:
    for event in pygame.event.get():
        if event.type == pygame.KEYDOWN and event.key <= 256:
            print event.key, chr(event.key)

You have to initialise pygame and create an active window to do this. I don't think there is any way to avoid hitting the 'return' key without doing something along these lines.

Making something in Pygame is actually a pretty good way to start learning programming, as the site has loads of examples.

fraxel
  • 34,470
  • 11
  • 98
  • 102
1

Ok, if you want to understand how to control this directly, start by taking a good look at the Linux (or OS X) manual pages for termios, fcntl, and stty. It's a lot of stuff but you'll see what all those flags are for.

Normally, your keyboard input is line-buffered: The terminal driver collects it until you hit return. The flag ~termios.ICANON is the one responsible for turning off line buffering, so you can immediately see what the user types.

On the other hand, if you want your program to only respond when the user presses a key, you DON'T want os.O_NONBLOCK: It means that your program won't block when it reads from the keyboard, but your reads will return an empty string. This is appropriate for live action games where things keep happening whether or not the user reacts.

alexis
  • 48,685
  • 16
  • 101
  • 161