Python/Pygame: Trying to use a variable (maybe holding a string) to represent a PyGame condition

125 Views Asked by At

This is my first post sorry in advance for any etiquette missteps.

I am currently using pygame in Python to allow the user to customise what keys do what. The code below is my current condition but it does not solve the problem I'm having.

 if keys[pygame.K_UP]:

What I actually want is something more like this:

if keys["pygame.customisable_key"]:

As far as I know the pygame preface has to be included because of the way I'm designing the class that import this one.

Thanks

1

There are 1 best solutions below

0
skrx On BEST ANSWER

The pygame.K_ constants are actually just numbers (integers) which you can put as the values into your keys dictionary.

I'd define a dictionary with the actions (strings) as the dict keys and the pygame key constansts as the values, e.g.: keys = {'move_left': pg.K_a, 'move_right': pg.K_d}.

Then you can check in the event loop if event.key == keys['move_left']: and handle that event as desired.

To change a key, you first need to figure out to which action a new key should be assigned and when the next keyboard key gets pressed, insert the event.key attribute as the new value: keys[selected_action] = event.key.

This is just a simplistic example which can still be improved, but it's complete and works correctly as far as I can see (Press Esc to toggle the assignment scene, press one of the previous keys to select an action and then another key to assign a new key to this action):

import sys
import pygame as pg


def key_assignment_scene(keys, screen, clock):
    selected_action = None

    while True:
        for event in pg.event.get():
            if event.type == pg.QUIT:
                pg.quit()
                sys.exit()
            elif event.type == pg.KEYDOWN:
                if event.key == pg.K_ESCAPE:
                    return keys  # Return the keys to the main scene.
                elif selected_action:
                    # Assign a new key to the action.
                    keys[selected_action] = event.key
                    print(keys, 'new key:', event.unicode)
                    selected_action = None
                else:  # Select an action (a key from the `keys` dict).
                    for action, pygame_key in keys.items():
                        if event.key == pygame_key:
                            selected_action = action
                            print('Selected action:', selected_action)

        screen.fill((20, 40, 60))
        pg.display.flip()
        clock.tick(30)


def main():
    pg.init()
    screen = pg.display.set_mode((640, 480))
    clock = pg.time.Clock()
    BG_COLOR = pg.Color('gray12')
    BLUE = pg.Color('dodgerblue1')
    rect = pg.Rect(300, 220, 20, 20)
    speed_x = 0
    keys = {'move_left': pg.K_a, 'move_right': pg.K_d}

    while True:
        for event in pg.event.get():
            if event.type == pg.QUIT:
                return
            elif event.type == pg.KEYDOWN:
                if event.key == pg.K_ESCAPE:
                    print(keys)
                    # Switch to the key assigment scene.
                    keys = key_assignment_scene(keys, screen, clock)
                elif event.key == keys['move_left']:
                    speed_x = -3
                elif event.key == keys['move_right']:
                    speed_x = 3
            elif event.type == pg.KEYUP:
                if event.key == keys['move_left'] and speed_x < 0:
                    speed_x = 0
                elif event.key == keys['move_right'] and speed_x > 0:
                    speed_x = 0

        rect.x += speed_x

        screen.fill(BG_COLOR)
        pg.draw.rect(screen, BLUE, rect)
        pg.display.flip()
        clock.tick(30)

main()
pg.quit()