我正在尝试做到这一点,所以当您在琐事游戏中获得正确答案时,它将消除您看到的大问题并说“做得好” 5秒钟,然后返回到主菜单有4个随机选择的问题。这些问题是从quizfile.csv中加载的,其中包含:
What colour is elon musk's hair?,brown
What is most popular sport?,football
What was Queen first called?,Smile
What's superior Apple Or Windows?,Windows
它们是随机的,因为它们只是占位符,并且仅用于测试目的。 我要暂停/显示5秒钟功能的位置是第一个文件的第115行。
我尝试了time.sleep(5)
,但这只是冻结程序,并且在5秒钟内不显示它,就像不到一秒钟一样。我是否需要使用pygame.event.set_timer()
?如果需要,如何使用?
import csv
import sys
import random
import pygame
import textwrap
import time
import pygame_textinput
textinput = pygame_textinput.TextInput()
pygame.init()
clock = pygame.time.Clock()
FPS=60
SCREENSIZE = SCREENWIDTH, SCREENHEIGHT = 1080, 720
screen = pygame.display.set_mode(SCREENSIZE)
white = (255, 255, 255)
black = (0, 0, 0)
red = (255, 0, 0)
yellow = (255, 255, 0)
green = (0, 255, 0)
questions = {}
def wrap_text(message, wraplimit): #keep text on screen
return textwrap.fill(message, wraplimit)
def text_objects(text,font): #render text
textSurf = font.render(text, True, black)
return textSurf, textSurf.get_rect()
def question(text):
xx=0
text = wrap_text(text,20) #wrap text
largeText = pygame.font.Font('freesansbold.ttf',100)
for part in text.split('\n'): #for each line from the wrapped text
TextSurf, TextRect = text_objects(part, largeText)
TextRect.center = ((SCREENWIDTH/2)),(SCREENHEIGHT/2+xx)
screen.blit(TextSurf, TextRect)
xx+=75 #change height of text so doesnt overlap
class Button:
def __init__(self, question, answer,positionx,positiony): #setup all vars
self.question = question
self.answer = answer
self.positionx = positionx
self.positiony = positiony
def button(self):
ltr = len(self.question)
w= 12.5*ltr #make width of button big enough for text
button = pygame.Rect(self.positionx,self.positiony,w,50) #make button
largeText = pygame.font.Font('freesansbold.ttf',20)
TextSurf, TextRect = text_objects(self.question, largeText)
TextRect.center = ((self.positionx+(w/2)),(self.positiony+25)) #button text
return button, TextSurf, TextRect
def question(self):
question(self.question) #display question
def giveQuestionAnswer(self):
return self.question,self.answer #give question and answer
with open("quizfile.csv") as f: #load in questions
reader = csv.reader(f)
quiz_qas = list(reader)
z=0 #for positioning
t=0 #for loop
quiz = random.sample(quiz_qas, 4) #randomly select 4 questions
for q, a in quiz: #for every question and answer in the file
questions[q] = a #define the dictionary of questions and answers
for x, y in questions.items(): #for every answer and question in the dictionary, link them
if t==0: #the sweet spots for getting a different question every time
b = Button(x,y,200,200) #make button object
z+=50
elif t==5:
b1 = Button(x,y,600,200)
z+=50
elif t==7:
b2 = Button(x,y,600,400)
z+=50
elif t==9:
b3 = Button(x,y,200,400)
z+=50
t+=1
b2on = False #for handling displaying the question
b3on = False
b4on = False
b5on = False
correct=False
gameState = "running" # controls which state the games is in
# game loop #################### runs 60 times a second!
while gameState != "exit": # game loop - note: everything in the mainloop is indented one tab
screen.fill(white)
events = pygame.event.get()
if b2on:
q,a = b.giveQuestionAnswer() #get question and answer
question(q) #display answer
# Feed it with events every frame
# Blit its surface onto the screen
screen.blit(textinput.get_surface(), (10, 10))
if textinput.update(events): #if hit enter
if textinput.get_text() == a:
b2on = False
correct=True
if correct:
question("well done")
#PAUSE SCREEN HERE AND DISPLAY WELL DONE FOR 5 SECONDS
correct=False
elif b3on:
q,a = b1.giveQuestionAnswer()
question(q)
textinput.update(events)
screen.blit(textinput.get_surface(), (10, 10))
if textinput.update(events): #if hit enter
if textinput.get_text() == a:
b3on = False
correct=True
elif b4on:
q,a = b2.giveQuestionAnswer()
question(q)
textinput.update(events)
screen.blit(textinput.get_surface(), (10, 10))
if textinput.update(events): #if hit enter
if textinput.get_text() == a:
b4on = False
correct=True
elif b5on:
q,a = b3.giveQuestionAnswer()
question(q)
textinput.update(events)
screen.blit(textinput.get_surface(), (10, 10))
if textinput.update(events): #if hit enter
if textinput.get_text() == a:
b5on = False
correct=True
elif b2on==False and b3on==False and b4on==False and b5on==False:
B2,TextSurf,TextRect = b.button() #draw buttons
pygame.draw.rect(screen, [255, 0, 0], B2)
screen.blit(TextSurf, TextRect)
B3,TextSurf,TextRect = b1.button()
pygame.draw.rect(screen, [255, 0, 0], B3)
screen.blit(TextSurf, TextRect)
B4,TextSurf,TextRect = b2.button()
pygame.draw.rect(screen, [255, 0, 0], B4)
screen.blit(TextSurf, TextRect)
B5,TextSurf,TextRect = b3.button()
pygame.draw.rect(screen, [255, 0, 0], B5)
screen.blit(TextSurf, TextRect)
for event in pygame.event.get(): # get user interaction events
if event.type == pygame.QUIT: # tests if window's X (close) has been clicked
gameState = "exit" # causes exit of game loop
if event.type == pygame.MOUSEBUTTONDOWN:
mouse_pos = event.pos # gets mouse position
if B2.collidepoint(mouse_pos): #if click on button
b2on = True #display question
if B3.collidepoint(mouse_pos):
b3on = True
if B4.collidepoint(mouse_pos):
b4on = True
if B5.collidepoint(mouse_pos):
b5on = True
pygame.display.update()
pygame.display.flip() # transfers build screen to human visable screen
clock.tick(FPS) # limits game to frame per second, FPS value
# out of game loop ###############
print("The game has closed")
pygame.quit()
sys.exit()
这是我用来创建闪烁的输入效果和功能的pygame_textinput.py文件。
"""
Copyright 2017, Silas Gyger, silasgyger@gmail.com, All rights reserved.
Borrowed from https://github.com/Nearoo/pygame-text-input under the MIT license.
"""
import os.path
import pygame
import pygame.locals as pl
pygame.font.init()
class TextInput:
"""
This class lets the user input a piece of text, e.g. a name or a message.
This class let's the user input a short, one-lines piece of text at a blinking cursor
that can be moved using the arrow-keys. Delete, home and end work as well.
"""
def __init__(
self,
initial_string="",
font_family="",
font_size=35,
antialias=True,
text_color=(0, 0, 0),
cursor_color=(0, 0, 1),
repeat_keys_initial_ms=400,
repeat_keys_interval_ms=35):
"""
:param initial_string: Initial text to be displayed
:param font_family: name or list of names for font (see pygame.font.match_font for precise format)
:param font_size: Size of font in pixels
:param antialias: Determines if antialias is applied to font (uses more processing power)
:param text_color: Color of text (duh)
:param cursor_color: Color of cursor
:param repeat_keys_initial_ms: Time in ms before keys are repeated when held
:param repeat_keys_interval_ms: Interval between key press repetition when helpd
"""
# Text related vars:
self.antialias = antialias
self.text_color = text_color
self.font_size = font_size
self.input_string = initial_string # Inputted text
if not os.path.isfile(font_family):
font_family = pygame.font.match_font(font_family)
self.font_object = pygame.font.Font(font_family, font_size)
# Text-surface will be created during the first update call:
self.surface = pygame.Surface((1, 1))
self.surface.set_alpha(0)
# Vars to make keydowns repeat after user pressed a key for some time:
self.keyrepeat_counters = {} # {event.key: (counter_int, event.unicode)} (look for "***")
self.keyrepeat_intial_interval_ms = repeat_keys_initial_ms
self.keyrepeat_interval_ms = repeat_keys_interval_ms
# Things cursor:
self.cursor_surface = pygame.Surface((int(self.font_size/20+1), self.font_size))
self.cursor_surface.fill(cursor_color)
self.cursor_position = len(initial_string) # Inside text
self.cursor_visible = True # Switches every self.cursor_switch_ms ms
self.cursor_switch_ms = 500 # /|\
self.cursor_ms_counter = 0
self.clock = pygame.time.Clock()
def update(self, events):
for event in events:
if event.type == pygame.KEYDOWN:
self.cursor_visible = True # So the user sees where he writes
# If none exist, create counter for that key:
if event.key not in self.keyrepeat_counters:
self.keyrepeat_counters[event.key] = [0, event.unicode]
if event.key == pl.K_BACKSPACE:
self.input_string = (
self.input_string[:max(self.cursor_position - 1, 0)]
+ self.input_string[self.cursor_position:]
)
# Subtract one from cursor_pos, but do not go below zero:
self.cursor_position = max(self.cursor_position - 1, 0)
elif event.key == pl.K_DELETE:
self.input_string = (
self.input_string[:self.cursor_position]
+ self.input_string[self.cursor_position + 1:]
)
elif event.key == pl.K_RETURN:
return True
elif event.key == pl.K_RIGHT:
# Add one to cursor_pos, but do not exceed len(input_string)
self.cursor_position = min(self.cursor_position + 1, len(self.input_string))
elif event.key == pl.K_LEFT:
# Subtract one from cursor_pos, but do not go below zero:
self.cursor_position = max(self.cursor_position - 1, 0)
elif event.key == pl.K_END:
self.cursor_position = len(self.input_string)
elif event.key == pl.K_HOME:
self.cursor_position = 0
else:
# If no special key is pressed, add unicode of key to input_string
self.input_string = (
self.input_string[:self.cursor_position]
+ event.unicode
+ self.input_string[self.cursor_position:]
)
self.cursor_position += len(event.unicode) # Some are empty, e.g. K_UP
elif event.type == pl.KEYUP:
# *** Because KEYUP doesn't include event.unicode, this dict is stored in such a weird way
if event.key in self.keyrepeat_counters:
del self.keyrepeat_counters[event.key]
# Update key counters:
for key in self.keyrepeat_counters:
self.keyrepeat_counters[key][0] += self.clock.get_time() # Update clock
# Generate new key events if enough time has passed:
if self.keyrepeat_counters[key][0] >= self.keyrepeat_intial_interval_ms:
self.keyrepeat_counters[key][0] = (
self.keyrepeat_intial_interval_ms
- self.keyrepeat_interval_ms
)
event_key, event_unicode = key, self.keyrepeat_counters[key][1]
pygame.event.post(pygame.event.Event(pl.KEYDOWN, key=event_key, unicode=event_unicode))
# Re-render text surface:
self.surface = self.font_object.render(self.input_string, self.antialias, self.text_color)
# Update self.cursor_visible
self.cursor_ms_counter += self.clock.get_time()
if self.cursor_ms_counter >= self.cursor_switch_ms:
self.cursor_ms_counter %= self.cursor_switch_ms
self.cursor_visible = not self.cursor_visible
if self.cursor_visible:
cursor_y_pos = self.font_object.size(self.input_string[:self.cursor_position])[0]
# Without this, the cursor is invisible when self.cursor_position > 0:
if self.cursor_position > 0:
cursor_y_pos -= self.cursor_surface.get_width()
self.surface.blit(self.cursor_surface, (cursor_y_pos, 0))
self.clock.tick()
return False
def get_surface(self):
return self.surface
def get_text(self):
return self.input_string
def get_cursor_position(self):
return self.cursor_position
def set_text_color(self, color):
self.text_color = color
def set_cursor_color(self, color):
self.cursor_surface.fill(color)
def clear_text(self):
self.input_string = ""
self.cursor_position = 0
任何帮助表示赞赏!
答案 0 :(得分:2)
您必须使用计时器事件。参见pygame.event
。
创建用户事件和paused
状态。
pausetimerevent = pygame.USEREVENT + 1
paused = False
如果游戏暂停,则显示“做得好”。答案正确时,请设置paused = True
并启动计时器。参见pygame.time.set_timer
:
while gameState != "exit":
if not paused and b2on:
# [...]
if paused:
question("well done")
elif correct:
correct = False
paused = True
pygame.time.set_timer(pausetimerevent, 5000) # 5000 milliseconds = 5 socond
时间过去之后,事件发生。重置paused
并通过将0传递给time参数来重置计时器:
while gameState != "exit":
# [...]
for event in pygame.event.get(): # get user interaction events
if event.type == pygame.QUIT: # tests if window's X (close) has been clicked
gameState = "exit" # causes exit of game loop
if event.type == pygame.MOUSEBUTTONDOWN:
mouse_pos = event.pos # gets mouse position
# [...]
if event.type == pausetimerevent:
pygame.time.set_timer(pausetimerevent, 0) # stop timer
paused = False
答案 1 :(得分:1)
您可以使用pygame.time.wait()或pygame.time.delay()[它们是不同的,请同时尝试两者]。从理论上讲,它应该起作用;)
编辑: 如果要在显示文本时运行循环,可以创建一个名为“ welldonetime”的变量,当要显示完成的文本时可以将其分配为5000毫秒,然后调用
continue
基本上跳过当前循环周期 。然后,您将在循环的顶部添加一条if语句,以检查“ welldonetime”变量是否大于0(如果这样),则显示效果良好的文本,并从“ welldonetime”中减去经过的时间。 一旦“ welldonetime”恢复为0,它将完成循环中的其余工作
b2on = False #for handling displaying the question
b3on = False
b4on = False
b5on = False
correct=False
gameState = "running" # controls which state the games is in
#edited here:
displaywelldoneuntil = 0
#end of edited
# game loop #################### runs 60 times a second!
while gameState != "exit": # game loop - note: everything in the mainloop is indented one tab
screen.fill(white)
events = pygame.event.get()
#edited here too:
if pygame.time.get_ticks() < displaywelldoneuntil:
question("well done")
continue #skip the rest of the current loop iteration
#end of edited
if b2on:
q,a = b.giveQuestionAnswer() #get question and answer
question(q) #display answer
# Feed it with events every frame
# Blit its surface onto the screen
screen.blit(textinput.get_surface(), (10, 10))
if textinput.update(events): #if hit enter
if textinput.get_text() == a:
b2on = False
correct=True
#edited here:
if correct:
displaywelldoneuntil = pygame.time.get_ticks() + 5000 # display well done until current time plus 5000ms
correct=False
continue #skip the rest of the current loop iteration
#end of edited
elif b3on:
在这里,我认为这是最直接的方法,尽管Rabbid76的回答稍微优雅一些;)