2017-09-27 10 views
1

Je construis un jeu-questionnaire à choix multiple dans pygame mais il y a un problème avec ma boucle while.Alors que le problème de boucle dans pygame ne s'arrête pas pour le gestionnaire d'événements

J'ai réussi à construire le jeu en python sans l'interface graphique et toute la logique fonctionne bien, cependant, quand j'essaie d'ajouter l'interface graphique à la logique, cela ne fonctionne pas de la même manière.

Dans mon jeu de logique de travail, la boucle while continue est mise en pause à chaque question grâce à la fonction 'raw_input()' et attend que l'utilisateur réponde. Quand je fais la version de l'interface graphique, mes questions sont lues avec succès mais elles les lisent toutes en même temps et il n'y a pas de temps pour répondre.

J'ai essayé d'ajouter time.sleep() après avoir lu chaque question, mais cela signifie que le programme ne répond pas aux gestionnaires d'événements. Si les gestionnaires d'événements fonctionnaient, alors ce serait la solution parfaite, donnant aux utilisateurs un certain temps pour répondre.

Cet exemple de code ci-dessous ne compilera pas car j'ai omis de nombreuses classes et méthodes, mais je voulais montrer que c'est là que se situe mon problème. Je lis les clefs et les valeurs de dictionnaire dedans et essaye alors et fais correspondre l'entrée d'utilisateur avec l'index de la réponse correcte qui est toujours answerMain [0] avant d'être mélangé.

Quelqu'un a-t-il eu un problème similaire ou connaît-il une solution possible?

 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' 
+0

Un [exemple minimal exécutable] (https://stackoverflow.com/help/mcve) serait utile. Je peux déjà vous dire que vous ne devriez pas utiliser 'time.sleep' dans pygame, car le programme ne répondra pas pendant ce temps. Il y a plusieurs façons d'implémenter des timers dans pygame (recherche sur Stack Overflow). – skrx

+0

Ok merci, j'ai jeté un oeil à l'heure.() Les fonctions sur tutoriels point, feront une recherche un peu plus spécifique ici alors! – odare

+0

Voici [quelques bonnes réponses] (https://stackoverflow.com/questions/30720665/countdown-timer-in-pygame) (Je veux dire le 'pygame.time.get_ticks()', 'pygame.time.set_timer' et mon approche 'dt = clock.tick (30)/1000'). – skrx

Répondre

0

Voici un exemple de jeu-questionnaire. J'utilise la solution dt = clock.tick(fps) de la réponse liée. Vous pouvez simplement décrémenter une variable time par le dt et si elle est inférieure à 0, passez à la question suivante. L'utilisateur peut entrer 1-4, qui est ensuite comparé avec le dernier élément de l'uplet de question pour vérifier si la réponse était correcte.

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() 
+0

Si quelque chose n'est pas clair, il suffit de demander et je vais l'expliquer. – skrx