I'm designing a simple emotion recognition game that displays faces to the screen for one second, before disappearing and letting participants click a button to decide which emotion was displayed. However, I struggled to get it to only display for a second, I eventually used a while loop to display it, but ever since I incorporated that my game is lagging and running really slowly. Here's the relevant code, from the function I defined to display the images. I have it set so it creates a transparent version of the image and then blits that instead, to provide the illusion of the image disappearing after 1 second.
def askQuestion(imageNumber):
mouse = pygame.mouse.get_pos()
last = pygame.time.get_ticks()
while pygame.time.get_ticks() - last <= 1000:
screen.blit(images[imageNumber], (((display_width/2) - (images[imageNumber].get_size()[0]/2)), (((display_height/2) - (images[imageNumber].get_size()[1]/2)))))
else:
images[imageNumber].fill((255,255,255,0))
I strongly suspect that the reason it is lagging is that, by having the while loop, Python is continually blitting the image to the screen, as opposed to just doing it once, thus using up a lot of resources. Could anyone suggest an easier way to display this image for only one second without using a while loop? (Also, I know my code for the image co-ordinates is really messy - it's on my to-do list!)
Update: I tried to incorporate the "state machine" suggested by @Kingsley, however it still doesn't appear to be working, as the image remains on the screen indefinitely. Here's what I have so far:
running = True
while running:
screen.fill((255, 255, 255))
answerDetection()
pygame.draw.circle(screen, (0,0,0), (int(display_width/2), int(display_height/2)), 10, 2)
displayButtons("sad", 0, 700, 200, 100)
displayButtons("happy", 240, 700, 200, 100)
displayButtons("neutral", 480, 700, 200, 100)
displayButtons("angry", 720, 700, 200, 100)
displayButtons("afraid", 960, 700, 200, 100)
imageNumber = len(answers) + 1
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_ESCAPE:
running = False
gameState = States.VIEWING
timeNow = pygame.time.get_ticks()
startTime = timeNow
if ( gameState == States.VIEWING):
if( timeNow <= startTime + 1000):
askQuestion(imageNumber)
else:
gameState == States.ANSWERING
if (gameState == States.ANSWERING):
images[imageNumber].fill((255,255,255,0))
for rects in rectList:
for event in pygame.event.get():
if event.type == pygame.MOUSEBUTTONUP:
if pygame.Rect(rects).collidepoint(mouse):
gameState == States.VIEWING
Just to clarify, answerDetection() is a function to detect which button a user has clicked. In the States.ANSWERING section, I use "images[imageNumber].fill((255, 255, 255, 0)) as a way to make the image transparent, because all I want to do in the VIEWING state is to make the image disappear (as the buttons are continually displayed anyway). I'm not sure if the issue is that it isn't changing state, or that when it is changing state nothing is happening.
Any help would be really appreciated!
Edit 2: Further experimentation has revealed the problem: With the way I have timeNow = pygame.time.get_ticks() followed immediately by startTime = timeNow, the loop is continually updating the timeNow variable, followed by re-setting the startTime variable to the same number immediately after - whereas as I understand, we want the startTime to be a static number to indicate the time the "viewing" state started. Otherwise, timeNow will never be 1000ms more than startTime and it will never move to the "answering" state. I just need to find a way to set the time at the start of the viewing state and have that be a static time in the startTime variable.