Search code examples
pythonpython-3.xpygameflicker

Why does my Pygame window flicker when animating objects?


So my pygame window just won't stop flickering. I know if only one item is in snake.snakearray, it won't flicker.

#class for the array
class snake:
  snakearray = [[ScreenConfigs.width / 2,ScreenConfigs.height / 2],[ScreenConfigs.width / 2,ScreenConfigs.height / 2]]
  direction = "up"
  increment = 0.1
#loop to draw the snake
while Running:
 for snakeBit in snake.snakearray:
  pygame.draw.rect(display,"black",(0,0,ScreenConfigs.width,ScreenConfigs.height))
  pygame.draw.rect(display,"white",(snakeBit[0],snakeBit[1],30,30))
  pygame.display.flip()

I tried putting the pygame.display.flip() outside of the loop and it only drew that last rectangle. (because when you call pygame.draw.rect, it disregards the last one drew)


Solution

  • Multiple calls to pygame.display.update() or pygame.display.flip() causes flickering. Updating the display once at the end of the application loop is sufficient. But you also need to clear the display only once before drawing the scene:

    while Running:
        # [...]
    
        # clear display 
        pygame.draw.rect(display,"black", (0,0,ScreenConfigs.width,ScreenConfigs.height))
    
        # draw scene
        for snakeBit in snake.snakearray:
            pygame.draw.rect(display,"white",(snakeBit[0],snakeBit[1],30,30))
      
        # update display
        pygame.display.flip()
    

    Clearing the display can also be done with fill:

    while Running:
        # [...]
    
        # clear display 
        display.fill("black")
    
        # draw scene
        for snakeBit in snake.snakearray:
            pygame.draw.rect(display,"white",(snakeBit[0],snakeBit[1],30,30))
      
        # update display
        pygame.display.flip()
    

    Each object in the scene is drawn to the pygame.Surface object associated with the display. To create animated objects, the entire scene must be redrawn in each frame. Therefore, the display must be cleared at the beginning of each frame in the application loop. If you draw on the Surface associated to the PyGame display, this is not immediately visible in the display. The changes become visible, when the display is updated with either pygame.display.update() or pygame.display.flip().

    The typical PyGame application loop has to: