简体   繁体   中英

Pygame skips checking for keypress

I'm programming a game that randomly picks a question for the player to answer. I have a function that randomly selects the question and displays it, which works fine. Here is the first question in the function:

topicList = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17]


def random_topic_generator():
    global RNG
    RNG = random.choice(topicList)
    if RNG == 0:
        screen.fill((255, 255, 255))
        draw_text("Question 1", questionFont, screen, 10, 0)
        draw_text("What color is the sky", questionFont, screen, 10, 100)
        draw_text("A: Green", answerFont, screen, 10,400)
        draw_text("B: Blue", answerFont, screen, 700, 400)
        draw_text("C: Orange", answerFont, screen, 10,600)
        draw_text("D: Yellow", answerFont, screen, 700, 600)
        topicList.remove(0)

Here is the corresponding part of the While loop:

while True:
    for event in pygame.event.get():
        if event.type == QUIT:
            pygame.quit()
            sys.exit()
        if event.type == KEYDOWN:
            if event.key == K_RETURN:
                random_topic_generator()
                if RNG == 0:
                    if event.key == K_b:
                        right_answer()
                    else:
                        wrong_answer()

right_answer() and wrong_answer():

def right_answer():
    screen.fill((255, 255, 255))
    draw_text("You got the question right!", right_wrongFont, screen, 500, 450)


def wrong_answer():
    screen.fill((255, 255, 255))
    draw_text("You got the question wrong.", right_wrongFont, screen, 500, 450)

Pressing return goes to the next question, which is fine. But, whenever RNG == 0, regardless of when I come across the question in the game, wrong_answer() always runs without a key press. If I get rid of the else and come across that question, pressing b does not do anything.

You already check the event key on line 7 of your second snippet. When you reach the innermost if statement, it always takes the else because you can only reach that code if the pressed key is return .

The cause of this logical error is probably the overcomplexity of your input handler, which makes it much easier to make mistakes. Long term you will probably want to refactor this code because your game will have many different states (menu, question, question complete) with different input handling. If you write separate input handling functions, you can check the game state before start handling events, and hand off the code to the correct handler. This prevents a monolithic megahandler from making your code difficult to update.

while True:
    state = handle_events(state)

def handle_events(state):
    if state == 1:
        return handle_menu_events(state)
    elif state == 2:
        return handle_question_events(state)
    elif state == 3:
        return handle_question_over_events(state)

def handle_question_events(state):
    for event in pygame.event.get():
        if event.type == KEYDOWN:
            if RNG == 0:
                if event.key == K_b:
                    right_answer()
                else:
                    wrong_answer()
            [...]

def handle_question_over_events(state):
    for event in pygame.event.get():
        if event.type == KEYDOWN:
            if event.key == K_RETURN:
                random_topic_generator()

Now your logic is separated enough that it becomes more difficult to accidentally mix event handling for different states, like your initial problem.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM