9

I'm writing a Python snake game using curses, but am having some trouble controlling the snake, my current code for controlling the snake is placed inside the main loop and looks like this:

while True:
    char = screen.getch()
    if char == 113: exit()  # q
    elif char == curses.KEY_RIGHT: snake.update(RIGHT)
    elif char == curses.KEY_LEFT: snake.update(LEFT)
    elif char == curses.KEY_UP: snake.update(UP)
    elif char == curses.KEY_DOWN: snake.update(DOWN)
    else snake.update()
    time.sleep(0.1)

However the code seems to treat the keys pressed as a que (so the snake will stop when it runs out of arrow-presses), whereas I actually want it to retrieve the last arrow key that was pressed.

How can I retrieve the last arrow key that was pressed?

Zaz
  • 46,476
  • 14
  • 84
  • 101
  • 1
    Rethink your design (a `direction` variable would be suitable) and this problem disappears. – You Sep 06 '10 at 13:30
  • @You: As I understand it, that won't fix my problem. – Zaz Sep 06 '10 at 21:16
  • That completely depends on how you layout your program. As it is now, it looks like movement depends on input — a more suitable dependency would be to have movement depend on time only, and poll (non-blocking) for key events, changing a variable `direction` when these occur. That's how I see it, anyway. – You Sep 06 '10 at 21:37
  • Added missing line `else snake.update()`. – Zaz Sep 07 '10 at 10:11
  • It's the non-blocking poll part that I'm struggling with, `curses.halfdelay()` seems to solve that problem. – Zaz Sep 07 '10 at 10:15

1 Answers1

4

Set screen.nodelay(1):

screen.nodelay(1)
while True:
    char = screen.getch()
    if char == 113: break  # q
    elif char == curses.KEY_RIGHT: snake.update(RIGHT)
    elif char == curses.KEY_LEFT: snake.update(LEFT)
    elif char == curses.KEY_UP: snake.update(UP)
    elif char == curses.KEY_DOWN: snake.update(DOWN)
    else: snake.update()
    time.sleep(0.1)
Zaz
  • 46,476
  • 14
  • 84
  • 101
  • 2
    I've discovered that `curses.halfdelay()` can cause some weird bugs, `screen.nodelay()` + `time.sleep()` seems to work better. – Zaz Sep 08 '10 at 19:46