2

I'm going through the Roguebasin python/libtcod roguelike tutorial. The problem I encounter is, every time key = libtcod.console_wait_for_keypress(True) is called, the main loop fires off not one, but two times. The code handling keyboard input is as follows:

def handle_keys():
    #key = libtcod.console_check_for_keypress()  #real-time
    key = libtcod.console_wait_for_keypress(True)  #turn-based

    if key.vk == libtcod.KEY_ENTER and key.lalt:
        #Alt+Enter: toggle fullscreen
        libtcod.console_set_fullscreen(not libtcod.console_is_fullscreen())

    elif key.vk == libtcod.KEY_ESCAPE:
        return 'exit'  #exit game

    if game_state == 'playing':
        #movement keys
        if libtcod.console_is_key_pressed(libtcod.KEY_UP):
            player_move_or_attack(0, -1)

        elif libtcod.console_is_key_pressed(libtcod.KEY_DOWN):
            player_move_or_attack(0, 1)

        elif libtcod.console_is_key_pressed(libtcod.KEY_LEFT):
            player_move_or_attack(-1, 0)

        elif libtcod.console_is_key_pressed(libtcod.KEY_RIGHT):
            player_move_or_attack(1, 0)

        else:
            return 'didnt-take-turn'

The code is lifted verbatim (save for the extra four-space indentation) from this part of the tutorial. Note there are two code versions on that page. I have my own version written up, but I encounter the problem even with a direct copy/paste. As far as I can tell, the problem permeates the whole tutorial.

console_wait_for_keypress(True) is supposed to wait for a single key and put it in "key" variable, so I can react to it. All other input is supposed to be flushed. Then new iteration of main loop calls console_wait_for_keypress(True) again, which is supposed to wait for new input, and so on. Instead, every second iteration of console_wait_for_keypress(True) triggers without waiting for a new input.

The game actually works fine, since the second input does not trigger any of the console_is_key_pressed() conditions, and the handle_keys() function returns 'didnt-take-turn', which tells game logic to do nothing. This still means for every cycle, two are spent instead, which is not the desired behaviour. The problem is easy to observe if you print the result of handle_keys() every cycle. It alternates between 'None' and 'didnt-take-turn'.

I am honestly stumped on this. Simply holding down a directional button seems to not produce 'didnt-take-turn' output, but the function is supposed to be used for single keypresses. It can't be too short a delay, since a normal keypress always produces exactly two outputs. The libtcod documentation fails to help me.

What should I do to make a single keystroke trigger only a single console_wait_for_keypress()?

sloth
  • 99,095
  • 21
  • 171
  • 219
Mainframe
  • 21
  • 2

1 Answers1

0

It's fixed in the last svn: http://doryen.eptalys.net/forum/index.php?topic=1500.msg8507#msg8507

or here: https://bitbucket.org/jice/libtcod

Abalieno
  • 159
  • 1
  • 1
  • 5
  • Ah, so it was bugged. Thank you. I think I will be switching to wait_for_event anyway, but I know now there was nothing wrong with the code. Your help was most excellent. – Mainframe Nov 29 '12 at 15:31