1

I am tooling around with some code to try to grasp some basic animation using Pygame. Some of the code is borrowed from Pygame tutorials that I have found.

What I am attempting to do is use a list to store all of the KEYDOWN events and eventually use that list to draw my character sprite to face the most recent direction of travel after releasing the key (I have nothing written in regards to recalling the last item in the list just yet). Currently, I have my sprite redraw to facing downward while no keys are being pressed.

The issue that I am running into is that while the function that gathers the KEYDOWN events is indeed called and produces output whenever I press the keys, the keys are not appended to the list and the console only shows empty brackets at every key press.

I am sure there may be a more effective solution and I realize that some of this code is likely a bit janky but I would certainly appreciate any guidance.

def get_pygame_events():
    pygame_events = pygame.event.get()
    return pygame_events


def last_pressed():
    global running
    keys_pressed = get_pygame_events()
    keys_pressed_list = []
    for event in keys_pressed:
        if event.type == pygame.KEYDOWN:
            if event.key == K_LEFT:
                keys_pressed_list.append("left")
            elif event.key == K_RIGHT:
                keys_pressed_list.append("right")
            elif event.key == K_UP:
                keys_pressed_list.append("up")
            elif event.key == K_DOWN:
                keys_pressed_list.append("down")
            elif event.key == K_ESCAPE:
                running = False
        if event.type == QUIT:
            running = False
    print(keys_pressed_list)


#main loop
running = True

while running:
    clock.tick(18)

    for event in pygame.event.get():
        if event.type == KEYDOWN:
            last_pressed()
            if event.key == K_ESCAPE:
                running = False
        elif event.type == QUIT:
            running = False

    keys = pygame.key.get_pressed()

    if keys[pygame.K_LEFT] and char_x > 5:
        char_x -= velocity
        move_left = True
        move_right = False
        move_down = False
        move_up = False

    elif keys[pygame.K_RIGHT] and char_x < win_x - char_width//2 - 5:
        char_x += velocity
        move_right = True
        move_left = False
        move_down = False
        move_up = False

    elif keys[pygame.K_UP] and char_y > 5:
        char_y -= velocity
        move_up = True
        move_down = False
        move_right = False
        move_left = False

    elif keys[pygame.K_DOWN] and char_y < win_y - char_height//2 - 5:
        char_y += velocity
        move_down = True
        move_up = False
        move_right = False
        move_left = False

    else:
        move_down = False
        move_up = False
        move_right = False
        move_left = False

    redrawGameWindow()
  • It looks like inside `last_pressed` you are setting `keys_pressed_list ` as an empty list again every time with this `keys_pressed_list = []`. Try declare `keys_pressed_list` somewhere outside the loop that gets checked on each new key press. –  Aug 14 '19 at 22:33

1 Answers1

0

There are two problems here, first keys_pressed_list is a local variable in the last_pressed() function. So really it only exists while that function is executing. You can declare it globally to increase the scope. This answer about python variable scope might give some more insight into this issue.

The second issue, is that keys_pressed_list is set to empty in the beginning of the last_pressed() function, so even if it was of global scope, the list would still be emptied.

Some code like:

keys_pressed_list = []

def last_pressed():
    global running, keys_pressed_list

    keys_pressed = get_pygame_events()

    for event in keys_pressed:
        if event.type == pygame.KEYDOWN:
            if event.key == K_LEFT:
                keys_pressed_list.append("left")
        ...

Would fix these scope, and clearing problems.

From your description, it sounds like you only need to record the most-recent key pressed. This is to determine the final orientation of your player bitmap (right?). So the code really only needs to remember the last key pressed, not an entire list. That said, the code is pretty much the same anyway.

last_key_pressed = None  # any non-movement key

def last_pressed():
    global running, last_key_pressed

    keys_pressed = get_pygame_events()

    for event in keys_pressed:
        if event.type == pygame.KEYDOWN:
            if event.key == K_LEFT:
                last_key_pressed = K_LEFT
        ...

Of course this doesn't handle the case when multiple keys are last-pressed, but that probably doesn't matter a whole lot.

Kingsley
  • 14,398
  • 5
  • 31
  • 53