【问题标题】:While loop issue in pygame not pausing for event handlerpygame中的循环问题不会为事件处理程序暂停
【发布时间】:2017-09-27 15:04:41
【问题描述】:

我正在 pygame 中构建一个多项选择测验游戏,但是我的 while 循环存在问题。

我在没有 GUI 的情况下成功地在 python 中构建了游戏,并且所有逻辑都可以正常工作,但是,当我尝试将 GUI 添加到逻辑时,它的工作方式就不同了。

在我的工作逻辑游戏中,由于我使用“raw_input()”函数,连续的 while 循环在每个问题处都会暂停并等待用户回答。当我做 GUI 版本时,我的问题被成功读入,但它一次全部读入,没有时间回答。

我尝试在阅读每个问题后添加 time.sleep() 但这意味着程序不会响应事件处理程序。如果事件处理程序确实有效,那么这将是一个完美的解决方案,给用户一定的时间来回答。

下面的示例代码无法编译,因为我遗漏了许多类和方法,但想表明这是我的问题所在。我在其中读取字典键和值,然后尝试将用户输入与正确答案的索引进行匹配,该索引始终为 answerMain[0] ,然后再被洗牌。

有没有人遇到过类似的问题或知道可能的解决方案?

        attemptMain = {'Q': 'Question Here', 'A': 'Answer1','B': 'Answer2','c': 'Answer3','D': 'Answer4',  }

        def normalQuestions(self, list):
             for i in list:
                questionMain = self.attemptMain.keys()[i - 1]
                answersMain = (self.attemptMain.values()[i - 1])
                correctAnswerMain = answersMain[0]
                shuffle(answersMain)
                answersMainIndex =  (1 + answersMain.index(correctAnswerMain) )
                self.layout.questionandAnswers(questionMain, answersMain[0], answersMain[1], answersMain[2], answersMain[3])
                time.sleep(10)
                x = self.layout.controls()
                if (x == answersMainIndex):
                    print("this is the correct answer")

            def controls(self):
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    pygame.quit()
                    quit()
                if event.type == pygame.KEYDOWN:
                    if event.key == pygame.K_1:
                        print("here" + str(1))
                        return '1'
                    elif event.key == pygame.K_2:
                        print("here" + str(2))
                        return '2'
                    elif event.key == pygame.K_3:
                        print("here" + str(3))
                        return '3'
                    elif event.key == pygame.K_4:
                        print("here" + str(4))
                        return '4'

【问题讨论】:

  • minimal, runnable example 会很有帮助。我已经可以告诉你,你不应该在 pygame 中使用time.sleep,因为此时程序将无响应。在 pygame 中有多种实现定时器的方法(在 Stack Overflow 上搜索)。
  • 好的,谢谢,我看了一下教程点上的时间。()函数,然后会在这里做一个更具体的搜索!
  • 这里是some good answers(我的意思是pygame.time.get_ticks()pygame.time.set_timer和我的dt = clock.tick(30) / 1000方法)。
  • 啊,我想我之前确实找到了那个确切的页面,它帮助我让倒计时工作,但是我的问题是在 normalQuestion 函数的 for 循环中,当我希望每次迭代时它迭代太快以 10/15 秒为例,这样用户就有机会回答问题
  • 给我看一个最小的、可运行的例子,我会看看问题出在哪里。问题中的代码不够完整,无法查看程序是如何工作的。

标签: python while-loop event-handling pygame


【解决方案1】:

这是一个问答游戏示例。我使用链接答案中的dt = clock.tick(fps) 解决方案。您可以通过 dt 递减一个 time 变量,如果它低于 0,则切换到下一个问题。用户可以输入 1-4,然后将其与问题元组的最后一个元素进行比较,以检查答案是否正确。

import random
import pygame as pg


pg.init()
FONT = pg.font.Font(None, 34)
FONT_SMALL = pg.font.Font(None, 24)
BLUE = pg.Color('steelblue1')


def get_question(questions, question_index):
    """Create a surface with the question and the 4 answer choices."""
    question, *answers, _ = questions[question_index]

    # Blit the question and answers onto this transparent surface.
    question_surface = pg.Surface((500, 150), pg.SRCALPHA)
    question_surface.blit(FONT.render(str(question), True, BLUE), (0, 0))
    for y, answer in enumerate(answers, 1):
        txt = FONT_SMALL.render('{}:  {}'.format(y, answer), True, BLUE)
        question_surface.blit(txt, (0, 20*y+20))
    return question_surface


def main():
    screen = pg.display.set_mode((640, 480))
    clock = pg.time.Clock()
    dt = 0
    time_to_answer = 5  # User has 5 seconds to answer.
    time = time_to_answer

    # A list of tuples that contain the question, 4 multiple choice
    # answers and the last element is the correct answer.
    questions = [
        ('Is it A, B, C or D?', 'A', 'B', 'C', 'D', '3'),
        ("What's 2+3?", '23', '5', '3', '2', '2'),
        ]
    random.shuffle(questions)
    question_index = 0
    question_surface = get_question(questions, question_index)

    correct = 0
    incorrect = 0
    game_over = False
    done = False

    while not done:
        for event in pg.event.get():
            if event.type == pg.QUIT:
                done = True
            elif event.type == pg.KEYDOWN:
                if not game_over:
                    user_input = event.unicode
                    correct_answer = questions[question_index][-1]
                    if user_input == correct_answer:
                        print('Correct')
                        correct += 1
                        time = time_to_answer
                    else:
                        incorrect += 1
                        time = time_to_answer

                    question_index += 1
                    if question_index >= len(questions):
                        game_over = True
                    else:
                        question_surface = get_question(questions, question_index)
                else:  # Restart.
                    game_over = False
                    correct = 0
                    incorrect = 0
                    random.shuffle(questions)
                    question_index = 0
                    question_surface = get_question(questions, question_index)

        if not game_over:
            time -= dt
            # If the timer is below 0, switch to the next question.
            if time <= 0:
                question_index += 1
                incorrect += 1
                if question_index >= len(questions):
                    game_over = True
                else:
                    time = time_to_answer
                    print('next')
                    question_surface = get_question(questions, question_index)

        screen.fill((30, 30, 30))
        if not game_over:
            screen.blit(question_surface, (20, 50))
            time_surface = FONT.render(str(round(time, 1)), True, BLUE)
            screen.blit(time_surface, (20, 20))
        correct_answer_surface = FONT_SMALL.render(
            'Correct {}, incorrect {}'.format(correct, incorrect),
            True, BLUE)
        screen.blit(correct_answer_surface, (20, 250))

        pg.display.flip()
        dt = clock.tick(30) / 1000


if __name__ == '__main__':
    main()
    pg.quit()

【讨论】:

  • 如果有什么不清楚的地方,尽管问,我会解释的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-04-05
  • 2021-06-15
  • 1970-01-01
  • 1970-01-01
  • 2011-04-01
  • 1970-01-01
相关资源
最近更新 更多