pythonpygametextbox

Textbox in pygame


I am creating a game. In some of the menus, when you create your profile, for example, I need to get the name typed by the player. The problem is: How?

I tested multiple techniques, for example:

Use pygame.KEYDOWN Ok, it works, but pygame.KEYDOWN is updated with pygame.event.get(). So because the game uses a lot of resources, most of the keys pressed aren't detected by pygame, because it needs to detect the exact moment where a key begins to be pressed. I've tried to reduce the amount of calcul, but it didn't help. And it doesn't really solve the problem. And the code began to be less understandable.

I could update the pressed keys every line, but... no one would think that it will not be unreadable.

Use pygame.key.get_pressed() This point is the axis where I think it will be good to work.

I used the technique below to detect the moment where a key is pressed (= last frame the key wasn't pressed, but this frame it is)

Bu this solution has a problem: the Shift key isn't managed, so you can't type any number, or delete a character... (well, you can, but I think it depends on the keyboard used, if it is an AZERTY or QWERTY and it will be very twisted and hard to code in this direction)

prev_key_pressed = None

while conditions:
    keys = pygame.key.get_pressed()
    num_keys_pressed = 0
    for key in range(len(keys)):
        if keys[key]:
            if prev_key_pressed != key: # if the key pressed last frame wasn't this key
                text += chr(key)

            num_keys_pressed += 1
            prev_key_pressed = key

    # if no key was pressed this frame
    if not num_keys_pressed:
        prev_key_pressed = None

Finally, I want to detect all the keys except \, / or . for example, to avoid evident directories reasons.

If anyone has an idea to help me, I'll be very grateful. I have searched and google but I found only what I already knew, or what I said above.


Solution

  • most of the keys pressed aren't detected by pygame, because it needs to detect the exact moment where a key begins to be pressed

    No. That is not true. The events are queued. However, pygame.event.get() gets all the messages and removes them from the queue. See the documentation:

    This will get all the messages and remove them from the queue. [...]

    If pygame.event.get() is called in multiple event loops, only one loop receives the events, but never do all loops receive all events. As a result, some events appear to be missed.
    See Faster version of 'pygame.event.get()'. Why are events being missed and why are the events delayed?.

    You have to use the KEYDOWN event instead of pygame.key.get_pressed().

    pygame.key.get_pressed() returns a list with the state of each key. If a key is held down, the state for the key is True, otherwise False. Use pygame.key.get_pressed() to evaluate the current state of a button and get continuous movement.

    The keyboard events (see pygame.event module) occur only once when the state of a key changes. The KEYDOWN event occurs once every time a key is pressed. KEYUP occurs once every time a key is released. Use the keyboard events for a single action.

    while conditions:
        # [...]
    
        for event in pygame.event.get():
            if event.type == pygame.KEYDOWN:
                text += event.unicode
    
        # [...]