-1

I create the snake game with python and curses library. However I found the bug in the program. When pressing the key repeatedly, the snake move faster. Here is some part the code

# standard initialization
s = curses.initscr()

curses.start_color()
curses.init_pair(1, curses.COLOR_RED, curses.COLOR_BLACK)

curses.noecho()
curses.curs_set(0)
sh, sw = 30, 60
w = curses.newwin(sh, sw, 0, 0)
w.keypad(1)
w.timeout(100)
w.nodelay(1)

#Snake moving loop

while True:

next_key = w.getch()

#Check if user is pressing the key or not, or pressing the opposite direction key
if (next_key == -1):
    key = key
elif (key == curses.KEY_DOWN and next_key == curses.KEY_UP) or (key == curses.KEY_UP and next_key == curses.KEY_DOWN):
    key = key
elif (key == curses.KEY_LEFT and next_key == curses.KEY_RIGHT) or (key == curses.KEY_RIGHT and next_key == curses.KEY_LEFT):
    key = key
else:
    key = next_key

#Current location of the head
new_head = [snake[0][0], snake[0][1]]

 #moving up, down,left,right according to the key
if key == curses.KEY_DOWN:
    new_head[0] += 1
if key == curses.KEY_UP:
    new_head[0] -= 1
if key == curses.KEY_LEFT:
    new_head[1] -= 1
if key == curses.KEY_RIGHT:
    new_head[1] += 1

snake.insert(0, new_head)

I think it is because the getch() get called many time as the key is pressed and get into the moving loop without waiting for the timeout.

I tried curses.napms(100),curses.cbreak(1),curses.halfdelay(1) nothing work.

double-beep
  • 5,031
  • 17
  • 33
  • 41

1 Answers1

1

Calling s.nodelay(0) sets nodelay mode to 0 (which means false, so there is a delay), and it's on the wrong window object (s instead of w.)

You're calling getch on the w window instance, so I believe you have to call w.nodelay(1) (to enable nodelay mode).

You will also have to modify your input loop to recognize that if getch() returns -1, that means no key has been pressed. (Which will be the usual outcome, as pressing a key takes a significant fraction of a second, but this loop will now run many hundreds or even thousands of times per second.)

EDIT:

I think I misunderstood your issue somewhat. The above code is good to have, but it doesn't solve the core problem. You probably want to add a constant delay in your input loop, so that more keypresses do not allow more actions.

Perhaps something like this:

while True:
    keypress = w.getch()
    if keypress != -1:
        # process keypress
    sleep(100 milliseconds)
John Gordon
  • 29,573
  • 7
  • 33
  • 58
  • Thank you so much for the reply but it still didn't fix the problem of speeding up when pressing multiple times. I've update the code where I move the snake. Thank you again. – Mild Suppakarn May 03 '19 at 07:50