ehmatthes / pcc_3e

Online resources for Python Crash Course, 3rd edition, from No Starch Press.
1.19k stars 478 forks source link

alien_invasion: Pressing Q to Quit #5

Closed JohnLocke closed 1 year ago

JohnLocke commented 1 year ago

While working on the program on page 245, I encountered the following issues:

def _check_keydown_events(self, event):
    """Respond to keypresses."""
    if event.key == pygame.K_RIGHT:
        self.ship.moving_right = True
    elif event.key == pygame.K_LEFT:
        self.ship.moving_left = True
    elif event.key == pygame.K_q:
        sys.exit()

1.When attempting to close the game, it is necessary to switch the keyboard to uppercase mode in order to close the window.

2.If the "q" key is pressed in lowercase mode, it causes the game to become unresponsive to all keys, including the left and right arrow keys. However, after minimizing the window and reopening it, the game becomes responsive again, and it is possible to exit using the uppercase "Q."

I conducted online research and was informed that in Pygame, pygame.K_q represents the "Q" key on the keyboard without distinguishing between uppercase and lowercase. Therefore, I am puzzled as to why this situation is occurring.

ehmatthes commented 1 year ago

Hi, this is pretty interesting. I've never heard of an issue like this, and I've answered quite a few questions about Pygame over the years.

JohnLocke commented 1 year ago

I have pushed the code to GitHub.

My programming environment is as follows: ● OS: Windows 10 ● PyCharm 2022.2.3 (Professional Edition) ● Python 3.10.10 installed via the official website ● pygame 2.5.0 installed via PyCharm ● Keyboard: Varmilo VA87M connected via a data cable ● Lenovo LEGION Y7000P

When I initially encountered this issue (being unable to close the window by pressing the 'q' key), I was not aware of the case sensitivity problem.

Then I searched on Google for the problem, and many people suggested a solution of adding the line pygame.quit() after sys.exit(). I tried it, but it didn't work.

Then I came across a blog post where the author seemed to have a similar issue, and the post mentioned that using the uppercase 'Q' successfully closed the window. I tried it, and it worked.

ehmatthes commented 1 year ago

Does this mean you have to have caps lock on to quit the game?

JohnLocke commented 1 year ago

Does this mean you have to have caps lock on to quit the game? Yes, I need to have Caps Lock on to quit the game (and close the window, if these two are the same). If I press the lowercase 'q', the game window will not close, but it will simply stop responding to any keys. It's somewhat like quitting the game anyway.

ehmatthes commented 1 year ago

I downloaded the version of the game you have in your repository, and it quits when I press q, shift-q. Both of those combinations work with or without caps lock on.

Here's a minimal program that just shows information about each key that's pressed:

import sys

import pygame

class KeyDisplayer:
    """Show info about any key that's pressed."""

    def __init__(self):
        pygame.init()
        self.screen = pygame.display.set_mode((400, 200))

    def run_game(self):

        while True:
            # Watch for keyboard and mouse events.
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    sys.exit()
                elif event.type == pygame.KEYDOWN:
                    key_name = pygame.key.name(event.key)
                    print(event.key, key_name)

if __name__ == '__main__':
    kd = KeyDisplayer()
    kd.run_game()

# Start with caps lock off, and press the following keys:
# q, shift-q, caps lock, q

Here's my output:

$ python key_displayer.py
pygame 2.5.1 (SDL 2.28.2, Python 3.11.2)
Hello from the pygame community. https://www.pygame.org/contribute.html
113 q
1073742049 left shift
113 q
1073741881 caps lock
113 q

What do you get if you press q, shift-q, caps lock, q?

Also, do you get the same results if you unplug the external keyboard and use your laptop's built-in keyboard? (both with this minimal program and the original game program?)

JohnLocke commented 1 year ago

I think I've found the reason for the issue. My keyboard language is set to Chinese by default, and even when switched to English input mode, the situation I described occurs. When I change the keyboard language to English, both lowercase and uppercase 'q' can exit the game properly.

In the case where the keyboard language is set to Chinese, whether using an external keyboard or the built-in laptop keyboard, only 'q' with Caps Lock on can successfully exit the game, while 'q' and 'Shift+q' can not.

Here's my output where the keyboard language is set to Chinese :

pygame 2.5.0 (SDL 2.28.0, Python 3.10.10)
Hello from the pygame community. https://www.pygame.org/contribute.html
1073741881 caps lock

Anyway, I'm very sorry for taking up your time due to the keyboard language, and I really appreciate your patient assistance.

ehmatthes commented 1 year ago

No problem, that was really interesting!

I'm glad you got it sorted, and I'm happy to know a little more about how internationalization work impacts a project like Pygame. I'm sure I will see this issue in some form or another again at some point.