简体   繁体   English

使pygame在继续操作之前等待用户点击/输入(python问答游戏)

[英]Making pygame wait for user click/input before proceeding (python quiz game)

So I am trying to make a game on pygame which would display a vocabulary as a question and three answer choices. 因此,我试图在pygame上制作一个游戏,该游戏将词汇显示为问题,并提供三个答案选择。 And if the user presses the correct answer, their score will go up by one, and the game will move on to the next vocabulary question. 如果用户按下正确的答案,他们的分数将提高一个,游戏将继续进行下一个词汇问题。

I store my questions in an 2D array called questions[], in each element of the array it holds the questions and answers for each question as [question, correct answer choice, answer choice, answer choice]. 我将我的问题存储在一个名为questions []的二维数组中,在该数组的每个元素中,它以[问题,正确答案选择,答案选择,答案选择]的形式保存每个问题的答案。 So the correct answer is always at index position [i][1]. 因此,正确答案始终在索引位置[i] [1]。 I do randomize the order in which the answer choices are shown later. 我确实将稍后显示答案选择的顺序随机化。

Now my problem is that my game goes through the questions without waiting for user input. 现在我的问题是我的游戏无需等待用户输入即可遍历所有问题。 The point was that it would wait for the user to click. 关键是它将等待用户单击。 When the user clicks, then it checks where the user click. 用户单击时,它将检查用户单击的位置。 The position of the user's mouse will determine which "answer box" the user pressed. 用户鼠标的位置将确定用户按下了哪个“答案框”。 Let's pretend the user pressed the first box. 假设用户按下了第一个框。 The game then compares whether the text stored in that box is correct (ie the text is the same as questions[i][1]). 然后,游戏会比较该框中存储的文本是否正确(即文本与问题[i] [1]相同)。 It displays each question for a split second, and then moves on to the next question and the next question. 它会瞬间显示每个问题,然后移至下一个问题和下一个问题。

But it does not wait for the user to click first. 但是它不等待用户首先单击。 Not even, it doesn't even display the questions long enough for the user to read the question. 甚至没有,它甚至没有显示足够长的问题以使用户阅读问题。 Is there a way I can perhaps structure the loop or add certain conditions so that the program would display each question until the user chooses an answer, and then add the score and move on to the next question? 有没有办法构造循环或添加某些条件,以便程序可以显示每个问题,直到用户选择答案,然后添加分数并移至下一个问题?

Here is the code: 这是代码:

import pygame
from random import randint
from pygame import *

pygame.init()
pygame.font.match_font('Courier New.ttf')


BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
GREEN = (0, 255, 0)
RED = (255, 0, 0)
GREEN = (71, 212, 15)
BLUE = (42, 250, 246)
PINK = (255,102, 196)
YELLOW = (255, 255, 0)
i = 0

size = (700, 500)
screen = pygame.display.set_mode(size)

pygame.display.set_caption("Spanish Space Quiz") 

done = False

questions = [["Hola", "Hello", "Goodbye", "Cow"],["Amigo", "Friend", "Cat", "Dog"],["Si", "Yes", "No", "Maybe"]]
answerboxes = [[30,300,190,150,BLUE,WHITE,7],[255,300,190,150,YELLOW,WHITE,7],[480,300,190,150,PINK,WHITE,7]]
score = 0
choices = []

def textObject (text, font):
    textWord = font.render(text, True, WHITE)
    return textWord, textWord.get_rect()

def answerbutton(drawbox):
    mouse = pygame.mouse.get_pos()

    if drawbox[0]+drawbox[2] > mouse[0] > drawbox[0] and drawbox[1]+drawbox[3] > mouse[1] > drawbox[1]:
        pygame.draw.rect(screen, drawbox[5],(drawbox[0],drawbox[1],drawbox[2],drawbox[3]),drawbox[6])           
    else:
        pygame.draw.rect(screen, drawbox[4],(drawbox[0],drawbox[1],drawbox[2],drawbox[3]),drawbox[6])

    answerTextFont = pygame.font.SysFont("Courier New",60)
    textWord, textBox = textObject(drawbox[7], answerTextFont) #the text & the "Text box"
    textBox.center = ( (drawbox[0]+(drawbox[2]/2)), (drawbox[1]+(drawbox[3]/2)) )
    screen.blit(textWord, textBox)

def questionbutton(message,x,y,w,h,color):
    mouse = pygame.mouse.get_pos()
    pygame.draw.rect(screen,color,(x,y,w,h))

    answerTextFont = pygame.font.SysFont("Courier New",60)
    textWord, textBox = textObject(message, answerTextFont) #the text & the "Text box"
    textBox.center = ( (x+(w/2)), (y+(h/2)) )
    screen.blit(textWord, textBox)

while not done:
    screen.blit (backgroundImage, [0,0])
    font = pygame.font.SysFont('Courier', 30, True, False)
    text = font.render("SPACE VOCBULARY QUIZ",True,WHITE)
    screen.blit(text, [30, 30])
    font = pygame.font.SysFont('Courier', 30, False, False)
    text = font.render("SCORE: ", True, WHITE)
    screen.blit(text, [500, 30])

    for event in pygame.event.get():
        if i == (len(questions)): #if user clicks close then done becomes true and game quits
            done = True
            event.type == pygame.QUIT
        for c in range (len(questions)):
            mouse = pygame.mouse.get_pos()
            click = pygame.mouse.get_pressed()
            questionbutton((questions[c][0]),30,150,640,100,GREEN)
            for n in range(3):
                choices.append(questions[c][n+1])
            for r in range(3):
                randomPointer = randint(0, (len(choices)-1))
                answerboxes[r].append(choices[randomPointer])
                choices.remove(choices[randomPointer])
                answerbutton(answerboxes[r][0:8])
            if click[0] == 1: 
                for a in range(3):
                    if answerboxes[a][0]+answerboxes[a][2] > mouse[0] > answerboxes[a][0] and answerboxes[a][1]+answerboxes[a][3] > mouse[1] > answerboxes[a][1]:
                        if answerboxes[a][7] == questions[i][1]:
                            score = score + 1
                            print (score)
            for g in range (3):
                answerboxes[g].pop()           
            i = i+1

    pygame.display.update()

pygame.quit()

You can put an infinite loop in the loop for questions, with the break condition of exiting the infinite loop when mouse is clicked on the answer box. 您可以在问题循环中放入一个无限循环,其中的中断条件是在答案框上单击鼠标时退出无限循环。

Example : 范例

for c in len(range(questions)):
    clicked_on_answer = False
    while True:
        # your code

        if click[0] == 1: 
            for a in range(3):
                if answerboxes[a][0]+answerboxes[a][2] > mouse[0] > answerboxes[a][0] and answerboxes[a][1]+answerboxes[a][3] > mouse[1] > answerboxes[a][1]:
                    clicked_on_answer = True
                    if answerboxes[a][7] == questions[i][1]:
                        score = score + 1
                        print (score)
        if clicked_on_answer:
            break

Yes, you need to restructure the program and better separate the drawing from the event handling and game logic. 是的,您需要重组程序,更好地将图形与事件处理和游戏逻辑分开。 It should only proceed to the next question if a mouse button is pressed, so check in the event loop if event.type == pygame.MOUSEBUTTONDOWN: (only one MOUSEBUTTONDOWN event is produced per click), then see if a rect was clicked, increment the score and finally render the next question and choices. 如果按下了鼠标键,它应该只继续处理下一个问题,因此请在事件循环中检查if event.type == pygame.MOUSEBUTTONDOWN:每次单击仅产生一个MOUSEBUTTONDOWN事件),然后查看是否单击了rect,增加分数,最后呈现下一个问题和选择。 Blit the question and choice texts outside of the event loop. 在事件循环之外取消问题和选择文本。

clock = pygame.time.Clock()  # A clock to limit the frame rate.
# Define the fonts outside of the main loop.
font = pygame.font.SysFont('Courier', 30, False, False)

# Render question and choice text surfaces.
# Create the rects for the choices and set their positions.

while not done:
    # Handle events.
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            done = True
        elif event.type == pygame.MOUSEBUTTONDOWN:
            # Check if event.pos collides with the correct rect.
            for index, rect in enumerate(rects):
                if rect.collidepoint(event.pos) and choices[index] == correct_answer:
                    score += 1
            # Get next question and choices, render them and update the rects.

    # Draw everything.
    # Blit the question and choice text surfaces at their rects.

    pygame.display.update()
    clock.tick(30)  # Limit frame rate to 30 fps.

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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