Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Effective Keyboard Input Handling

What is a good way to implement keyboard handling? In any language, where I write a keyboard-interactive program (such as a tetris game), I end up having some code that looks like this:

for event in pygame.event.get():
    if event.type == KEYDOWN:
        if False: pass          #make everything an elif
        elif rotating: pass
        elif event.key == K_q:
        elif event.key == K_e:
        elif event.key == K_LEFT:
            curpiece.shift(-1, 0)
            shadowpiece = curpiece.clone(); setupshadow(shadowpiece)
        elif event.key == K_RIGHT:
            curpiece.shift(1, 0)
            shadowpiece = curpiece.clone(); setupshadow(shadowpiece)

(shortened). I don't like this, as this has to go in my main loop, and it messes with all parts of the program. This also makes it impossible to have a user config screen where they can change which key maps to which action. Is there a good pattern to do this using some form of function callbacks?

like image 478
Claudiu Avatar asked Nov 23 '08 07:11

Claudiu


2 Answers

You could create a dictionary where the keys are the input and the value is a function that handles the keypress:

def handle_quit():
  quit()

def handle_left():
    curpiece.shift(-1, 0)
    shadowpiece = curpiece.clone(); setupshadow(shadowpiece)

def handle_right():
    curpiece.shift(1, 0)
    shadowpiece = curpiece.clone(); setupshadow(shadowpiece)

def handle_pause():
    if not paused:
        paused = True

branch = {
  K_q: handle_quit
  K_e: handle_pause
  K_LEFT: handle_left
  K_RIGHT: handle_right
}

for event in pygame.event.get():
    if event.type == KEYDOWN:
        branch[event.key]()

Then changing the keys is a matter of modifying keys of the dictionary.

like image 122
andrewrk Avatar answered Oct 13 '22 21:10

andrewrk


in addition to superjoe30's answer, you can use two levels of mapping (two dictionaries)

  • key => command string
  • command string => function

I think this would make it easier to allow user-defined mappings. i.e. so users can map their keys to "commands" rather than "the name of a function"

like image 39
hasen Avatar answered Oct 13 '22 21:10

hasen