在 PYGAME 中创建反应时间测试游戏
CREATING A REACTION TIME TEST GAME IN PYGAME
我正在尝试使用 pygame 的 gui 在 python 中创建一个反应时间测试游戏。因为,我对这项技术还很陌生,所以我被困在代码的一部分,比如如何注册更多的按键,然后相应地记录时间。
到目前为止,这是我的代码:
import pygame
from datetime import datetime
import time
import random
pygame.init()
screen = pygame.display.set_mode((640, 480))
pygame.display.set_caption("Reaction Time Test")
font = pygame.font.SysFont(None, 30)
text = font.render("PRESS ANY KEY TO START TEST", 0, (255,255,255))
w = font.render("PRESS ANY KEY",0,(0,255,0))
count = 0
screen.blit(text, (150,240))
running = True
while running:
pygame.display.flip()
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
pygame.quit()
if count <= 5 and event.type == pygame.KEYDOWN:
screen.fill(pygame.Color("black"))
pygame.display.flip()
wait_time = random.randint(1,4)
time.sleep(wait_time)
reaction_start = datetime.now()
print(reaction_start)
screen.blit(w,(225,200))
count = count + 1
if event.type == pygame.KEYDOWN:
reaction_end = datetime.now()
print(reaction_end)
t = reaction_end - reaction_start
print(t)
f = font.render("REACTION TIME: "+ str(t),0,(255,255,255))
screen.blit(f,(225,300))
if count > 5:
screen.fill(pygame.Color("black"))
pygame.display.flip()
s = font.render("AVERAGE REACTION TIME IS: ",0,(255,255,255))
screen.blit(s,(150,200))
pygame.display.flip()
我卡住的部分是这个代码片段
if count <= 5 and event.type == pygame.KEYDOWN:
screen.fill(pygame.Color("black"))
pygame.display.flip()
wait_time = random.randint(1,4)
time.sleep(wait_time)
reaction_start = datetime.now()
print(reaction_start)
screen.blit(w,(225,200))
count = count + 1
if event.type == pygame.KEYDOWN:
reaction_end = datetime.now()
print(reaction_end)
t = reaction_end - reaction_start
print(t)
f = font.render("REACTION TIME: "+ str(t),0,(255,255,255))
screen.blit(f,(225,300))
它会几乎同时注册 reaction_start 和 reaction_end,不会等待按键。
这目前同时打印语句“PRESS ANY KEY”和“REACTION TIME:”,但是当我将 screen.fill(pygame.Color("black") 和 pygame.display.flip() 在 screen.blit(f) 之前,它只会显示 REACTION TIME: 而不是“PRESS ANY KEY”
在pygame中可以通过调用pygame.time.get_ticks()
, which returns the number of milliseconds since pygame.init()
获取系统时间
不要试图在应用程序循环中延迟或等待。添加一个 game_state
变量,它可以具有状态“开始”、“等待”和“wait_for_reaction”。
在应用程序循环开始时获取当前时间:
while running:
current_time = pygame.time.get_ticks()
设置按键开始时间:
if event.type == pygame.KEYDOWN:
if game_state == "start":
game_state = "wait"
start_time = current_time + random.randint(1000, 4000)
当当前时间大于或等于开始时间时,将 game_state
形式的“等待”更改为“wait_for_reaction”:
if game_state == "wait":
if current_time >= start_time:
game_state = "wait_for_reaction"
计算反应时间并重新启动进程,当再次按下某个键时:
if event.type == pygame.KEYDOWN:
# [...]
if game_state == "wait_for_reaction":
game_state = "wait"
reaction_time = (current_time - start_time) / 1000
start_time = current_time + random.randint(1000, 4000)
count += 1
average_time = (average_time * (count-1) + reaction_time) / count
r_surf = font.render(f"REACTION TIME: {reaction_time:.03f}",0,(255,255,255))
ar_surf = font.render(f"AVERAGE REACTION TIME IS: {average_time:.03f}",0,(255,255,255))
根据游戏状态重绘每一帧场景:
while running:
# [...]
screen.fill(pygame.Color("black"))
center = screen.get_rect().center
if game_state == "start":
screen.blit(text, text.get_rect(center = center))
if game_state == "wait_for_reaction":
screen.blit(w, w.get_rect(center = center))
if r_surf:
screen.blit(r_surf, r_surf.get_rect(center = (center[0], 350)))
if ar_surf:
screen.blit(ar_surf, ar_surf.get_rect(center = (center[0], 400)))
pygame.display.flip()
完整示例:
import pygame
import random
pygame.init()
screen = pygame.display.set_mode((640, 480))
pygame.display.set_caption("Reaction Time Test")
font = pygame.font.SysFont(None, 30)
text = font.render("PRESS ANY KEY TO START TEST", 0, (255,255,255))
w = font.render("PRESS ANY KEY",0,(0,255,0))
r_surf = None
ar_surf = None
game_state = "start"
start_time = 0
average_time = 0
count = 0
running = True
while running:
current_time = pygame.time.get_ticks()
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
pygame.quit()
if event.type == pygame.KEYDOWN:
if game_state == "start":
game_state = "wait"
start_time = current_time + random.randint(1000, 4000)
if game_state == "wait_for_reaction":
game_state = "wait"
reaction_time = (current_time - start_time) / 1000
start_time = current_time + random.randint(1000, 4000)
count += 1
average_time = (average_time * (count-1) + reaction_time) / count
r_surf = font.render(f"REACTION TIME: {reaction_time:.03f}",0,(255,255,255))
ar_surf = font.render(f"AVERAGE REACTION TIME IS: {average_time:.03f}",0,(255,255,255))
if game_state == "wait":
if current_time >= start_time:
game_state = "wait_for_reaction"
screen.fill(pygame.Color("black"))
center = screen.get_rect().center
if game_state == "start":
screen.blit(text, text.get_rect(center = center))
if game_state == "wait_for_reaction":
screen.blit(w, w.get_rect(center = center))
if r_surf:
screen.blit(r_surf, r_surf.get_rect(center = (center[0], 350)))
if ar_surf:
screen.blit(ar_surf, ar_surf.get_rect(center = (center[0], 400)))
pygame.display.flip()
我正在尝试使用 pygame 的 gui 在 python 中创建一个反应时间测试游戏。因为,我对这项技术还很陌生,所以我被困在代码的一部分,比如如何注册更多的按键,然后相应地记录时间。
到目前为止,这是我的代码:
import pygame
from datetime import datetime
import time
import random
pygame.init()
screen = pygame.display.set_mode((640, 480))
pygame.display.set_caption("Reaction Time Test")
font = pygame.font.SysFont(None, 30)
text = font.render("PRESS ANY KEY TO START TEST", 0, (255,255,255))
w = font.render("PRESS ANY KEY",0,(0,255,0))
count = 0
screen.blit(text, (150,240))
running = True
while running:
pygame.display.flip()
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
pygame.quit()
if count <= 5 and event.type == pygame.KEYDOWN:
screen.fill(pygame.Color("black"))
pygame.display.flip()
wait_time = random.randint(1,4)
time.sleep(wait_time)
reaction_start = datetime.now()
print(reaction_start)
screen.blit(w,(225,200))
count = count + 1
if event.type == pygame.KEYDOWN:
reaction_end = datetime.now()
print(reaction_end)
t = reaction_end - reaction_start
print(t)
f = font.render("REACTION TIME: "+ str(t),0,(255,255,255))
screen.blit(f,(225,300))
if count > 5:
screen.fill(pygame.Color("black"))
pygame.display.flip()
s = font.render("AVERAGE REACTION TIME IS: ",0,(255,255,255))
screen.blit(s,(150,200))
pygame.display.flip()
我卡住的部分是这个代码片段
if count <= 5 and event.type == pygame.KEYDOWN:
screen.fill(pygame.Color("black"))
pygame.display.flip()
wait_time = random.randint(1,4)
time.sleep(wait_time)
reaction_start = datetime.now()
print(reaction_start)
screen.blit(w,(225,200))
count = count + 1
if event.type == pygame.KEYDOWN:
reaction_end = datetime.now()
print(reaction_end)
t = reaction_end - reaction_start
print(t)
f = font.render("REACTION TIME: "+ str(t),0,(255,255,255))
screen.blit(f,(225,300))
它会几乎同时注册 reaction_start 和 reaction_end,不会等待按键。
这目前同时打印语句“PRESS ANY KEY”和“REACTION TIME:”,但是当我将 screen.fill(pygame.Color("black") 和 pygame.display.flip() 在 screen.blit(f) 之前,它只会显示 REACTION TIME: 而不是“PRESS ANY KEY”
在pygame中可以通过调用pygame.time.get_ticks()
, which returns the number of milliseconds since pygame.init()
获取系统时间
不要试图在应用程序循环中延迟或等待。添加一个 game_state
变量,它可以具有状态“开始”、“等待”和“wait_for_reaction”。
在应用程序循环开始时获取当前时间:
while running:
current_time = pygame.time.get_ticks()
设置按键开始时间:
if event.type == pygame.KEYDOWN:
if game_state == "start":
game_state = "wait"
start_time = current_time + random.randint(1000, 4000)
当当前时间大于或等于开始时间时,将 game_state
形式的“等待”更改为“wait_for_reaction”:
if game_state == "wait":
if current_time >= start_time:
game_state = "wait_for_reaction"
计算反应时间并重新启动进程,当再次按下某个键时:
if event.type == pygame.KEYDOWN:
# [...]
if game_state == "wait_for_reaction":
game_state = "wait"
reaction_time = (current_time - start_time) / 1000
start_time = current_time + random.randint(1000, 4000)
count += 1
average_time = (average_time * (count-1) + reaction_time) / count
r_surf = font.render(f"REACTION TIME: {reaction_time:.03f}",0,(255,255,255))
ar_surf = font.render(f"AVERAGE REACTION TIME IS: {average_time:.03f}",0,(255,255,255))
根据游戏状态重绘每一帧场景:
while running:
# [...]
screen.fill(pygame.Color("black"))
center = screen.get_rect().center
if game_state == "start":
screen.blit(text, text.get_rect(center = center))
if game_state == "wait_for_reaction":
screen.blit(w, w.get_rect(center = center))
if r_surf:
screen.blit(r_surf, r_surf.get_rect(center = (center[0], 350)))
if ar_surf:
screen.blit(ar_surf, ar_surf.get_rect(center = (center[0], 400)))
pygame.display.flip()
完整示例:
import pygame
import random
pygame.init()
screen = pygame.display.set_mode((640, 480))
pygame.display.set_caption("Reaction Time Test")
font = pygame.font.SysFont(None, 30)
text = font.render("PRESS ANY KEY TO START TEST", 0, (255,255,255))
w = font.render("PRESS ANY KEY",0,(0,255,0))
r_surf = None
ar_surf = None
game_state = "start"
start_time = 0
average_time = 0
count = 0
running = True
while running:
current_time = pygame.time.get_ticks()
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
pygame.quit()
if event.type == pygame.KEYDOWN:
if game_state == "start":
game_state = "wait"
start_time = current_time + random.randint(1000, 4000)
if game_state == "wait_for_reaction":
game_state = "wait"
reaction_time = (current_time - start_time) / 1000
start_time = current_time + random.randint(1000, 4000)
count += 1
average_time = (average_time * (count-1) + reaction_time) / count
r_surf = font.render(f"REACTION TIME: {reaction_time:.03f}",0,(255,255,255))
ar_surf = font.render(f"AVERAGE REACTION TIME IS: {average_time:.03f}",0,(255,255,255))
if game_state == "wait":
if current_time >= start_time:
game_state = "wait_for_reaction"
screen.fill(pygame.Color("black"))
center = screen.get_rect().center
if game_state == "start":
screen.blit(text, text.get_rect(center = center))
if game_state == "wait_for_reaction":
screen.blit(w, w.get_rect(center = center))
if r_surf:
screen.blit(r_surf, r_surf.get_rect(center = (center[0], 350)))
if ar_surf:
screen.blit(ar_surf, ar_surf.get_rect(center = (center[0], 400)))
pygame.display.flip()